aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-08-13 18:34:33 +0300
committerArtur Signell <artur@vaadin.com>2012-08-13 19:18:33 +0300
commite85d933b25cc3c5cc85eb7eb4b13b950fd8e1569 (patch)
tree9ab6f13f7188cab44bbd979b1cf620f15328a03f /src
parent14dd4d0b28c76eb994b181a4570f3adec53342e6 (diff)
downloadvaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.tar.gz
vaadin-framework-e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569.zip
Moved server files to a server src folder (#9299)
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/Application.java2426
-rw-r--r--src/com/vaadin/RootRequiresMoreInformationException.java25
-rw-r--r--src/com/vaadin/Vaadin.gwt.xml85
-rw-r--r--src/com/vaadin/Version.java74
-rw-r--r--src/com/vaadin/annotations/AutoGenerated.java18
-rw-r--r--src/com/vaadin/annotations/EagerInit.java30
-rw-r--r--src/com/vaadin/annotations/JavaScript.java41
-rw-r--r--src/com/vaadin/annotations/StyleSheet.java38
-rw-r--r--src/com/vaadin/annotations/Theme.java24
-rw-r--r--src/com/vaadin/annotations/Widgetset.java25
-rw-r--r--src/com/vaadin/annotations/package.html12
-rw-r--r--src/com/vaadin/data/Buffered.java280
-rw-r--r--src/com/vaadin/data/BufferedValidatable.java35
-rw-r--r--src/com/vaadin/data/Collapsible.java68
-rw-r--r--src/com/vaadin/data/Container.java1105
-rw-r--r--src/com/vaadin/data/Item.java180
-rw-r--r--src/com/vaadin/data/Property.java402
-rw-r--r--src/com/vaadin/data/Validatable.java110
-rw-r--r--src/com/vaadin/data/Validator.java175
-rw-r--r--src/com/vaadin/data/fieldgroup/BeanFieldGroup.java157
-rw-r--r--src/com/vaadin/data/fieldgroup/Caption.java15
-rw-r--r--src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java157
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroup.java978
-rw-r--r--src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java31
-rw-r--r--src/com/vaadin/data/fieldgroup/PropertyId.java15
-rw-r--r--src/com/vaadin/data/package.html49
-rw-r--r--src/com/vaadin/data/util/AbstractBeanContainer.java856
-rw-r--r--src/com/vaadin/data/util/AbstractContainer.java251
-rw-r--r--src/com/vaadin/data/util/AbstractInMemoryContainer.java941
-rw-r--r--src/com/vaadin/data/util/AbstractProperty.java226
-rw-r--r--src/com/vaadin/data/util/BeanContainer.java168
-rw-r--r--src/com/vaadin/data/util/BeanItem.java269
-rw-r--r--src/com/vaadin/data/util/BeanItemContainer.java241
-rw-r--r--src/com/vaadin/data/util/ContainerHierarchicalWrapper.java792
-rw-r--r--src/com/vaadin/data/util/ContainerOrderedWrapper.java644
-rw-r--r--src/com/vaadin/data/util/DefaultItemSorter.java210
-rw-r--r--src/com/vaadin/data/util/FilesystemContainer.java918
-rw-r--r--src/com/vaadin/data/util/HierarchicalContainer.java814
-rw-r--r--src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java70
-rw-r--r--src/com/vaadin/data/util/IndexedContainer.java1109
-rw-r--r--src/com/vaadin/data/util/ItemSorter.java57
-rw-r--r--src/com/vaadin/data/util/ListSet.java264
-rw-r--r--src/com/vaadin/data/util/MethodProperty.java784
-rw-r--r--src/com/vaadin/data/util/MethodPropertyDescriptor.java134
-rw-r--r--src/com/vaadin/data/util/NestedMethodProperty.java257
-rw-r--r--src/com/vaadin/data/util/NestedPropertyDescriptor.java60
-rw-r--r--src/com/vaadin/data/util/ObjectProperty.java141
-rw-r--r--src/com/vaadin/data/util/PropertyFormatter.java245
-rw-r--r--src/com/vaadin/data/util/PropertysetItem.java340
-rw-r--r--src/com/vaadin/data/util/QueryContainer.java675
-rw-r--r--src/com/vaadin/data/util/TextFileProperty.java144
-rw-r--r--src/com/vaadin/data/util/TransactionalPropertyWrapper.java114
-rw-r--r--src/com/vaadin/data/util/VaadinPropertyDescriptor.java43
-rw-r--r--src/com/vaadin/data/util/converter/Converter.java159
-rw-r--r--src/com/vaadin/data/util/converter/ConverterFactory.java23
-rw-r--r--src/com/vaadin/data/util/converter/ConverterUtil.java168
-rw-r--r--src/com/vaadin/data/util/converter/DateToLongConverter.java72
-rw-r--r--src/com/vaadin/data/util/converter/DefaultConverterFactory.java101
-rw-r--r--src/com/vaadin/data/util/converter/ReverseConverter.java84
-rw-r--r--src/com/vaadin/data/util/converter/StringToBooleanConverter.java108
-rw-r--r--src/com/vaadin/data/util/converter/StringToDateConverter.java112
-rw-r--r--src/com/vaadin/data/util/converter/StringToDoubleConverter.java107
-rw-r--r--src/com/vaadin/data/util/converter/StringToIntegerConverter.java88
-rw-r--r--src/com/vaadin/data/util/converter/StringToNumberConverter.java111
-rw-r--r--src/com/vaadin/data/util/filter/AbstractJunctionFilter.java76
-rw-r--r--src/com/vaadin/data/util/filter/And.java44
-rw-r--r--src/com/vaadin/data/util/filter/Between.java74
-rw-r--r--src/com/vaadin/data/util/filter/Compare.java327
-rw-r--r--src/com/vaadin/data/util/filter/IsNull.java79
-rw-r--r--src/com/vaadin/data/util/filter/Like.java83
-rw-r--r--src/com/vaadin/data/util/filter/Not.java70
-rw-r--r--src/com/vaadin/data/util/filter/Or.java63
-rw-r--r--src/com/vaadin/data/util/filter/SimpleStringFilter.java152
-rw-r--r--src/com/vaadin/data/util/filter/UnsupportedFilterException.java35
-rw-r--r--src/com/vaadin/data/util/package.html18
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java92
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/CacheMap.java31
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java248
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java38
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java31
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/Reference.java56
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/RowId.java81
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/RowItem.java133
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/SQLContainer.java1716
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/SQLUtil.java36
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java32
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java72
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java41
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java168
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java507
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java118
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java57
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java46
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java211
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java715
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java367
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java101
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java112
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java88
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java163
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java23
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java25
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java38
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java16
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java22
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java30
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java29
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java23
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java98
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java30
-rw-r--r--src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java58
-rw-r--r--src/com/vaadin/data/validator/AbstractStringValidator.java42
-rw-r--r--src/com/vaadin/data/validator/AbstractValidator.java139
-rw-r--r--src/com/vaadin/data/validator/BeanValidator.java176
-rw-r--r--src/com/vaadin/data/validator/CompositeValidator.java259
-rw-r--r--src/com/vaadin/data/validator/DateRangeValidator.java51
-rw-r--r--src/com/vaadin/data/validator/DoubleRangeValidator.java37
-rw-r--r--src/com/vaadin/data/validator/DoubleValidator.java58
-rw-r--r--src/com/vaadin/data/validator/EmailValidator.java35
-rw-r--r--src/com/vaadin/data/validator/IntegerRangeValidator.java37
-rw-r--r--src/com/vaadin/data/validator/IntegerValidator.java58
-rw-r--r--src/com/vaadin/data/validator/NullValidator.java92
-rw-r--r--src/com/vaadin/data/validator/RangeValidator.java186
-rw-r--r--src/com/vaadin/data/validator/RegexpValidator.java97
-rw-r--r--src/com/vaadin/data/validator/StringLengthValidator.java139
-rw-r--r--src/com/vaadin/data/validator/package.html23
-rw-r--r--src/com/vaadin/event/Action.java195
-rw-r--r--src/com/vaadin/event/ActionManager.java249
-rw-r--r--src/com/vaadin/event/ComponentEventListener.java11
-rw-r--r--src/com/vaadin/event/DataBoundTransferable.java66
-rw-r--r--src/com/vaadin/event/EventRouter.java201
-rw-r--r--src/com/vaadin/event/FieldEvents.java275
-rw-r--r--src/com/vaadin/event/ItemClickEvent.java121
-rw-r--r--src/com/vaadin/event/LayoutEvents.java138
-rw-r--r--src/com/vaadin/event/ListenerMethod.java663
-rw-r--r--src/com/vaadin/event/MethodEventSource.java157
-rw-r--r--src/com/vaadin/event/MouseEvents.java234
-rw-r--r--src/com/vaadin/event/ShortcutAction.java373
-rw-r--r--src/com/vaadin/event/ShortcutListener.java33
-rw-r--r--src/com/vaadin/event/Transferable.java57
-rw-r--r--src/com/vaadin/event/TransferableImpl.java47
-rw-r--r--src/com/vaadin/event/dd/DragAndDropEvent.java50
-rw-r--r--src/com/vaadin/event/dd/DragSource.java52
-rw-r--r--src/com/vaadin/event/dd/DropHandler.java61
-rw-r--r--src/com/vaadin/event/dd/DropTarget.java42
-rw-r--r--src/com/vaadin/event/dd/TargetDetails.java37
-rw-r--r--src/com/vaadin/event/dd/TargetDetailsImpl.java46
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java36
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java75
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/And.java54
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java61
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java53
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/Not.java39
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/Or.java52
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java57
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/SourceIs.java67
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java51
-rw-r--r--src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java72
-rw-r--r--src/com/vaadin/event/package.html58
-rw-r--r--src/com/vaadin/external/json/JSONArray.java963
-rw-r--r--src/com/vaadin/external/json/JSONException.java32
-rw-r--r--src/com/vaadin/external/json/JSONObject.java1693
-rw-r--r--src/com/vaadin/external/json/JSONString.java21
-rw-r--r--src/com/vaadin/external/json/JSONStringer.java84
-rw-r--r--src/com/vaadin/external/json/JSONTokener.java451
-rw-r--r--src/com/vaadin/external/json/JSONWriter.java355
-rw-r--r--src/com/vaadin/external/json/README68
-rw-r--r--src/com/vaadin/navigator/FragmentManager.java38
-rw-r--r--src/com/vaadin/navigator/Navigator.java656
-rw-r--r--src/com/vaadin/navigator/View.java36
-rw-r--r--src/com/vaadin/navigator/ViewChangeListener.java118
-rw-r--r--src/com/vaadin/navigator/ViewDisplay.java29
-rw-r--r--src/com/vaadin/navigator/ViewProvider.java44
-rw-r--r--src/com/vaadin/package.html27
-rw-r--r--src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml6
-rw-r--r--src/com/vaadin/service/ApplicationContext.java165
-rw-r--r--src/com/vaadin/service/FileTypeResolver.java385
-rw-r--r--src/com/vaadin/service/package.html20
-rw-r--r--src/com/vaadin/terminal/AbstractClientConnector.java510
-rw-r--r--src/com/vaadin/terminal/AbstractErrorMessage.java176
-rw-r--r--src/com/vaadin/terminal/AbstractExtension.java76
-rw-r--r--src/com/vaadin/terminal/AbstractJavaScriptExtension.java162
-rw-r--r--src/com/vaadin/terminal/ApplicationResource.java75
-rw-r--r--src/com/vaadin/terminal/ClassResource.java178
-rw-r--r--src/com/vaadin/terminal/CombinedRequest.java187
-rw-r--r--src/com/vaadin/terminal/CompositeErrorMessage.java112
-rw-r--r--src/com/vaadin/terminal/DeploymentConfiguration.java123
-rw-r--r--src/com/vaadin/terminal/DownloadStream.java335
-rw-r--r--src/com/vaadin/terminal/ErrorMessage.java126
-rw-r--r--src/com/vaadin/terminal/Extension.java27
-rw-r--r--src/com/vaadin/terminal/ExternalResource.java118
-rw-r--r--src/com/vaadin/terminal/FileResource.java174
-rw-r--r--src/com/vaadin/terminal/JavaScriptCallbackHelper.java116
-rw-r--r--src/com/vaadin/terminal/KeyMapper.java86
-rw-r--r--src/com/vaadin/terminal/LegacyPaint.java85
-rw-r--r--src/com/vaadin/terminal/Page.java646
-rw-r--r--src/com/vaadin/terminal/PaintException.java54
-rw-r--r--src/com/vaadin/terminal/PaintTarget.java509
-rw-r--r--src/com/vaadin/terminal/RequestHandler.java36
-rw-r--r--src/com/vaadin/terminal/Resource.java26
-rw-r--r--src/com/vaadin/terminal/Scrollable.java80
-rw-r--r--src/com/vaadin/terminal/Sizeable.java242
-rw-r--r--src/com/vaadin/terminal/StreamResource.java222
-rw-r--r--src/com/vaadin/terminal/StreamVariable.java157
-rw-r--r--src/com/vaadin/terminal/SystemError.java82
-rw-r--r--src/com/vaadin/terminal/Terminal.java80
-rw-r--r--src/com/vaadin/terminal/ThemeResource.java96
-rw-r--r--src/com/vaadin/terminal/UserError.java70
-rw-r--r--src/com/vaadin/terminal/Vaadin6Component.java44
-rw-r--r--src/com/vaadin/terminal/VariableOwner.java85
-rw-r--r--src/com/vaadin/terminal/WrappedRequest.java277
-rw-r--r--src/com/vaadin/terminal/WrappedResponse.java147
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java1079
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java1623
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java2790
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java143
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractStreamingEvent.java46
-rw-r--r--src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java268
-rw-r--r--src/com/vaadin/terminal/gwt/server/AddonContext.java80
-rw-r--r--src/com/vaadin/terminal/gwt/server/AddonContextEvent.java19
-rw-r--r--src/com/vaadin/terminal/gwt/server/AddonContextListener.java13
-rw-r--r--src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java38
-rw-r--r--src/com/vaadin/terminal/gwt/server/ApplicationResourceHandler.java55
-rw-r--r--src/com/vaadin/terminal/gwt/server/ApplicationServlet.java78
-rw-r--r--src/com/vaadin/terminal/gwt/server/ApplicationStartedEvent.java28
-rw-r--r--src/com/vaadin/terminal/gwt/server/ApplicationStartedListener.java11
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapDom.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapFragmentResponse.java28
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapHandler.java570
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapListener.java13
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapPageResponse.java39
-rw-r--r--src/com/vaadin/terminal/gwt/server/BootstrapResponse.java45
-rw-r--r--src/com/vaadin/terminal/gwt/server/ChangeVariablesErrorEvent.java39
-rw-r--r--src/com/vaadin/terminal/gwt/server/ClientConnector.java149
-rw-r--r--src/com/vaadin/terminal/gwt/server/ClientMethodInvocation.java71
-rw-r--r--src/com/vaadin/terminal/gwt/server/CommunicationManager.java122
-rw-r--r--src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java664
-rw-r--r--src/com/vaadin/terminal/gwt/server/Constants.java80
-rw-r--r--src/com/vaadin/terminal/gwt/server/DragAndDropService.java313
-rw-r--r--src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java417
-rw-r--r--src/com/vaadin/terminal/gwt/server/HttpServletRequestListener.java54
-rw-r--r--src/com/vaadin/terminal/gwt/server/JsonCodec.java792
-rw-r--r--src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java1022
-rw-r--r--src/com/vaadin/terminal/gwt/server/LegacyChangeVariablesInvocation.java38
-rw-r--r--src/com/vaadin/terminal/gwt/server/NoInputStreamException.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/NoOutputStreamException.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java398
-rw-r--r--src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java170
-rw-r--r--src/com/vaadin/terminal/gwt/server/PortletRequestListener.java56
-rw-r--r--src/com/vaadin/terminal/gwt/server/RequestTimer.java43
-rw-r--r--src/com/vaadin/terminal/gwt/server/ResourceReference.java67
-rw-r--r--src/com/vaadin/terminal/gwt/server/RestrictedRenderResponse.java172
-rw-r--r--src/com/vaadin/terminal/gwt/server/RpcManager.java48
-rw-r--r--src/com/vaadin/terminal/gwt/server/RpcTarget.java28
-rw-r--r--src/com/vaadin/terminal/gwt/server/ServerRpcManager.java142
-rw-r--r--src/com/vaadin/terminal/gwt/server/ServerRpcMethodInvocation.java113
-rw-r--r--src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java120
-rw-r--r--src/com/vaadin/terminal/gwt/server/SessionExpiredException.java9
-rw-r--r--src/com/vaadin/terminal/gwt/server/StreamingEndEventImpl.java16
-rw-r--r--src/com/vaadin/terminal/gwt/server/StreamingErrorEventImpl.java25
-rw-r--r--src/com/vaadin/terminal/gwt/server/StreamingProgressEventImpl.java17
-rw-r--r--src/com/vaadin/terminal/gwt/server/StreamingStartEventImpl.java28
-rw-r--r--src/com/vaadin/terminal/gwt/server/SystemMessageException.java57
-rw-r--r--src/com/vaadin/terminal/gwt/server/UnsupportedBrowserHandler.java89
-rw-r--r--src/com/vaadin/terminal/gwt/server/UploadException.java15
-rw-r--r--src/com/vaadin/terminal/gwt/server/WebApplicationContext.java180
-rw-r--r--src/com/vaadin/terminal/gwt/server/WebBrowser.java462
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java118
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedHttpServletResponse.java75
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java217
-rw-r--r--src/com/vaadin/terminal/gwt/server/WrappedPortletResponse.java111
-rw-r--r--src/com/vaadin/terminal/package.html21
-rw-r--r--src/com/vaadin/tools/ReflectTools.java126
-rw-r--r--src/com/vaadin/tools/WidgetsetCompiler.java94
-rw-r--r--src/com/vaadin/ui/AbsoluteLayout.java632
-rw-r--r--src/com/vaadin/ui/AbstractComponent.java1382
-rw-r--r--src/com/vaadin/ui/AbstractComponentContainer.java351
-rw-r--r--src/com/vaadin/ui/AbstractField.java1657
-rw-r--r--src/com/vaadin/ui/AbstractJavaScriptComponent.java165
-rw-r--r--src/com/vaadin/ui/AbstractLayout.java77
-rw-r--r--src/com/vaadin/ui/AbstractMedia.java196
-rw-r--r--src/com/vaadin/ui/AbstractOrderedLayout.java383
-rw-r--r--src/com/vaadin/ui/AbstractSelect.java2029
-rw-r--r--src/com/vaadin/ui/AbstractSplitPanel.java521
-rw-r--r--src/com/vaadin/ui/AbstractTextField.java674
-rw-r--r--src/com/vaadin/ui/Accordion.java19
-rw-r--r--src/com/vaadin/ui/Alignment.java158
-rw-r--r--src/com/vaadin/ui/Audio.java55
-rw-r--r--src/com/vaadin/ui/Button.java539
-rw-r--r--src/com/vaadin/ui/CheckBox.java141
-rw-r--r--src/com/vaadin/ui/ComboBox.java116
-rw-r--r--src/com/vaadin/ui/Component.java1047
-rw-r--r--src/com/vaadin/ui/ComponentContainer.java222
-rw-r--r--src/com/vaadin/ui/ConnectorTracker.java320
-rw-r--r--src/com/vaadin/ui/CssLayout.java308
-rw-r--r--src/com/vaadin/ui/CustomComponent.java189
-rw-r--r--src/com/vaadin/ui/CustomField.java237
-rw-r--r--src/com/vaadin/ui/CustomLayout.java329
-rw-r--r--src/com/vaadin/ui/DateField.java869
-rw-r--r--src/com/vaadin/ui/DefaultFieldFactory.java146
-rw-r--r--src/com/vaadin/ui/DragAndDropWrapper.java407
-rw-r--r--src/com/vaadin/ui/Embedded.java531
-rw-r--r--src/com/vaadin/ui/Field.java97
-rw-r--r--src/com/vaadin/ui/Form.java1420
-rw-r--r--src/com/vaadin/ui/FormFieldFactory.java41
-rw-r--r--src/com/vaadin/ui/FormLayout.java31
-rw-r--r--src/com/vaadin/ui/GridLayout.java1415
-rw-r--r--src/com/vaadin/ui/HasComponents.java49
-rw-r--r--src/com/vaadin/ui/HorizontalLayout.java24
-rw-r--r--src/com/vaadin/ui/HorizontalSplitPanel.java34
-rw-r--r--src/com/vaadin/ui/Html5File.java65
-rw-r--r--src/com/vaadin/ui/InlineDateField.java46
-rw-r--r--src/com/vaadin/ui/JavaScript.java157
-rw-r--r--src/com/vaadin/ui/JavaScriptFunction.java41
-rw-r--r--src/com/vaadin/ui/Label.java483
-rw-r--r--src/com/vaadin/ui/Layout.java229
-rw-r--r--src/com/vaadin/ui/Link.java242
-rw-r--r--src/com/vaadin/ui/ListSelect.java96
-rw-r--r--src/com/vaadin/ui/LoginForm.java353
-rw-r--r--src/com/vaadin/ui/MenuBar.java890
-rw-r--r--src/com/vaadin/ui/NativeButton.java21
-rw-r--r--src/com/vaadin/ui/NativeSelect.java91
-rw-r--r--src/com/vaadin/ui/Notification.java367
-rw-r--r--src/com/vaadin/ui/OptionGroup.java203
-rw-r--r--src/com/vaadin/ui/Panel.java486
-rw-r--r--src/com/vaadin/ui/PasswordField.java67
-rw-r--r--src/com/vaadin/ui/PopupDateField.java80
-rw-r--r--src/com/vaadin/ui/PopupView.java453
-rw-r--r--src/com/vaadin/ui/ProgressIndicator.java257
-rw-r--r--src/com/vaadin/ui/RichTextArea.java344
-rw-r--r--src/com/vaadin/ui/Root.java1227
-rw-r--r--src/com/vaadin/ui/Select.java803
-rw-r--r--src/com/vaadin/ui/Slider.java372
-rw-r--r--src/com/vaadin/ui/TabSheet.java1328
-rw-r--r--src/com/vaadin/ui/Table.java5449
-rw-r--r--src/com/vaadin/ui/TableFieldFactory.java45
-rw-r--r--src/com/vaadin/ui/TextArea.java121
-rw-r--r--src/com/vaadin/ui/TextField.java92
-rw-r--r--src/com/vaadin/ui/Tree.java1615
-rw-r--r--src/com/vaadin/ui/TreeTable.java824
-rw-r--r--src/com/vaadin/ui/TwinColSelect.java180
-rw-r--r--src/com/vaadin/ui/UniqueSerializable.java30
-rw-r--r--src/com/vaadin/ui/Upload.java1055
-rw-r--r--src/com/vaadin/ui/VerticalLayout.java25
-rw-r--r--src/com/vaadin/ui/VerticalSplitPanel.java30
-rw-r--r--src/com/vaadin/ui/Video.java81
-rw-r--r--src/com/vaadin/ui/Window.java853
-rw-r--r--src/com/vaadin/ui/doc-files/component_class_hierarchy.gifbin11077 -> 0 bytes
-rw-r--r--src/com/vaadin/ui/doc-files/component_interfaces.gifbin2272 -> 0 bytes
-rw-r--r--src/com/vaadin/ui/package.html76
-rw-r--r--src/com/vaadin/ui/themes/BaseTheme.java59
-rw-r--r--src/com/vaadin/ui/themes/ChameleonTheme.java365
-rw-r--r--src/com/vaadin/ui/themes/LiferayTheme.java31
-rw-r--r--src/com/vaadin/ui/themes/Reindeer.java217
-rw-r--r--src/com/vaadin/ui/themes/Runo.java183
-rw-r--r--src/com/vaadin/util/SerializerHelper.java145
-rw-r--r--src/org/jsoup/Connection.java481
-rw-r--r--src/org/jsoup/Jsoup.java229
-rw-r--r--src/org/jsoup/examples/HtmlToPlainText.java109
-rw-r--r--src/org/jsoup/examples/ListLinks.java56
-rw-r--r--src/org/jsoup/examples/package-info.java4
-rw-r--r--src/org/jsoup/helper/DataUtil.java135
-rw-r--r--src/org/jsoup/helper/DescendableLinkedList.java82
-rw-r--r--src/org/jsoup/helper/HttpConnection.java658
-rw-r--r--src/org/jsoup/helper/StringUtil.java140
-rw-r--r--src/org/jsoup/helper/Validate.java112
-rw-r--r--src/org/jsoup/nodes/Attribute.java131
-rw-r--r--src/org/jsoup/nodes/Attributes.java249
-rw-r--r--src/org/jsoup/nodes/Comment.java46
-rw-r--r--src/org/jsoup/nodes/DataNode.java62
-rw-r--r--src/org/jsoup/nodes/Document.java350
-rw-r--r--src/org/jsoup/nodes/DocumentType.java46
-rw-r--r--src/org/jsoup/nodes/Element.java1119
-rw-r--r--src/org/jsoup/nodes/Entities.java184
-rw-r--r--src/org/jsoup/nodes/Node.java615
-rw-r--r--src/org/jsoup/nodes/TextNode.java175
-rw-r--r--src/org/jsoup/nodes/XmlDeclaration.java48
-rw-r--r--src/org/jsoup/nodes/entities-base.properties106
-rw-r--r--src/org/jsoup/nodes/entities-full.properties2032
-rw-r--r--src/org/jsoup/nodes/package-info.java4
-rw-r--r--src/org/jsoup/package-info.java4
-rw-r--r--src/org/jsoup/parser/CharacterReader.java230
-rw-r--r--src/org/jsoup/parser/HtmlTreeBuilder.java672
-rw-r--r--src/org/jsoup/parser/HtmlTreeBuilderState.java1482
-rw-r--r--src/org/jsoup/parser/ParseError.java40
-rw-r--r--src/org/jsoup/parser/ParseErrorList.java34
-rw-r--r--src/org/jsoup/parser/Parser.java157
-rw-r--r--src/org/jsoup/parser/Tag.java262
-rw-r--r--src/org/jsoup/parser/Token.java252
-rw-r--r--src/org/jsoup/parser/TokenQueue.java393
-rw-r--r--src/org/jsoup/parser/Tokeniser.java230
-rw-r--r--src/org/jsoup/parser/TokeniserState.java1778
-rw-r--r--src/org/jsoup/parser/TreeBuilder.java60
-rw-r--r--src/org/jsoup/parser/XmlTreeBuilder.java111
-rw-r--r--src/org/jsoup/parser/package-info.java4
-rw-r--r--src/org/jsoup/safety/Cleaner.java129
-rw-r--r--src/org/jsoup/safety/Whitelist.java451
-rw-r--r--src/org/jsoup/safety/package-info.java4
-rw-r--r--src/org/jsoup/select/Collector.java51
-rw-r--r--src/org/jsoup/select/CombiningEvaluator.java94
-rw-r--r--src/org/jsoup/select/Elements.java536
-rw-r--r--src/org/jsoup/select/Evaluator.java454
-rw-r--r--src/org/jsoup/select/NodeTraversor.java47
-rw-r--r--src/org/jsoup/select/NodeVisitor.java30
-rw-r--r--src/org/jsoup/select/QueryParser.java293
-rw-r--r--src/org/jsoup/select/Selector.java126
-rw-r--r--src/org/jsoup/select/StructuralEvaluator.java132
-rw-r--r--src/org/jsoup/select/package-info.java4
408 files changed, 0 insertions, 107042 deletions
diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java
deleted file mode 100644
index 1d31410185..0000000000
--- a/src/com/vaadin/Application.java
+++ /dev/null
@@ -1,2426 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.net.SocketException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.EventListener;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.vaadin.annotations.EagerInit;
-import com.vaadin.annotations.Theme;
-import com.vaadin.annotations.Widgetset;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.data.util.converter.ConverterFactory;
-import com.vaadin.data.util.converter.DefaultConverterFactory;
-import com.vaadin.event.EventRouter;
-import com.vaadin.service.ApplicationContext;
-import com.vaadin.terminal.AbstractErrorMessage;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedRequest.BrowserDetails;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-import com.vaadin.terminal.gwt.server.BootstrapFragmentResponse;
-import com.vaadin.terminal.gwt.server.BootstrapListener;
-import com.vaadin.terminal.gwt.server.BootstrapPageResponse;
-import com.vaadin.terminal.gwt.server.BootstrapResponse;
-import com.vaadin.terminal.gwt.server.ChangeVariablesErrorEvent;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-import com.vaadin.terminal.gwt.server.WebApplicationContext;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.AbstractComponent;
-import com.vaadin.ui.AbstractField;
-import com.vaadin.ui.Root;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.Window;
-
-/**
- * <p>
- * Base class required for all Vaadin applications. This class provides all the
- * basic services required by Vaadin. These services allow external discovery
- * and manipulation of the user, {@link com.vaadin.ui.Window windows} and
- * themes, and starting and stopping the application.
- * </p>
- *
- * <p>
- * As mentioned, all Vaadin applications must inherit this class. However, this
- * is almost all of what one needs to do to create a fully functional
- * application. The only thing a class inheriting the <code>Application</code>
- * needs to do is implement the <code>init</code> method where it creates the
- * windows it needs to perform its function. Note that all applications must
- * have at least one window: the main window. The first unnamed window
- * constructed by an application automatically becomes the main window which
- * behaves just like other windows with one exception: when accessing windows
- * using URLs the main window corresponds to the application URL whereas other
- * windows correspond to a URL gotten by catenating the window's name to the
- * application URL.
- * </p>
- *
- * <p>
- * See the class <code>com.vaadin.demo.HelloWorld</code> for a simple example of
- * a fully working application.
- * </p>
- *
- * <p>
- * <strong>Window access.</strong> <code>Application</code> provides methods to
- * list, add and remove the windows it contains.
- * </p>
- *
- * <p>
- * <strong>Execution control.</strong> This class includes method to start and
- * finish the execution of the application. Being finished means basically that
- * no windows will be available from the application anymore.
- * </p>
- *
- * <p>
- * <strong>Theme selection.</strong> The theme selection process allows a theme
- * to be specified at three different levels. When a window's theme needs to be
- * found out, the window itself is queried for a preferred theme. If the window
- * does not prefer a specific theme, the application containing the window is
- * queried. If neither the application prefers a theme, the default theme for
- * the {@link com.vaadin.terminal.Terminal terminal} is used. The terminal
- * always defines a default theme.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Application implements Terminal.ErrorListener, Serializable {
-
- /**
- * The name of the parameter that is by default used in e.g. web.xml to
- * define the name of the default {@link Root} class.
- */
- public static final String ROOT_PARAMETER = "root";
-
- private static final Method BOOTSTRAP_FRAGMENT_METHOD = ReflectTools
- .findMethod(BootstrapListener.class, "modifyBootstrapFragment",
- BootstrapFragmentResponse.class);
- private static final Method BOOTSTRAP_PAGE_METHOD = ReflectTools
- .findMethod(BootstrapListener.class, "modifyBootstrapPage",
- BootstrapPageResponse.class);
-
- /**
- * A special application designed to help migrating applications from Vaadin
- * 6 to Vaadin 7. The legacy application supports setting a main window,
- * adding additional browser level windows and defining the theme for the
- * entire application.
- *
- * @deprecated This class is only intended to ease migration and should not
- * be used for new projects.
- *
- * @since 7.0
- */
- @Deprecated
- public static class LegacyApplication extends Application {
- /**
- * Ignore initial / and then get everything up to the next /
- */
- private static final Pattern WINDOW_NAME_PATTERN = Pattern
- .compile("^/?([^/]+).*");
-
- private Root.LegacyWindow mainWindow;
- private String theme;
-
- private Map<String, Root.LegacyWindow> legacyRootNames = new HashMap<String, Root.LegacyWindow>();
-
- /**
- * Sets the main window of this application. Setting window as a main
- * window of this application also adds the window to this application.
- *
- * @param mainWindow
- * the root to set as the default window
- */
- public void setMainWindow(Root.LegacyWindow mainWindow) {
- if (this.mainWindow != null) {
- throw new IllegalStateException(
- "mainWindow has already been set");
- }
- if (mainWindow.getApplication() == null) {
- mainWindow.setApplication(this);
- } else if (mainWindow.getApplication() != this) {
- throw new IllegalStateException(
- "mainWindow is attached to another application");
- }
- this.mainWindow = mainWindow;
- }
-
- /**
- * Gets the mainWindow of the application.
- *
- * <p>
- * The main window is the window attached to the application URL (
- * {@link #getURL()}) and thus which is show by default to the user.
- * </p>
- * <p>
- * Note that each application must have at least one main window.
- * </p>
- *
- * @return the root used as the default window
- */
- public Root.LegacyWindow getMainWindow() {
- return mainWindow;
- }
-
- /**
- * This implementation simulates the way of finding a window for a
- * request by extracting a window name from the requested path and
- * passes that name to {@link #getWindow(String)}.
- *
- * {@inheritDoc}
- *
- * @see #getWindow(String)
- * @see Application#getRoot(WrappedRequest)
- */
-
- @Override
- public Root.LegacyWindow getRoot(WrappedRequest request) {
- String pathInfo = request.getRequestPathInfo();
- String name = null;
- if (pathInfo != null && pathInfo.length() > 0) {
- Matcher matcher = WINDOW_NAME_PATTERN.matcher(pathInfo);
- if (matcher.matches()) {
- // Skip the initial slash
- name = matcher.group(1);
- }
- }
- Root.LegacyWindow window = getWindow(name);
- if (window != null) {
- return window;
- }
- return mainWindow;
- }
-
- /**
- * Sets the application's theme.
- * <p>
- * Note that this theme can be overridden for a specific root with
- * {@link Application#getThemeForRoot(Root)}. Setting theme to be
- * <code>null</code> selects the default theme. For the available theme
- * names, see the contents of the VAADIN/themes directory.
- * </p>
- *
- * @param theme
- * the new theme for this application.
- */
- public void setTheme(String theme) {
- this.theme = theme;
- }
-
- /**
- * Gets the application's theme. The application's theme is the default
- * theme used by all the roots for which a theme is not explicitly
- * defined. If the application theme is not explicitly set,
- * <code>null</code> is returned.
- *
- * @return the name of the application's theme.
- */
- public String getTheme() {
- return theme;
- }
-
- /**
- * This implementation returns the theme that has been set using
- * {@link #setTheme(String)}
- * <p>
- * {@inheritDoc}
- */
-
- @Override
- public String getThemeForRoot(Root root) {
- return theme;
- }
-
- /**
- * <p>
- * Gets a root by name. Returns <code>null</code> if the application is
- * not running or it does not contain a window corresponding to the
- * name.
- * </p>
- *
- * @param name
- * the name of the requested window
- * @return a root corresponding to the name, or <code>null</code> to use
- * the default window
- */
- public Root.LegacyWindow getWindow(String name) {
- return legacyRootNames.get(name);
- }
-
- /**
- * Counter to get unique names for windows with no explicit name
- */
- private int namelessRootIndex = 0;
-
- /**
- * Adds a new browser level window to this application. Please note that
- * Root doesn't have a name that is used in the URL - to add a named
- * window you should instead use {@link #addWindow(Root, String)}
- *
- * @param root
- * the root window to add to the application
- * @return returns the name that has been assigned to the window
- *
- * @see #addWindow(Root, String)
- */
- public void addWindow(Root.LegacyWindow root) {
- if (root.getName() == null) {
- String name = Integer.toString(namelessRootIndex++);
- root.setName(name);
- }
-
- legacyRootNames.put(root.getName(), root);
- root.setApplication(this);
- }
-
- /**
- * Removes the specified window from the application. This also removes
- * all name mappings for the window (see
- * {@link #addWindow(Root, String) and #getWindowName(Root)}.
- *
- * <p>
- * Note that removing window from the application does not close the
- * browser window - the window is only removed from the server-side.
- * </p>
- *
- * @param root
- * the root to remove
- */
- public void removeWindow(Root.LegacyWindow root) {
- for (Entry<String, Root.LegacyWindow> entry : legacyRootNames
- .entrySet()) {
- if (entry.getValue() == root) {
- legacyRootNames.remove(entry.getKey());
- }
- }
- }
-
- /**
- * Gets the set of windows contained by the application.
- *
- * <p>
- * Note that the returned set of windows can not be modified.
- * </p>
- *
- * @return the unmodifiable collection of windows.
- */
- public Collection<Root.LegacyWindow> getWindows() {
- return Collections.unmodifiableCollection(legacyRootNames.values());
- }
- }
-
- /**
- * An event sent to {@link #start(ApplicationStartEvent)} when a new
- * Application is being started.
- *
- * @since 7.0
- */
- public static class ApplicationStartEvent implements Serializable {
- private final URL applicationUrl;
-
- private final Properties applicationProperties;
-
- private final ApplicationContext context;
-
- private final boolean productionMode;
-
- /**
- * @param applicationUrl
- * the URL the application should respond to.
- * @param applicationProperties
- * the Application properties as specified by the deployment
- * configuration.
- * @param context
- * the context application will be running in.
- * @param productionMode
- * flag indicating whether the application is running in
- * production mode.
- */
- public ApplicationStartEvent(URL applicationUrl,
- Properties applicationProperties, ApplicationContext context,
- boolean productionMode) {
- this.applicationUrl = applicationUrl;
- this.applicationProperties = applicationProperties;
- this.context = context;
- this.productionMode = productionMode;
- }
-
- /**
- * Gets the URL the application should respond to.
- *
- * @return the URL the application should respond to or
- * <code>null</code> if the URL is not defined.
- *
- * @see Application#getURL()
- */
- public URL getApplicationUrl() {
- return applicationUrl;
- }
-
- /**
- * Gets the Application properties as specified by the deployment
- * configuration.
- *
- * @return the properties configured for the applciation.
- *
- * @see Application#getProperty(String)
- */
- public Properties getApplicationProperties() {
- return applicationProperties;
- }
-
- /**
- * Gets the context application will be running in.
- *
- * @return the context application will be running in.
- *
- * @see Application#getContext()
- */
- public ApplicationContext getContext() {
- return context;
- }
-
- /**
- * Checks whether the application is running in production mode.
- *
- * @return <code>true</code> if in production mode, else
- * <code>false</code>
- *
- * @see Application#isProductionMode()
- */
- public boolean isProductionMode() {
- return productionMode;
- }
- }
-
- private final static Logger logger = Logger.getLogger(Application.class
- .getName());
-
- /**
- * Application context the application is running in.
- */
- private ApplicationContext context;
-
- /**
- * The current user or <code>null</code> if no user has logged in.
- */
- private Object user;
-
- /**
- * The application's URL.
- */
- private URL applicationUrl;
-
- /**
- * Application status.
- */
- private volatile boolean applicationIsRunning = false;
-
- /**
- * Application properties.
- */
- private Properties properties;
-
- /**
- * Default locale of the application.
- */
- private Locale locale;
-
- /**
- * List of listeners listening user changes.
- */
- private LinkedList<UserChangeListener> userChangeListeners = null;
-
- /**
- * Application resource mapping: key <-> resource.
- */
- private final Hashtable<ApplicationResource, String> resourceKeyMap = new Hashtable<ApplicationResource, String>();
-
- private final Hashtable<String, ApplicationResource> keyResourceMap = new Hashtable<String, ApplicationResource>();
-
- private long lastResourceKeyNumber = 0;
-
- /**
- * URL where the user is redirected to on application close, or null if
- * application is just closed without redirection.
- */
- private String logoutURL = null;
-
- /**
- * The default SystemMessages (read-only). Change by overriding
- * getSystemMessages() and returning CustomizedSystemMessages
- */
- private static final SystemMessages DEFAULT_SYSTEM_MESSAGES = new SystemMessages();
-
- /**
- * Application wide error handler which is used by default if an error is
- * left unhandled.
- */
- private Terminal.ErrorListener errorHandler = this;
-
- /**
- * The converter factory that is used to provide default converters for the
- * application.
- */
- private ConverterFactory converterFactory = new DefaultConverterFactory();
-
- private LinkedList<RequestHandler> requestHandlers = new LinkedList<RequestHandler>();
-
- private int nextRootId = 0;
- private Map<Integer, Root> roots = new HashMap<Integer, Root>();
-
- private boolean productionMode = true;
-
- private final Map<String, Integer> retainOnRefreshRoots = new HashMap<String, Integer>();
-
- private final EventRouter eventRouter = new EventRouter();
-
- /**
- * Keeps track of which roots have been inited.
- * <p>
- * TODO Investigate whether this might be derived from the different states
- * in getRootForRrequest.
- * </p>
- */
- private Set<Integer> initedRoots = new HashSet<Integer>();
-
- /**
- * Gets the user of the application.
- *
- * <p>
- * Vaadin doesn't define of use user object in any way - it only provides
- * this getter and setter methods for convenience. The user is any object
- * that has been stored to the application with {@link #setUser(Object)}.
- * </p>
- *
- * @return the User of the application.
- */
- public Object getUser() {
- return user;
- }
-
- /**
- * <p>
- * Sets the user of the application instance. An application instance may
- * have a user associated to it. This can be set in login procedure or
- * application initialization.
- * </p>
- * <p>
- * A component performing the user login procedure can assign the user
- * property of the application and make the user object available to other
- * components of the application.
- * </p>
- * <p>
- * Vaadin doesn't define of use user object in any way - it only provides
- * getter and setter methods for convenience. The user reference stored to
- * the application can be read with {@link #getUser()}.
- * </p>
- *
- * @param user
- * the new user.
- */
- public void setUser(Object user) {
- final Object prevUser = this.user;
- if (user == prevUser || (user != null && user.equals(prevUser))) {
- return;
- }
-
- this.user = user;
- if (userChangeListeners != null) {
- final Object[] listeners = userChangeListeners.toArray();
- final UserChangeEvent event = new UserChangeEvent(this, user,
- prevUser);
- for (int i = 0; i < listeners.length; i++) {
- ((UserChangeListener) listeners[i])
- .applicationUserChanged(event);
- }
- }
- }
-
- /**
- * Gets the URL of the application.
- *
- * <p>
- * This is the URL what can be entered to a browser window to start the
- * application. Navigating to the application URL shows the main window (
- * {@link #getMainWindow()}) of the application. Note that the main window
- * can also be shown by navigating to the window url (
- * {@link com.vaadin.ui.Window#getURL()}).
- * </p>
- *
- * @return the application's URL.
- */
- public URL getURL() {
- return applicationUrl;
- }
-
- /**
- * Ends the Application.
- *
- * <p>
- * In effect this will cause the application stop returning any windows when
- * asked. When the application is closed, its state is removed from the
- * session and the browser window is redirected to the application logout
- * url set with {@link #setLogoutURL(String)}. If the logout url has not
- * been set, the browser window is reloaded and the application is
- * restarted.
- * </p>
- * .
- */
- public void close() {
- applicationIsRunning = false;
- }
-
- /**
- * Starts the application on the given URL.
- *
- * <p>
- * This method is called by Vaadin framework when a user navigates to the
- * application. After this call the application corresponds to the given URL
- * and it will return windows when asked for them. There is no need to call
- * this method directly.
- * </p>
- *
- * <p>
- * Application properties are defined by servlet configuration object
- * {@link javax.servlet.ServletConfig} and they are overridden by
- * context-wide initialization parameters
- * {@link javax.servlet.ServletContext}.
- * </p>
- *
- * @param event
- * the application start event containing details required for
- * starting the application.
- *
- */
- public void start(ApplicationStartEvent event) {
- applicationUrl = event.getApplicationUrl();
- productionMode = event.isProductionMode();
- properties = event.getApplicationProperties();
- context = event.getContext();
- init();
- applicationIsRunning = true;
- }
-
- /**
- * Tests if the application is running or if it has been finished.
- *
- * <p>
- * Application starts running when its
- * {@link #start(URL, Properties, ApplicationContext)} method has been
- * called and stops when the {@link #close()} is called.
- * </p>
- *
- * @return <code>true</code> if the application is running,
- * <code>false</code> if not.
- */
- public boolean isRunning() {
- return applicationIsRunning;
- }
-
- /**
- * <p>
- * Main initializer of the application. The <code>init</code> method is
- * called by the framework when the application is started, and it should
- * perform whatever initialization operations the application needs.
- * </p>
- */
- public void init() {
- // Default implementation does nothing
- }
-
- /**
- * Returns an enumeration of all the names in this application.
- *
- * <p>
- * See {@link #start(URL, Properties, ApplicationContext)} how properties
- * are defined.
- * </p>
- *
- * @return an enumeration of all the keys in this property list, including
- * the keys in the default property list.
- *
- */
- public Enumeration<?> getPropertyNames() {
- return properties.propertyNames();
- }
-
- /**
- * Searches for the property with the specified name in this application.
- * This method returns <code>null</code> if the property is not found.
- *
- * See {@link #start(URL, Properties, ApplicationContext)} how properties
- * are defined.
- *
- * @param name
- * the name of the property.
- * @return the value in this property list with the specified key value.
- */
- public String getProperty(String name) {
- return properties.getProperty(name);
- }
-
- /**
- * Adds new resource to the application. The resource can be accessed by the
- * user of the application.
- *
- * @param resource
- * the resource to add.
- */
- public void addResource(ApplicationResource resource) {
-
- // Check if the resource is already mapped
- if (resourceKeyMap.containsKey(resource)) {
- return;
- }
-
- // Generate key
- final String key = String.valueOf(++lastResourceKeyNumber);
-
- // Add the resource to mappings
- resourceKeyMap.put(resource, key);
- keyResourceMap.put(key, resource);
- }
-
- /**
- * Removes the resource from the application.
- *
- * @param resource
- * the resource to remove.
- */
- public void removeResource(ApplicationResource resource) {
- final Object key = resourceKeyMap.get(resource);
- if (key != null) {
- resourceKeyMap.remove(resource);
- keyResourceMap.remove(key);
- }
- }
-
- /**
- * Gets the relative uri of the resource. This method is intended to be
- * called only be the terminal implementation.
- *
- * This method can only be called from within the processing of a UIDL
- * request, not from a background thread.
- *
- * @param resource
- * the resource to get relative location.
- * @return the relative uri of the resource or null if called in a
- * background thread
- *
- * @deprecated this method is intended to be used by the terminal only. It
- * may be removed or moved in the future.
- */
- @Deprecated
- public String getRelativeLocation(ApplicationResource resource) {
-
- // Gets the key
- final String key = resourceKeyMap.get(resource);
-
- // If the resource is not registered, return null
- if (key == null) {
- return null;
- }
-
- return context.generateApplicationResourceURL(resource, key);
- }
-
- /**
- * Gets the default locale for this application.
- *
- * By default this is the preferred locale of the user using the
- * application. In most cases it is read from the browser defaults.
- *
- * @return the locale of this application.
- */
- public Locale getLocale() {
- if (locale != null) {
- return locale;
- }
- return Locale.getDefault();
- }
-
- /**
- * Sets the default locale for this application.
- *
- * By default this is the preferred locale of the user using the
- * application. In most cases it is read from the browser defaults.
- *
- * @param locale
- * the Locale object.
- *
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * <p>
- * An event that characterizes a change in the current selection.
- * </p>
- * Application user change event sent when the setUser is called to change
- * the current user of the application.
- *
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class UserChangeEvent extends java.util.EventObject {
-
- /**
- * New user of the application.
- */
- private final Object newUser;
-
- /**
- * Previous user of the application.
- */
- private final Object prevUser;
-
- /**
- * Constructor for user change event.
- *
- * @param source
- * the application source.
- * @param newUser
- * the new User.
- * @param prevUser
- * the previous User.
- */
- public UserChangeEvent(Application source, Object newUser,
- Object prevUser) {
- super(source);
- this.newUser = newUser;
- this.prevUser = prevUser;
- }
-
- /**
- * Gets the new user of the application.
- *
- * @return the new User.
- */
- public Object getNewUser() {
- return newUser;
- }
-
- /**
- * Gets the previous user of the application.
- *
- * @return the previous Vaadin user, if user has not changed ever on
- * application it returns <code>null</code>
- */
- public Object getPreviousUser() {
- return prevUser;
- }
-
- /**
- * Gets the application where the user change occurred.
- *
- * @return the Application.
- */
- public Application getApplication() {
- return (Application) getSource();
- }
- }
-
- /**
- * The <code>UserChangeListener</code> interface for listening application
- * user changes.
- *
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface UserChangeListener extends EventListener, Serializable {
-
- /**
- * The <code>applicationUserChanged</code> method Invoked when the
- * application user has changed.
- *
- * @param event
- * the change event.
- */
- public void applicationUserChanged(Application.UserChangeEvent event);
- }
-
- /**
- * Adds the user change listener.
- *
- * This allows one to get notification each time {@link #setUser(Object)} is
- * called.
- *
- * @param listener
- * the user change listener to add.
- */
- public void addListener(UserChangeListener listener) {
- if (userChangeListeners == null) {
- userChangeListeners = new LinkedList<UserChangeListener>();
- }
- userChangeListeners.add(listener);
- }
-
- /**
- * Removes the user change listener.
- *
- * @param listener
- * the user change listener to remove.
- */
- public void removeListener(UserChangeListener listener) {
- if (userChangeListeners == null) {
- return;
- }
- userChangeListeners.remove(listener);
- if (userChangeListeners.isEmpty()) {
- userChangeListeners = null;
- }
- }
-
- /**
- * Window detach event.
- *
- * This event is sent each time a window is removed from the application
- * with {@link com.vaadin.Application#removeWindow(Window)}.
- */
- public class WindowDetachEvent extends EventObject {
-
- private final Window window;
-
- /**
- * Creates a event.
- *
- * @param window
- * the Detached window.
- */
- public WindowDetachEvent(Window window) {
- super(Application.this);
- this.window = window;
- }
-
- /**
- * Gets the detached window.
- *
- * @return the detached window.
- */
- public Window getWindow() {
- return window;
- }
-
- /**
- * Gets the application from which the window was detached.
- *
- * @return the Application.
- */
- public Application getApplication() {
- return (Application) getSource();
- }
- }
-
- /**
- * Window attach event.
- *
- * This event is sent each time a window is attached tothe application with
- * {@link com.vaadin.Application#addWindow(Window)}.
- */
- public class WindowAttachEvent extends EventObject {
-
- private final Window window;
-
- /**
- * Creates a event.
- *
- * @param window
- * the Attached window.
- */
- public WindowAttachEvent(Window window) {
- super(Application.this);
- this.window = window;
- }
-
- /**
- * Gets the attached window.
- *
- * @return the attached window.
- */
- public Window getWindow() {
- return window;
- }
-
- /**
- * Gets the application to which the window was attached.
- *
- * @return the Application.
- */
- public Application getApplication() {
- return (Application) getSource();
- }
- }
-
- /**
- * Window attach listener interface.
- */
- public interface WindowAttachListener extends Serializable {
-
- /**
- * Window attached
- *
- * @param event
- * the window attach event.
- */
- public void windowAttached(WindowAttachEvent event);
- }
-
- /**
- * Window detach listener interface.
- */
- public interface WindowDetachListener extends Serializable {
-
- /**
- * Window detached.
- *
- * @param event
- * the window detach event.
- */
- public void windowDetached(WindowDetachEvent event);
- }
-
- /**
- * Returns the URL user is redirected to on application close. If the URL is
- * <code>null</code>, the application is closed normally as defined by the
- * application running environment.
- * <p>
- * Desktop application just closes the application window and
- * web-application redirects the browser to application main URL.
- * </p>
- *
- * @return the URL.
- */
- public String getLogoutURL() {
- return logoutURL;
- }
-
- /**
- * Sets the URL user is redirected to on application close. If the URL is
- * <code>null</code>, the application is closed normally as defined by the
- * application running environment: Desktop application just closes the
- * application window and web-application redirects the browser to
- * application main URL.
- *
- * @param logoutURL
- * the logoutURL to set.
- */
- public void setLogoutURL(String logoutURL) {
- this.logoutURL = logoutURL;
- }
-
- /**
- * Gets the SystemMessages for this application. SystemMessages are used to
- * notify the user of various critical situations that can occur, such as
- * session expiration, client/server out of sync, and internal server error.
- *
- * You can customize the messages by "overriding" this method and returning
- * {@link CustomizedSystemMessages}. To "override" this method, re-implement
- * this method in your application (the class that extends
- * {@link Application}). Even though overriding static methods is not
- * possible in Java, Vaadin selects to call the static method from the
- * subclass instead of the original {@link #getSystemMessages()} if such a
- * method exists.
- *
- * @return the SystemMessages for this application
- */
- public static SystemMessages getSystemMessages() {
- return DEFAULT_SYSTEM_MESSAGES;
- }
-
- /**
- * <p>
- * Invoked by the terminal on any exception that occurs in application and
- * is thrown by the <code>setVariable</code> to the terminal. The default
- * implementation sets the exceptions as <code>ComponentErrors</code> to the
- * component that initiated the exception and prints stack trace to standard
- * error stream.
- * </p>
- * <p>
- * You can safely override this method in your application in order to
- * direct the errors to some other destination (for example log).
- * </p>
- *
- * @param event
- * the change event.
- * @see com.vaadin.terminal.Terminal.ErrorListener#terminalError(com.vaadin.terminal.Terminal.ErrorEvent)
- */
-
- @Override
- public void terminalError(Terminal.ErrorEvent event) {
- final Throwable t = event.getThrowable();
- if (t instanceof SocketException) {
- // Most likely client browser closed socket
- getLogger().info(
- "SocketException in CommunicationManager."
- + " Most likely client (browser) closed socket.");
- return;
- }
-
- // Finds the original source of the error/exception
- Object owner = null;
- if (event instanceof VariableOwner.ErrorEvent) {
- owner = ((VariableOwner.ErrorEvent) event).getVariableOwner();
- } else if (event instanceof ChangeVariablesErrorEvent) {
- owner = ((ChangeVariablesErrorEvent) event).getComponent();
- }
-
- // Shows the error in AbstractComponent
- if (owner instanceof AbstractComponent) {
- ((AbstractComponent) owner).setComponentError(AbstractErrorMessage
- .getErrorMessageForException(t));
- }
-
- // also print the error on console
- getLogger().log(Level.SEVERE, "Terminal error:", t);
- }
-
- /**
- * Gets the application context.
- * <p>
- * The application context is the environment where the application is
- * running in. The actual implementation class of may contains quite a lot
- * more functionality than defined in the {@link ApplicationContext}
- * interface.
- * </p>
- * <p>
- * By default, when you are deploying your application to a servlet
- * container, the implementation class is {@link WebApplicationContext} -
- * you can safely cast to this class and use the methods from there. When
- * you are deploying your application as a portlet, context implementation
- * is {@link PortletApplicationContext}.
- * </p>
- *
- * @return the application context.
- */
- public ApplicationContext getContext() {
- return context;
- }
-
- /**
- * Override this method to return correct version number of your
- * Application. Version information is delivered for example to Testing
- * Tools test results. By default this returns a string "NONVERSIONED".
- *
- * @return version string
- */
- public String getVersion() {
- return "NONVERSIONED";
- }
-
- /**
- * Gets the application error handler.
- *
- * The default error handler is the application itself.
- *
- * @return Application error handler
- */
- public Terminal.ErrorListener getErrorHandler() {
- return errorHandler;
- }
-
- /**
- * Sets the application error handler.
- *
- * The default error handler is the application itself. By overriding this,
- * you can redirect the error messages to your selected target (log for
- * example).
- *
- * @param errorHandler
- */
- public void setErrorHandler(Terminal.ErrorListener errorHandler) {
- this.errorHandler = errorHandler;
- }
-
- /**
- * Gets the {@link ConverterFactory} used to locate a suitable
- * {@link Converter} for fields in the application.
- *
- * See {@link #setConverterFactory(ConverterFactory)} for more details
- *
- * @return The converter factory used in the application
- */
- public ConverterFactory getConverterFactory() {
- return converterFactory;
- }
-
- /**
- * Sets the {@link ConverterFactory} used to locate a suitable
- * {@link Converter} for fields in the application.
- * <p>
- * The {@link ConverterFactory} is used to find a suitable converter when
- * binding data to a UI component and the data type does not match the UI
- * component type, e.g. binding a Double to a TextField (which is based on a
- * String).
- * </p>
- * <p>
- * The {@link Converter} for an individual field can be overridden using
- * {@link AbstractField#setConverter(Converter)} and for individual property
- * ids in a {@link Table} using
- * {@link Table#setConverter(Object, Converter)}.
- * </p>
- * <p>
- * The converter factory must never be set to null.
- *
- * @param converterFactory
- * The converter factory used in the application
- */
- public void setConverterFactory(ConverterFactory converterFactory) {
- this.converterFactory = converterFactory;
- }
-
- /**
- * Contains the system messages used to notify the user about various
- * critical situations that can occur.
- * <p>
- * Customize by overriding the static
- * {@link Application#getSystemMessages()} and returning
- * {@link CustomizedSystemMessages}.
- * </p>
- * <p>
- * The defaults defined in this class are:
- * <ul>
- * <li><b>sessionExpiredURL</b> = null</li>
- * <li><b>sessionExpiredNotificationEnabled</b> = true</li>
- * <li><b>sessionExpiredCaption</b> = ""</li>
- * <li><b>sessionExpiredMessage</b> =
- * "Take note of any unsaved data, and <u>click here</u> to continue."</li>
- * <li><b>communicationErrorURL</b> = null</li>
- * <li><b>communicationErrorNotificationEnabled</b> = true</li>
- * <li><b>communicationErrorCaption</b> = "Communication problem"</li>
- * <li><b>communicationErrorMessage</b> =
- * "Take note of any unsaved data, and <u>click here</u> to continue."</li>
- * <li><b>internalErrorURL</b> = null</li>
- * <li><b>internalErrorNotificationEnabled</b> = true</li>
- * <li><b>internalErrorCaption</b> = "Internal error"</li>
- * <li><b>internalErrorMessage</b> = "Please notify the administrator.<br/>
- * Take note of any unsaved data, and <u>click here</u> to continue."</li>
- * <li><b>outOfSyncURL</b> = null</li>
- * <li><b>outOfSyncNotificationEnabled</b> = true</li>
- * <li><b>outOfSyncCaption</b> = "Out of sync"</li>
- * <li><b>outOfSyncMessage</b> = "Something has caused us to be out of sync
- * with the server.<br/>
- * Take note of any unsaved data, and <u>click here</u> to re-sync."</li>
- * <li><b>cookiesDisabledURL</b> = null</li>
- * <li><b>cookiesDisabledNotificationEnabled</b> = true</li>
- * <li><b>cookiesDisabledCaption</b> = "Cookies disabled"</li>
- * <li><b>cookiesDisabledMessage</b> = "This application requires cookies to
- * function.<br/>
- * Please enable cookies in your browser and <u>click here</u> to try again.
- * </li>
- * </ul>
- * </p>
- *
- */
- public static class SystemMessages implements Serializable {
- protected String sessionExpiredURL = null;
- protected boolean sessionExpiredNotificationEnabled = true;
- protected String sessionExpiredCaption = "Session Expired";
- protected String sessionExpiredMessage = "Take note of any unsaved data, and <u>click here</u> to continue.";
-
- protected String communicationErrorURL = null;
- protected boolean communicationErrorNotificationEnabled = true;
- protected String communicationErrorCaption = "Communication problem";
- protected String communicationErrorMessage = "Take note of any unsaved data, and <u>click here</u> to continue.";
-
- protected String authenticationErrorURL = null;
- protected boolean authenticationErrorNotificationEnabled = true;
- protected String authenticationErrorCaption = "Authentication problem";
- protected String authenticationErrorMessage = "Take note of any unsaved data, and <u>click here</u> to continue.";
-
- protected String internalErrorURL = null;
- protected boolean internalErrorNotificationEnabled = true;
- protected String internalErrorCaption = "Internal error";
- protected String internalErrorMessage = "Please notify the administrator.<br/>Take note of any unsaved data, and <u>click here</u> to continue.";
-
- protected String outOfSyncURL = null;
- protected boolean outOfSyncNotificationEnabled = true;
- protected String outOfSyncCaption = "Out of sync";
- protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.<br/>Take note of any unsaved data, and <u>click here</u> to re-sync.";
-
- protected String cookiesDisabledURL = null;
- protected boolean cookiesDisabledNotificationEnabled = true;
- protected String cookiesDisabledCaption = "Cookies disabled";
- protected String cookiesDisabledMessage = "This application requires cookies to function.<br/>Please enable cookies in your browser and <u>click here</u> to try again.";
-
- /**
- * Use {@link CustomizedSystemMessages} to customize
- */
- private SystemMessages() {
-
- }
-
- /**
- * @return null to indicate that the application will be restarted after
- * session expired message has been shown.
- */
- public String getSessionExpiredURL() {
- return sessionExpiredURL;
- }
-
- /**
- * @return true to show session expiration message.
- */
- public boolean isSessionExpiredNotificationEnabled() {
- return sessionExpiredNotificationEnabled;
- }
-
- /**
- * @return "" to show no caption.
- */
- public String getSessionExpiredCaption() {
- return (sessionExpiredNotificationEnabled ? sessionExpiredCaption
- : null);
- }
-
- /**
- * @return
- * "Take note of any unsaved data, and <u>click here</u> to continue."
- */
- public String getSessionExpiredMessage() {
- return (sessionExpiredNotificationEnabled ? sessionExpiredMessage
- : null);
- }
-
- /**
- * @return null to reload the application after communication error
- * message.
- */
- public String getCommunicationErrorURL() {
- return communicationErrorURL;
- }
-
- /**
- * @return true to show the communication error message.
- */
- public boolean isCommunicationErrorNotificationEnabled() {
- return communicationErrorNotificationEnabled;
- }
-
- /**
- * @return "Communication problem"
- */
- public String getCommunicationErrorCaption() {
- return (communicationErrorNotificationEnabled ? communicationErrorCaption
- : null);
- }
-
- /**
- * @return
- * "Take note of any unsaved data, and <u>click here</u> to continue."
- */
- public String getCommunicationErrorMessage() {
- return (communicationErrorNotificationEnabled ? communicationErrorMessage
- : null);
- }
-
- /**
- * @return null to reload the application after authentication error
- * message.
- */
- public String getAuthenticationErrorURL() {
- return authenticationErrorURL;
- }
-
- /**
- * @return true to show the authentication error message.
- */
- public boolean isAuthenticationErrorNotificationEnabled() {
- return authenticationErrorNotificationEnabled;
- }
-
- /**
- * @return "Authentication problem"
- */
- public String getAuthenticationErrorCaption() {
- return (authenticationErrorNotificationEnabled ? authenticationErrorCaption
- : null);
- }
-
- /**
- * @return
- * "Take note of any unsaved data, and <u>click here</u> to continue."
- */
- public String getAuthenticationErrorMessage() {
- return (authenticationErrorNotificationEnabled ? authenticationErrorMessage
- : null);
- }
-
- /**
- * @return null to reload the current URL after internal error message
- * has been shown.
- */
- public String getInternalErrorURL() {
- return internalErrorURL;
- }
-
- /**
- * @return true to enable showing of internal error message.
- */
- public boolean isInternalErrorNotificationEnabled() {
- return internalErrorNotificationEnabled;
- }
-
- /**
- * @return "Internal error"
- */
- public String getInternalErrorCaption() {
- return (internalErrorNotificationEnabled ? internalErrorCaption
- : null);
- }
-
- /**
- * @return "Please notify the administrator.<br/>
- * Take note of any unsaved data, and <u>click here</u> to
- * continue."
- */
- public String getInternalErrorMessage() {
- return (internalErrorNotificationEnabled ? internalErrorMessage
- : null);
- }
-
- /**
- * @return null to reload the application after out of sync message.
- */
- public String getOutOfSyncURL() {
- return outOfSyncURL;
- }
-
- /**
- * @return true to enable showing out of sync message
- */
- public boolean isOutOfSyncNotificationEnabled() {
- return outOfSyncNotificationEnabled;
- }
-
- /**
- * @return "Out of sync"
- */
- public String getOutOfSyncCaption() {
- return (outOfSyncNotificationEnabled ? outOfSyncCaption : null);
- }
-
- /**
- * @return "Something has caused us to be out of sync with the server.<br/>
- * Take note of any unsaved data, and <u>click here</u> to
- * re-sync."
- */
- public String getOutOfSyncMessage() {
- return (outOfSyncNotificationEnabled ? outOfSyncMessage : null);
- }
-
- /**
- * Returns the URL the user should be redirected to after dismissing the
- * "you have to enable your cookies" message. Typically null.
- *
- * @return A URL the user should be redirected to after dismissing the
- * message or null to reload the current URL.
- */
- public String getCookiesDisabledURL() {
- return cookiesDisabledURL;
- }
-
- /**
- * Determines if "cookies disabled" messages should be shown to the end
- * user or not. If the notification is disabled the user will be
- * immediately redirected to the URL returned by
- * {@link #getCookiesDisabledURL()}.
- *
- * @return true to show "cookies disabled" messages to the end user,
- * false to redirect to the given URL directly
- */
- public boolean isCookiesDisabledNotificationEnabled() {
- return cookiesDisabledNotificationEnabled;
- }
-
- /**
- * Returns the caption of the message shown to the user when cookies are
- * disabled in the browser.
- *
- * @return The caption of the "cookies disabled" message
- */
- public String getCookiesDisabledCaption() {
- return (cookiesDisabledNotificationEnabled ? cookiesDisabledCaption
- : null);
- }
-
- /**
- * Returns the message shown to the user when cookies are disabled in
- * the browser.
- *
- * @return The "cookies disabled" message
- */
- public String getCookiesDisabledMessage() {
- return (cookiesDisabledNotificationEnabled ? cookiesDisabledMessage
- : null);
- }
-
- }
-
- /**
- * Contains the system messages used to notify the user about various
- * critical situations that can occur.
- * <p>
- * Vaadin gets the SystemMessages from your application by calling a static
- * getSystemMessages() method. By default the
- * Application.getSystemMessages() is used. You can customize this by
- * defining a static MyApplication.getSystemMessages() and returning
- * CustomizedSystemMessages. Note that getSystemMessages() is static -
- * changing the system messages will by default change the message for all
- * users of the application.
- * </p>
- * <p>
- * The default behavior is to show a notification, and restart the
- * application the the user clicks the message. <br/>
- * Instead of restarting the application, you can set a specific URL that
- * the user is taken to.<br/>
- * Setting both caption and message to null will restart the application (or
- * go to the specified URL) without displaying a notification.
- * set*NotificationEnabled(false) will achieve the same thing.
- * </p>
- * <p>
- * The situations are:
- * <li>Session expired: the user session has expired, usually due to
- * inactivity.</li>
- * <li>Communication error: the client failed to contact the server, or the
- * server returned and invalid response.</li>
- * <li>Internal error: unhandled critical server error (e.g out of memory,
- * database crash)
- * <li>Out of sync: the client is not in sync with the server. E.g the user
- * opens two windows showing the same application, but the application does
- * not support this and uses the same Window instance. When the user makes
- * changes in one of the windows - the other window is no longer in sync,
- * and (for instance) pressing a button that is no longer present in the UI
- * will cause a out-of-sync -situation.
- * </p>
- */
-
- public static class CustomizedSystemMessages extends SystemMessages
- implements Serializable {
-
- /**
- * Sets the URL to go to when the session has expired.
- *
- * @param sessionExpiredURL
- * the URL to go to, or null to reload current
- */
- public void setSessionExpiredURL(String sessionExpiredURL) {
- this.sessionExpiredURL = sessionExpiredURL;
- }
-
- /**
- * Enables or disables the notification. If disabled, the set URL (or
- * current) is loaded directly when next transaction between server and
- * client happens.
- *
- * @param sessionExpiredNotificationEnabled
- * true = enabled, false = disabled
- */
- public void setSessionExpiredNotificationEnabled(
- boolean sessionExpiredNotificationEnabled) {
- this.sessionExpiredNotificationEnabled = sessionExpiredNotificationEnabled;
- }
-
- /**
- * Sets the caption of the notification. Set to null for no caption. If
- * both caption and message are null, client automatically forwards to
- * sessionExpiredUrl after timeout timer expires. Timer uses value read
- * from HTTPSession.getMaxInactiveInterval()
- *
- * @param sessionExpiredCaption
- * the caption
- */
- public void setSessionExpiredCaption(String sessionExpiredCaption) {
- this.sessionExpiredCaption = sessionExpiredCaption;
- }
-
- /**
- * Sets the message of the notification. Set to null for no message. If
- * both caption and message are null, client automatically forwards to
- * sessionExpiredUrl after timeout timer expires. Timer uses value read
- * from HTTPSession.getMaxInactiveInterval()
- *
- * @param sessionExpiredMessage
- * the message
- */
- public void setSessionExpiredMessage(String sessionExpiredMessage) {
- this.sessionExpiredMessage = sessionExpiredMessage;
- }
-
- /**
- * Sets the URL to go to when there is a authentication error.
- *
- * @param authenticationErrorURL
- * the URL to go to, or null to reload current
- */
- public void setAuthenticationErrorURL(String authenticationErrorURL) {
- this.authenticationErrorURL = authenticationErrorURL;
- }
-
- /**
- * Enables or disables the notification. If disabled, the set URL (or
- * current) is loaded directly.
- *
- * @param authenticationErrorNotificationEnabled
- * true = enabled, false = disabled
- */
- public void setAuthenticationErrorNotificationEnabled(
- boolean authenticationErrorNotificationEnabled) {
- this.authenticationErrorNotificationEnabled = authenticationErrorNotificationEnabled;
- }
-
- /**
- * Sets the caption of the notification. Set to null for no caption. If
- * both caption and message is null, the notification is disabled;
- *
- * @param authenticationErrorCaption
- * the caption
- */
- public void setAuthenticationErrorCaption(
- String authenticationErrorCaption) {
- this.authenticationErrorCaption = authenticationErrorCaption;
- }
-
- /**
- * Sets the message of the notification. Set to null for no message. If
- * both caption and message is null, the notification is disabled;
- *
- * @param authenticationErrorMessage
- * the message
- */
- public void setAuthenticationErrorMessage(
- String authenticationErrorMessage) {
- this.authenticationErrorMessage = authenticationErrorMessage;
- }
-
- /**
- * Sets the URL to go to when there is a communication error.
- *
- * @param communicationErrorURL
- * the URL to go to, or null to reload current
- */
- public void setCommunicationErrorURL(String communicationErrorURL) {
- this.communicationErrorURL = communicationErrorURL;
- }
-
- /**
- * Enables or disables the notification. If disabled, the set URL (or
- * current) is loaded directly.
- *
- * @param communicationErrorNotificationEnabled
- * true = enabled, false = disabled
- */
- public void setCommunicationErrorNotificationEnabled(
- boolean communicationErrorNotificationEnabled) {
- this.communicationErrorNotificationEnabled = communicationErrorNotificationEnabled;
- }
-
- /**
- * Sets the caption of the notification. Set to null for no caption. If
- * both caption and message is null, the notification is disabled;
- *
- * @param communicationErrorCaption
- * the caption
- */
- public void setCommunicationErrorCaption(
- String communicationErrorCaption) {
- this.communicationErrorCaption = communicationErrorCaption;
- }
-
- /**
- * Sets the message of the notification. Set to null for no message. If
- * both caption and message is null, the notification is disabled;
- *
- * @param communicationErrorMessage
- * the message
- */
- public void setCommunicationErrorMessage(
- String communicationErrorMessage) {
- this.communicationErrorMessage = communicationErrorMessage;
- }
-
- /**
- * Sets the URL to go to when an internal error occurs.
- *
- * @param internalErrorURL
- * the URL to go to, or null to reload current
- */
- public void setInternalErrorURL(String internalErrorURL) {
- this.internalErrorURL = internalErrorURL;
- }
-
- /**
- * Enables or disables the notification. If disabled, the set URL (or
- * current) is loaded directly.
- *
- * @param internalErrorNotificationEnabled
- * true = enabled, false = disabled
- */
- public void setInternalErrorNotificationEnabled(
- boolean internalErrorNotificationEnabled) {
- this.internalErrorNotificationEnabled = internalErrorNotificationEnabled;
- }
-
- /**
- * Sets the caption of the notification. Set to null for no caption. If
- * both caption and message is null, the notification is disabled;
- *
- * @param internalErrorCaption
- * the caption
- */
- public void setInternalErrorCaption(String internalErrorCaption) {
- this.internalErrorCaption = internalErrorCaption;
- }
-
- /**
- * Sets the message of the notification. Set to null for no message. If
- * both caption and message is null, the notification is disabled;
- *
- * @param internalErrorMessage
- * the message
- */
- public void setInternalErrorMessage(String internalErrorMessage) {
- this.internalErrorMessage = internalErrorMessage;
- }
-
- /**
- * Sets the URL to go to when the client is out-of-sync.
- *
- * @param outOfSyncURL
- * the URL to go to, or null to reload current
- */
- public void setOutOfSyncURL(String outOfSyncURL) {
- this.outOfSyncURL = outOfSyncURL;
- }
-
- /**
- * Enables or disables the notification. If disabled, the set URL (or
- * current) is loaded directly.
- *
- * @param outOfSyncNotificationEnabled
- * true = enabled, false = disabled
- */
- public void setOutOfSyncNotificationEnabled(
- boolean outOfSyncNotificationEnabled) {
- this.outOfSyncNotificationEnabled = outOfSyncNotificationEnabled;
- }
-
- /**
- * Sets the caption of the notification. Set to null for no caption. If
- * both caption and message is null, the notification is disabled;
- *
- * @param outOfSyncCaption
- * the caption
- */
- public void setOutOfSyncCaption(String outOfSyncCaption) {
- this.outOfSyncCaption = outOfSyncCaption;
- }
-
- /**
- * Sets the message of the notification. Set to null for no message. If
- * both caption and message is null, the notification is disabled;
- *
- * @param outOfSyncMessage
- * the message
- */
- public void setOutOfSyncMessage(String outOfSyncMessage) {
- this.outOfSyncMessage = outOfSyncMessage;
- }
-
- /**
- * Sets the URL to redirect to when the browser has cookies disabled.
- *
- * @param cookiesDisabledURL
- * the URL to redirect to, or null to reload the current URL
- */
- public void setCookiesDisabledURL(String cookiesDisabledURL) {
- this.cookiesDisabledURL = cookiesDisabledURL;
- }
-
- /**
- * Enables or disables the notification for "cookies disabled" messages.
- * If disabled, the URL returned by {@link #getCookiesDisabledURL()} is
- * loaded directly.
- *
- * @param cookiesDisabledNotificationEnabled
- * true to enable "cookies disabled" messages, false
- * otherwise
- */
- public void setCookiesDisabledNotificationEnabled(
- boolean cookiesDisabledNotificationEnabled) {
- this.cookiesDisabledNotificationEnabled = cookiesDisabledNotificationEnabled;
- }
-
- /**
- * Sets the caption of the "cookies disabled" notification. Set to null
- * for no caption. If both caption and message is null, the notification
- * is disabled.
- *
- * @param cookiesDisabledCaption
- * the caption for the "cookies disabled" notification
- */
- public void setCookiesDisabledCaption(String cookiesDisabledCaption) {
- this.cookiesDisabledCaption = cookiesDisabledCaption;
- }
-
- /**
- * Sets the message of the "cookies disabled" notification. Set to null
- * for no message. If both caption and message is null, the notification
- * is disabled.
- *
- * @param cookiesDisabledMessage
- * the message for the "cookies disabled" notification
- */
- public void setCookiesDisabledMessage(String cookiesDisabledMessage) {
- this.cookiesDisabledMessage = cookiesDisabledMessage;
- }
-
- }
-
- /**
- * Application error is an error message defined on the application level.
- *
- * When an error occurs on the application level, this error message type
- * should be used. This indicates that the problem is caused by the
- * application - not by the user.
- */
- public class ApplicationError implements Terminal.ErrorEvent {
- private final Throwable throwable;
-
- public ApplicationError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
- * Gets a root for a request for which no root is already known. This method
- * is called when the framework processes a request that does not originate
- * from an existing root instance. This typically happens when a host page
- * is requested.
- *
- * <p>
- * Subclasses of Application may override this method to provide custom
- * logic for choosing how to create a suitable root or for picking an
- * already created root. If an existing root is picked, care should be taken
- * to avoid keeping the same root open in multiple browser windows, as that
- * will cause the states to go out of sync.
- * </p>
- *
- * <p>
- * If {@link BrowserDetails} are required to create a Root, the
- * implementation can throw a {@link RootRequiresMoreInformationException}
- * exception. In this case, the framework will instruct the browser to send
- * the additional details, whereupon this method is invoked again with the
- * browser details present in the wrapped request. Throwing the exception if
- * the browser details are already available is not supported.
- * </p>
- *
- * <p>
- * The default implementation in {@link Application} creates a new instance
- * of the Root class returned by {@link #getRootClassName(WrappedRequest)},
- * which in turn uses the {@value #ROOT_PARAMETER} parameter from web.xml.
- * If {@link DeploymentConfiguration#getClassLoader()} for the request
- * returns a {@link ClassLoader}, it is used for loading the Root class.
- * Otherwise the {@link ClassLoader} used to load this class is used.
- * </p>
- *
- * @param request
- * the wrapped request for which a root is needed
- * @return a root instance to use for the request
- * @throws RootRequiresMoreInformationException
- * may be thrown by an implementation to indicate that
- * {@link BrowserDetails} are required to create a root
- *
- * @see #getRootClassName(WrappedRequest)
- * @see Root
- * @see RootRequiresMoreInformationException
- * @see WrappedRequest#getBrowserDetails()
- *
- * @since 7.0
- */
- protected Root getRoot(WrappedRequest request)
- throws RootRequiresMoreInformationException {
- String rootClassName = getRootClassName(request);
- try {
- ClassLoader classLoader = request.getDeploymentConfiguration()
- .getClassLoader();
- if (classLoader == null) {
- classLoader = getClass().getClassLoader();
- }
- Class<? extends Root> rootClass = Class.forName(rootClassName,
- true, classLoader).asSubclass(Root.class);
- try {
- Root root = rootClass.newInstance();
- return root;
- } catch (Exception e) {
- throw new RuntimeException("Could not instantiate root class "
- + rootClassName, e);
- }
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Could not load root class "
- + rootClassName, e);
- }
- }
-
- /**
- * Provides the name of the <code>Root</code> class that should be used for
- * a request. The class must have an accessible no-args constructor.
- * <p>
- * The default implementation uses the {@value #ROOT_PARAMETER} parameter
- * from web.xml.
- * </p>
- * <p>
- * This method is mainly used by the default implementation of
- * {@link #getRoot(WrappedRequest)}. If you override that method with your
- * own functionality, the results of this method might not be used.
- * </p>
- *
- * @param request
- * the request for which a new root is required
- * @return the name of the root class to use
- *
- * @since 7.0
- */
- protected String getRootClassName(WrappedRequest request) {
- Object rootClassNameObj = properties.get(ROOT_PARAMETER);
- if (rootClassNameObj instanceof String) {
- return (String) rootClassNameObj;
- } else {
- throw new RuntimeException("No " + ROOT_PARAMETER
- + " defined in web.xml");
- }
- }
-
- /**
- * Finds the theme to use for a specific root. If no specific theme is
- * required, <code>null</code> is returned.
- *
- * TODO Tell what the default implementation does once it does something.
- *
- * @param root
- * the root to get a theme for
- * @return the name of the theme, or <code>null</code> if the default theme
- * should be used
- *
- * @since 7.0
- */
- public String getThemeForRoot(Root root) {
- Theme rootTheme = getAnnotationFor(root.getClass(), Theme.class);
- if (rootTheme != null) {
- return rootTheme.value();
- } else {
- return null;
- }
- }
-
- /**
- * Finds the widgetset to use for a specific root. If no specific widgetset
- * is required, <code>null</code> is returned.
- *
- * TODO Tell what the default implementation does once it does something.
- *
- * @param root
- * the root to get a widgetset for
- * @return the name of the widgetset, or <code>null</code> if the default
- * widgetset should be used
- *
- * @since 7.0
- */
- public String getWidgetsetForRoot(Root root) {
- Widgetset rootWidgetset = getAnnotationFor(root.getClass(),
- Widgetset.class);
- if (rootWidgetset != null) {
- return rootWidgetset.value();
- } else {
- return null;
- }
- }
-
- /**
- * Helper to get an annotation for a class. If the annotation is not present
- * on the target class, it's superclasses and implemented interfaces are
- * also searched for the annotation.
- *
- * @param type
- * the target class from which the annotation should be found
- * @param annotationType
- * the annotation type to look for
- * @return an annotation of the given type, or <code>null</code> if the
- * annotation is not present on the class
- */
- private static <T extends Annotation> T getAnnotationFor(Class<?> type,
- Class<T> annotationType) {
- // Find from the class hierarchy
- Class<?> currentType = type;
- while (currentType != Object.class) {
- T annotation = currentType.getAnnotation(annotationType);
- if (annotation != null) {
- return annotation;
- } else {
- currentType = currentType.getSuperclass();
- }
- }
-
- // Find from an implemented interface
- for (Class<?> iface : type.getInterfaces()) {
- T annotation = iface.getAnnotation(annotationType);
- if (annotation != null) {
- return annotation;
- }
- }
-
- return null;
- }
-
- /**
- * Handles a request by passing it to each registered {@link RequestHandler}
- * in turn until one produces a response. This method is used for requests
- * that have not been handled by any specific functionality in the terminal
- * implementation (e.g. {@link AbstractApplicationServlet}).
- * <p>
- * The request handlers are invoked in the revere order in which they were
- * added to the application until a response has been produced. This means
- * that the most recently added handler is used first and the first request
- * handler that was added to the application is invoked towards the end
- * unless any previous handler has already produced a response.
- * </p>
- *
- * @param request
- * the wrapped request to get information from
- * @param response
- * the response to which data can be written
- * @return returns <code>true</code> if a {@link RequestHandler} has
- * produced a response and <code>false</code> if no response has
- * been written.
- * @throws IOException
- *
- * @see #addRequestHandler(RequestHandler)
- * @see RequestHandler
- *
- * @since 7.0
- */
- public boolean handleRequest(WrappedRequest request,
- WrappedResponse response) throws IOException {
- // Use a copy to avoid ConcurrentModificationException
- for (RequestHandler handler : new ArrayList<RequestHandler>(
- requestHandlers)) {
- if (handler.handleRequest(this, request, response)) {
- return true;
- }
- }
- // If not handled
- return false;
- }
-
- /**
- * Adds a request handler to this application. Request handlers can be added
- * to provide responses to requests that are not handled by the default
- * functionality of the framework.
- * <p>
- * Handlers are called in reverse order of addition, so the most recently
- * added handler will be called first.
- * </p>
- *
- * @param handler
- * the request handler to add
- *
- * @see #handleRequest(WrappedRequest, WrappedResponse)
- * @see #removeRequestHandler(RequestHandler)
- *
- * @since 7.0
- */
- public void addRequestHandler(RequestHandler handler) {
- requestHandlers.addFirst(handler);
- }
-
- /**
- * Removes a request handler from the application.
- *
- * @param handler
- * the request handler to remove
- *
- * @since 7.0
- */
- public void removeRequestHandler(RequestHandler handler) {
- requestHandlers.remove(handler);
- }
-
- /**
- * Gets the request handlers that are registered to the application. The
- * iteration order of the returned collection is the same as the order in
- * which the request handlers will be invoked when a request is handled.
- *
- * @return a collection of request handlers, with the iteration order
- * according to the order they would be invoked
- *
- * @see #handleRequest(WrappedRequest, WrappedResponse)
- * @see #addRequestHandler(RequestHandler)
- * @see #removeRequestHandler(RequestHandler)
- *
- * @since 7.0
- */
- public Collection<RequestHandler> getRequestHandlers() {
- return Collections.unmodifiableCollection(requestHandlers);
- }
-
- /**
- * Find an application resource with a given key.
- *
- * @param key
- * The key of the resource
- * @return The application resource corresponding to the provided key, or
- * <code>null</code> if no resource is registered for the key
- *
- * @since 7.0
- */
- public ApplicationResource getResource(String key) {
- return keyResourceMap.get(key);
- }
-
- /**
- * Thread local for keeping track of currently used application instance
- *
- * @since 7.0
- */
- private static final ThreadLocal<Application> currentApplication = new ThreadLocal<Application>();
-
- private boolean rootPreserved = false;
-
- /**
- * Gets the currently used application. The current application is
- * automatically defined when processing requests to the server. In other
- * cases, (e.g. from background threads), the current application is not
- * automatically defined.
- *
- * @return the current application instance if available, otherwise
- * <code>null</code>
- *
- * @see #setCurrent(Application)
- *
- * @since 7.0
- */
- public static Application getCurrent() {
- return currentApplication.get();
- }
-
- /**
- * Sets the thread local for the current application. This method is used by
- * the framework to set the current application whenever a new request is
- * processed and it is cleared when the request has been processed.
- * <p>
- * The application developer can also use this method to define the current
- * application outside the normal request handling, e.g. when initiating
- * custom background threads.
- * </p>
- *
- * @param application
- *
- * @see #getCurrent()
- * @see ThreadLocal
- *
- * @since 7.0
- */
- public static void setCurrent(Application application) {
- currentApplication.set(application);
- }
-
- /**
- * Check whether this application is in production mode. If an application
- * is in production mode, certain debugging facilities are not available.
- *
- * @return the status of the production mode flag
- *
- * @since 7.0
- */
- public boolean isProductionMode() {
- return productionMode;
- }
-
- /**
- * Finds the {@link Root} to which a particular request belongs. If the
- * request originates from an existing Root, that root is returned. In other
- * cases, the method attempts to create and initialize a new root and might
- * throw a {@link RootRequiresMoreInformationException} if all required
- * information is not available.
- * <p>
- * Please note that this method can also return a newly created
- * <code>Root</code> which has not yet been initialized. You can use
- * {@link #isRootInitPending(int)} with the root's id (
- * {@link Root#getRootId()} to check whether the initialization is still
- * pending.
- * </p>
- *
- * @param request
- * the request for which a root is desired
- * @return a root belonging to the request
- * @throws RootRequiresMoreInformationException
- * if no existing root could be found and creating a new root
- * requires additional information from the browser
- *
- * @see #getRoot(WrappedRequest)
- * @see RootRequiresMoreInformationException
- *
- * @since 7.0
- */
- public Root getRootForRequest(WrappedRequest request)
- throws RootRequiresMoreInformationException {
- Root root = Root.getCurrent();
- if (root != null) {
- return root;
- }
- Integer rootId = getRootId(request);
-
- synchronized (this) {
- BrowserDetails browserDetails = request.getBrowserDetails();
- boolean hasBrowserDetails = browserDetails != null
- && browserDetails.getUriFragment() != null;
-
- root = roots.get(rootId);
-
- if (root == null && isRootPreserved()) {
- // Check for a known root
- if (!retainOnRefreshRoots.isEmpty()) {
-
- Integer retainedRootId;
- if (!hasBrowserDetails) {
- throw new RootRequiresMoreInformationException();
- } else {
- String windowName = browserDetails.getWindowName();
- retainedRootId = retainOnRefreshRoots.get(windowName);
- }
-
- if (retainedRootId != null) {
- rootId = retainedRootId;
- root = roots.get(rootId);
- }
- }
- }
-
- if (root == null) {
- // Throws exception if root can not yet be created
- root = getRoot(request);
-
- // Initialize some fields for a newly created root
- if (root.getApplication() == null) {
- root.setApplication(this);
- }
- if (root.getRootId() < 0) {
-
- if (rootId == null) {
- // Get the next id if none defined
- rootId = Integer.valueOf(nextRootId++);
- }
- root.setRootId(rootId.intValue());
- roots.put(rootId, root);
- }
- }
-
- // Set thread local here so it is available in init
- Root.setCurrent(root);
-
- if (!initedRoots.contains(rootId)) {
- boolean initRequiresBrowserDetails = isRootPreserved()
- || !root.getClass()
- .isAnnotationPresent(EagerInit.class);
- if (!initRequiresBrowserDetails || hasBrowserDetails) {
- root.doInit(request);
-
- // Remember that this root has been initialized
- initedRoots.add(rootId);
-
- // init() might turn on preserve so do this afterwards
- if (isRootPreserved()) {
- // Remember this root
- String windowName = request.getBrowserDetails()
- .getWindowName();
- retainOnRefreshRoots.put(windowName, rootId);
- }
- }
- }
- } // end synchronized block
-
- return root;
- }
-
- /**
- * Internal helper to finds the root id for a request.
- *
- * @param request
- * the request to get the root id for
- * @return a root id, or <code>null</code> if no root id is defined
- *
- * @since 7.0
- */
- private static Integer getRootId(WrappedRequest request) {
- if (request instanceof CombinedRequest) {
- // Combined requests has the rootid parameter in the second request
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- String rootIdString = request
- .getParameter(ApplicationConnection.ROOT_ID_PARAMETER);
- Integer rootId = rootIdString == null ? null
- : new Integer(rootIdString);
- return rootId;
- }
-
- /**
- * Sets whether the same Root state should be reused if the framework can
- * detect that the application is opened in a browser window where it has
- * previously been open. The framework attempts to discover this by checking
- * the value of window.name in the browser.
- * <p>
- * NOTE that you should avoid turning this feature on/off on-the-fly when
- * the UI is already shown, as it might not be retained as intended.
- * </p>
- *
- * @param rootPreserved
- * <code>true</code>if the same Root instance should be reused
- * e.g. when the browser window is refreshed.
- */
- public void setRootPreserved(boolean rootPreserved) {
- this.rootPreserved = rootPreserved;
- if (!rootPreserved) {
- retainOnRefreshRoots.clear();
- }
- }
-
- /**
- * Checks whether the same Root state should be reused if the framework can
- * detect that the application is opened in a browser window where it has
- * previously been open. The framework attempts to discover this by checking
- * the value of window.name in the browser.
- *
- * @return <code>true</code>if the same Root instance should be reused e.g.
- * when the browser window is refreshed.
- */
- public boolean isRootPreserved() {
- return rootPreserved;
- }
-
- /**
- * Checks whether there's a pending initialization for the root with the
- * given id.
- *
- * @param rootId
- * root id to check for
- * @return <code>true</code> of the initialization is pending,
- * <code>false</code> if the root id is not registered or if the
- * root has already been initialized
- *
- * @see #getRootForRequest(WrappedRequest)
- */
- public boolean isRootInitPending(int rootId) {
- return !initedRoots.contains(Integer.valueOf(rootId));
- }
-
- /**
- * Gets all the roots of this application. This includes roots that have
- * been requested but not yet initialized. Please note, that roots are not
- * automatically removed e.g. if the browser window is closed and that there
- * is no way to manually remove a root. Inactive roots will thus not be
- * released for GC until the entire application is released when the session
- * has timed out (unless there are dangling references). Improved support
- * for releasing unused roots is planned for an upcoming alpha release of
- * Vaadin 7.
- *
- * @return a collection of roots belonging to this application
- *
- * @since 7.0
- */
- public Collection<Root> getRoots() {
- return Collections.unmodifiableCollection(roots.values());
- }
-
- private int connectorIdSequence = 0;
-
- /**
- * Generate an id for the given Connector. Connectors must not call this
- * method more than once, the first time they need an id.
- *
- * @param connector
- * A connector that has not yet been assigned an id.
- * @return A new id for the connector
- */
- public String createConnectorId(ClientConnector connector) {
- return String.valueOf(connectorIdSequence++);
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(Application.class.getName());
- }
-
- /**
- * Returns a Root with the given id.
- * <p>
- * This is meant for framework internal use.
- * </p>
- *
- * @param rootId
- * The root id
- * @return The root with the given id or null if not found
- */
- public Root getRootById(int rootId) {
- return roots.get(rootId);
- }
-
- public void addBootstrapListener(BootstrapListener listener) {
- eventRouter.addListener(BootstrapFragmentResponse.class, listener,
- BOOTSTRAP_FRAGMENT_METHOD);
- eventRouter.addListener(BootstrapPageResponse.class, listener,
- BOOTSTRAP_PAGE_METHOD);
- }
-
- public void removeBootstrapListener(BootstrapListener listener) {
- eventRouter.removeListener(BootstrapFragmentResponse.class, listener,
- BOOTSTRAP_FRAGMENT_METHOD);
- eventRouter.removeListener(BootstrapPageResponse.class, listener,
- BOOTSTRAP_PAGE_METHOD);
- }
-
- public void modifyBootstrapResponse(BootstrapResponse response) {
- eventRouter.fireEvent(response);
- }
-}
diff --git a/src/com/vaadin/RootRequiresMoreInformationException.java b/src/com/vaadin/RootRequiresMoreInformationException.java
deleted file mode 100644
index ed0fa41437..0000000000
--- a/src/com/vaadin/RootRequiresMoreInformationException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin;
-
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedRequest.BrowserDetails;
-
-/**
- * Exception that is thrown to indicate that creating or initializing the root
- * requires information detailed from the web browser ({@link BrowserDetails})
- * to be present.
- *
- * This exception may not be thrown if that information is already present in
- * the current WrappedRequest.
- *
- * @see Application#getRoot(WrappedRequest)
- * @see WrappedRequest#getBrowserDetails()
- *
- * @since 7.0
- */
-public class RootRequiresMoreInformationException extends Exception {
- // Nothing of interest here
-}
diff --git a/src/com/vaadin/Vaadin.gwt.xml b/src/com/vaadin/Vaadin.gwt.xml
deleted file mode 100644
index 07d7c941e6..0000000000
--- a/src/com/vaadin/Vaadin.gwt.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<module>
- <!-- This GWT module inherits all Vaadin client side functionality modules.
- This is the module you want to inherit in your client side project to be
- able to use com.vaadin.* classes. -->
-
- <!-- Hint for WidgetSetBuilder not to automatically update the file -->
- <!-- WS Compiler: manually edited -->
-
- <inherits name="com.google.gwt.user.User" />
-
- <inherits name="com.google.gwt.http.HTTP" />
-
- <inherits name="com.google.gwt.json.JSON" />
-
- <inherits name="com.vaadin.terminal.gwt.VaadinBrowserSpecificOverrides" />
-
- <source path="terminal/gwt/client" />
- <source path="shared" />
-
- <!-- Use own Scheduler implementation to be able to track if commands are
- running -->
- <replace-with class="com.vaadin.terminal.gwt.client.VSchedulerImpl">
- <when-type-is class="com.google.gwt.core.client.impl.SchedulerImpl" />
- </replace-with>
-
- <!-- Generators for serializators for classes used in communication between
- server and client -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.SerializerMapGenerator">
- <when-type-is
- class="com.vaadin.terminal.gwt.client.communication.SerializerMap" />
- </generate-with>
-
- <replace-with class="com.vaadin.terminal.gwt.client.VDebugConsole">
- <when-type-is class="com.vaadin.terminal.gwt.client.Console" />
- </replace-with>
-
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.EagerWidgetMapGenerator">
- <when-type-is class="com.vaadin.terminal.gwt.client.WidgetMap" />
- </generate-with>
-
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.AcceptCriteriaFactoryGenerator">
- <when-type-is
- class="com.vaadin.terminal.gwt.client.ui.dd.VAcceptCriterionFactory" />
- </generate-with>
-
- <!-- Generate client side proxies for client to server RPC interfaces -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.RpcProxyGenerator">
- <when-type-assignable
- class="com.vaadin.shared.communication.ServerRpc" />
- </generate-with>
-
- <!-- Generate client side proxies for client to server RPC interfaces -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.RpcProxyCreatorGenerator">
- <when-type-assignable
- class="com.vaadin.terminal.gwt.client.communication.RpcProxy.RpcProxyCreator" />
- </generate-with>
-
- <!-- Generate client side RPC manager for server to client RPC -->
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.GeneratedRpcMethodProviderGenerator">
- <when-type-assignable
- class="com.vaadin.terminal.gwt.client.communication.GeneratedRpcMethodProvider" />
- </generate-with>
-
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorWidgetFactoryGenerator">
- <when-type-assignable
- class="com.vaadin.terminal.gwt.client.ui.ConnectorWidgetFactory" />
- </generate-with>
-
- <generate-with
- class="com.vaadin.terminal.gwt.widgetsetutils.ConnectorStateFactoryGenerator">
- <when-type-assignable
- class="com.vaadin.terminal.gwt.client.ui.ConnectorStateFactory" />
- </generate-with>
-
- <!-- Use the new cross site linker to get a nocache.js without document.write -->
- <add-linker name="xsiframe" />
-
-</module>
diff --git a/src/com/vaadin/Version.java b/src/com/vaadin/Version.java
deleted file mode 100644
index eb6d73e7e0..0000000000
--- a/src/com/vaadin/Version.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin;
-
-import java.io.Serializable;
-
-public class Version implements Serializable {
- /**
- * The version number of this release. For example "6.2.0". Always in the
- * format "major.minor.revision[.build]". The build part is optional. All of
- * major, minor, revision must be integers.
- */
- private static final String VERSION;
- /**
- * Major version number. For example 6 in 6.2.0.
- */
- private static final int VERSION_MAJOR;
-
- /**
- * Minor version number. For example 2 in 6.2.0.
- */
- private static final int VERSION_MINOR;
-
- /**
- * Version revision number. For example 0 in 6.2.0.
- */
- private static final int VERSION_REVISION;
-
- /**
- * Build identifier. For example "nightly-20091123-c9963" in
- * 6.2.0.nightly-20091123-c9963.
- */
- private static final String VERSION_BUILD;
-
- /* Initialize version numbers from string replaced by build-script. */
- static {
- if ("@VERSION@".equals("@" + "VERSION" + "@")) {
- VERSION = "9.9.9.INTERNAL-DEBUG-BUILD";
- } else {
- VERSION = "@VERSION@";
- }
- final String[] digits = VERSION.split("\\.", 4);
- VERSION_MAJOR = Integer.parseInt(digits[0]);
- VERSION_MINOR = Integer.parseInt(digits[1]);
- VERSION_REVISION = Integer.parseInt(digits[2]);
- if (digits.length == 4) {
- VERSION_BUILD = digits[3];
- } else {
- VERSION_BUILD = "";
- }
- }
-
- public static String getFullVersion() {
- return VERSION;
- }
-
- public static int getMajorVersion() {
- return VERSION_MAJOR;
- }
-
- public static int getMinorVersion() {
- return VERSION_MINOR;
- }
-
- public static int getRevision() {
- return VERSION_REVISION;
- }
-
- public static String getBuildIdentifier() {
- return VERSION_BUILD;
- }
-
-}
diff --git a/src/com/vaadin/annotations/AutoGenerated.java b/src/com/vaadin/annotations/AutoGenerated.java
deleted file mode 100644
index 72c9b62a91..0000000000
--- a/src/com/vaadin/annotations/AutoGenerated.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.annotations;
-
-/**
- * Marker annotation for automatically generated code elements.
- *
- * These elements may be modified or removed by code generation.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.0
- */
-public @interface AutoGenerated {
-
-}
diff --git a/src/com/vaadin/annotations/EagerInit.java b/src/com/vaadin/annotations/EagerInit.java
deleted file mode 100644
index c7c2702d2a..0000000000
--- a/src/com/vaadin/annotations/EagerInit.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.ui.Root;
-
-/**
- * Indicates that the init method in a Root class can be called before full
- * browser details ({@link WrappedRequest#getBrowserDetails()}) are available.
- * This will make the UI appear more quickly, as ensuring the availability of
- * this information typically requires an additional round trip to the client.
- *
- * @see Root#init(com.vaadin.terminal.WrappedRequest)
- * @see WrappedRequest#getBrowserDetails()
- *
- * @since 7.0
- *
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface EagerInit {
- // No values
-}
diff --git a/src/com/vaadin/annotations/JavaScript.java b/src/com/vaadin/annotations/JavaScript.java
deleted file mode 100644
index 357bcc3649..0000000000
--- a/src/com/vaadin/annotations/JavaScript.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * If this annotation is present on a {@link ClientConnector} class, the
- * framework ensures the referenced JavaScript files are loaded before the init
- * method for the corresponding client-side connector is invoked.
- * <p>
- * Absolute URLs including protocol and host are used as is on the client-side.
- * Relative urls are mapped to APP/CONNECTOR/[url] which are by default served
- * from the classpath relative to the class where the annotation is defined.
- * <p>
- * Example: {@code @JavaScript( "http://host.com/file1.js", "file2.js"})} on the
- * class com.example.MyConnector would load the file http://host.com/file1.js as
- * is and file2.js from /com/example/file2.js on the server's classpath using
- * the ClassLoader that was used to load com.example.MyConnector.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface JavaScript {
- /**
- * JavaScript files to load before initializing the client-side connector.
- *
- * @return an array of JavaScript file urls
- */
- public String[] value();
-}
diff --git a/src/com/vaadin/annotations/StyleSheet.java b/src/com/vaadin/annotations/StyleSheet.java
deleted file mode 100644
index d082cb8d30..0000000000
--- a/src/com/vaadin/annotations/StyleSheet.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * If this annotation is present on a {@link ClientConnector} class, the
- * framework ensures the referenced style sheets are loaded before the init
- * method for the corresponding client-side connector is invoked.
- * <p>
- * Example: {@code @StyleSheet( "http://host.com/file1.css", "file2.css"})} on
- * the class com.example.MyConnector would load the file
- * http://host.com/file1.css as is and file2.css from /com/example/file2.css on
- * the server's classpath using the ClassLoader that was used to load
- * com.example.MyConnector.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface StyleSheet {
- /**
- * Style sheets to load before initializing the client-side connector.
- *
- * @return an array of style sheet urls
- */
- public String[] value();
-}
diff --git a/src/com/vaadin/annotations/Theme.java b/src/com/vaadin/annotations/Theme.java
deleted file mode 100644
index 7c62b07741..0000000000
--- a/src/com/vaadin/annotations/Theme.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import com.vaadin.ui.Root;
-
-/**
- * Defines a specific theme for a {@link Root}.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Theme {
- /**
- * @return simple name of the theme
- */
- public String value();
-}
diff --git a/src/com/vaadin/annotations/Widgetset.java b/src/com/vaadin/annotations/Widgetset.java
deleted file mode 100644
index 99113f73f9..0000000000
--- a/src/com/vaadin/annotations/Widgetset.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import com.vaadin.ui.Root;
-
-/**
- * Defines a specific theme for a {@link Root}.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Widgetset {
- /**
- * @return name of the widgetset
- */
- public String value();
-
-}
diff --git a/src/com/vaadin/annotations/package.html b/src/com/vaadin/annotations/package.html
deleted file mode 100644
index d789e9b5df..0000000000
--- a/src/com/vaadin/annotations/package.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-
-<p>Contains annotations used in Vaadin. Note that some annotations
-are also found in other packages e.g., {@link com.vaadin.ui.ClientWidget}.</p>
-
-</body>
-</html>
diff --git a/src/com/vaadin/data/Buffered.java b/src/com/vaadin/data/Buffered.java
deleted file mode 100644
index 1387cb965b..0000000000
--- a/src/com/vaadin/data/Buffered.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-
-import com.vaadin.data.Validator.InvalidValueException;
-
-/**
- * <p>
- * Defines the interface to commit and discard changes to an object, supporting
- * read-through and write-through modes.
- * </p>
- *
- * <p>
- * <i>Read-through mode</i> means that the value read from the buffered object
- * is constantly up to date with the data source. <i>Write-through</i> mode
- * means that all changes to the object are immediately updated to the data
- * source.
- * </p>
- *
- * <p>
- * Since these modes are independent, their combinations may result in some
- * behaviour that may sound surprising.
- * </p>
- *
- * <p>
- * For example, if a <code>Buffered</code> object is in read-through mode but
- * not in write-through mode, the result is an object whose value is updated
- * directly from the data source only if it's not locally modified. If the value
- * is locally modified, retrieving the value from the object would result in a
- * value that is different than the one stored in the data source, even though
- * the object is in read-through mode.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Buffered extends Serializable {
-
- /**
- * Updates all changes since the previous commit to the data source. The
- * value stored in the object will always be updated into the data source
- * when <code>commit</code> is called.
- *
- * @throws SourceException
- * if the operation fails because of an exception is thrown by
- * the data source. The cause is included in the exception.
- * @throws InvalidValueException
- * if the operation fails because validation is enabled and the
- * values do not validate
- */
- public void commit() throws SourceException, InvalidValueException;
-
- /**
- * Discards all changes since last commit. The object updates its value from
- * the data source.
- *
- * @throws SourceException
- * if the operation fails because of an exception is thrown by
- * the data source. The cause is included in the exception.
- */
- public void discard() throws SourceException;
-
- /**
- * Tests if the object is in write-through mode. If the object is in
- * write-through mode, all modifications to it will result in
- * <code>commit</code> being called after the modification.
- *
- * @return <code>true</code> if the object is in write-through mode,
- * <code>false</code> if it's not.
- * @deprecated Use {@link #setBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Deprecated
- public boolean isWriteThrough();
-
- /**
- * Sets the object's write-through mode to the specified status. When
- * switching the write-through mode on, the <code>commit</code> operation
- * will be performed.
- *
- * @param writeThrough
- * Boolean value to indicate if the object should be in
- * write-through mode after the call.
- * @throws SourceException
- * If the operation fails because of an exception is thrown by
- * the data source.
- * @throws InvalidValueException
- * If the implicit commit operation fails because of a
- * validation error.
- *
- * @deprecated Use {@link #setBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Deprecated
- public void setWriteThrough(boolean writeThrough) throws SourceException,
- InvalidValueException;
-
- /**
- * Tests if the object is in read-through mode. If the object is in
- * read-through mode, retrieving its value will result in the value being
- * first updated from the data source to the object.
- * <p>
- * The only exception to this rule is that when the object is not in
- * write-through mode and it's buffer contains a modified value, the value
- * retrieved from the object will be the locally modified value in the
- * buffer which may differ from the value in the data source.
- * </p>
- *
- * @return <code>true</code> if the object is in read-through mode,
- * <code>false</code> if it's not.
- * @deprecated Use {@link #isBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Deprecated
- public boolean isReadThrough();
-
- /**
- * Sets the object's read-through mode to the specified status. When
- * switching read-through mode on, the object's value is updated from the
- * data source.
- *
- * @param readThrough
- * Boolean value to indicate if the object should be in
- * read-through mode after the call.
- *
- * @throws SourceException
- * If the operation fails because of an exception is thrown by
- * the data source. The cause is included in the exception.
- * @deprecated Use {@link #setBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Deprecated
- public void setReadThrough(boolean readThrough) throws SourceException;
-
- /**
- * Sets the object's buffered mode to the specified status.
- * <p>
- * When the object is in buffered mode, an internal buffer will be used to
- * store changes until {@link #commit()} is called. Calling
- * {@link #discard()} will revert the internal buffer to the value of the
- * data source.
- * </p>
- * <p>
- * This is an easier way to use {@link #setReadThrough(boolean)} and
- * {@link #setWriteThrough(boolean)} and not as error prone. Changing
- * buffered mode will change both the read through and write through state
- * of the object.
- * </p>
- * <p>
- * Mixing calls to {@link #setBuffered(boolean)}/{@link #isBuffered()} and
- * {@link #setReadThrough(boolean)}/{@link #isReadThrough()} or
- * {@link #setWriteThrough(boolean)}/{@link #isWriteThrough()} is generally
- * a bad idea.
- * </p>
- *
- * @param buffered
- * true if buffered mode should be turned on, false otherwise
- * @since 7.0
- */
- public void setBuffered(boolean buffered);
-
- /**
- * Checks the buffered mode of this Object.
- * <p>
- * This method only returns true if both read and write buffering is used.
- * </p>
- *
- * @return true if buffered mode is on, false otherwise
- * @since 7.0
- */
- public boolean isBuffered();
-
- /**
- * Tests if the value stored in the object has been modified since it was
- * last updated from the data source.
- *
- * @return <code>true</code> if the value in the object has been modified
- * since the last data source update, <code>false</code> if not.
- */
- public boolean isModified();
-
- /**
- * An exception that signals that one or more exceptions occurred while a
- * buffered object tried to access its data source or if there is a problem
- * in processing a data source.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public class SourceException extends RuntimeException implements
- Serializable {
-
- /** Source class implementing the buffered interface */
- private final Buffered source;
-
- /** Original cause of the source exception */
- private Throwable[] causes = {};
-
- /**
- * Creates a source exception that does not include a cause.
- *
- * @param source
- * the source object implementing the Buffered interface.
- */
- public SourceException(Buffered source) {
- this.source = source;
- }
-
- /**
- * Creates a source exception from a cause exception.
- *
- * @param source
- * the source object implementing the Buffered interface.
- * @param cause
- * the original cause for this exception.
- */
- public SourceException(Buffered source, Throwable cause) {
- this.source = source;
- causes = new Throwable[] { cause };
- }
-
- /**
- * Creates a source exception from multiple causes.
- *
- * @param source
- * the source object implementing the Buffered interface.
- * @param causes
- * the original causes for this exception.
- */
- public SourceException(Buffered source, Throwable[] causes) {
- this.source = source;
- this.causes = causes;
- }
-
- /**
- * Gets the cause of the exception.
- *
- * @return The (first) cause for the exception, null if no cause.
- */
- @Override
- public final Throwable getCause() {
- if (causes.length == 0) {
- return null;
- }
- return causes[0];
- }
-
- /**
- * Gets all the causes for this exception.
- *
- * @return throwables that caused this exception
- */
- public final Throwable[] getCauses() {
- return causes;
- }
-
- /**
- * Gets a source of the exception.
- *
- * @return the Buffered object which generated this exception.
- */
- public Buffered getSource() {
- return source;
- }
-
- }
-}
diff --git a/src/com/vaadin/data/BufferedValidatable.java b/src/com/vaadin/data/BufferedValidatable.java
deleted file mode 100644
index ce1d44fce6..0000000000
--- a/src/com/vaadin/data/BufferedValidatable.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-
-/**
- * <p>
- * This interface defines the combination of <code>Validatable</code> and
- * <code>Buffered</code> interfaces. The combination of the interfaces defines
- * if the invalid data is committed to datasource.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface BufferedValidatable extends Buffered, Validatable,
- Serializable {
-
- /**
- * Tests if the invalid data is committed to datasource. The default is
- * <code>false</code>.
- */
- public boolean isInvalidCommitted();
-
- /**
- * Sets if the invalid data should be committed to datasource. The default
- * is <code>false</code>.
- */
- public void setInvalidCommitted(boolean isCommitted);
-}
diff --git a/src/com/vaadin/data/Collapsible.java b/src/com/vaadin/data/Collapsible.java
deleted file mode 100644
index 06c96b7ea7..0000000000
--- a/src/com/vaadin/data/Collapsible.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data;
-
-import com.vaadin.data.Container.Hierarchical;
-import com.vaadin.data.Container.Ordered;
-
-/**
- * Container needed by large lazy loading hierarchies displayed e.g. in
- * TreeTable.
- * <p>
- * Container of this type gets notified when a subtree is opened/closed in a
- * component displaying its content. This allows container to lazy load subtrees
- * and release memory when a sub-tree is no longer displayed.
- * <p>
- * Methods from {@link Container.Ordered} (and from {@linkContainer.Indexed} if
- * implemented) are expected to work as in "preorder" of the currently visible
- * hierarchy. This means for example that the return value of size method
- * changes when subtree is collapsed/expanded. In other words items in collapsed
- * sub trees should be "ignored" by container when the container is accessed
- * with methods introduced in {@link Container.Ordered} or
- * {@linkContainer.Indexed}. From the accessors point of view, items in
- * collapsed subtrees don't exist.
- * <p>
- *
- */
-public interface Collapsible extends Hierarchical, Ordered {
-
- /**
- * <p>
- * Collapsing the {@link Item} indicated by <code>itemId</code> hides all
- * children, and their respective children, from the {@link Container}.
- * </p>
- *
- * <p>
- * If called on a leaf {@link Item}, this method does nothing.
- * </p>
- *
- * @param itemId
- * the identifier of the collapsed {@link Item}
- * @param collapsed
- * <code>true</code> if you want to collapse the children below
- * this {@link Item}. <code>false</code> if you want to
- * uncollapse the children.
- */
- public void setCollapsed(Object itemId, boolean collapsed);
-
- /**
- * <p>
- * Checks whether the {@link Item}, identified by <code>itemId</code> is
- * collapsed or not.
- * </p>
- *
- * <p>
- * If an {@link Item} is "collapsed" its children are not included in
- * methods used to list Items in this container.
- * </p>
- *
- * @param itemId
- * The {@link Item}'s identifier that is to be checked.
- * @return <code>true</code> iff the {@link Item} identified by
- * <code>itemId</code> is currently collapsed, otherwise
- * <code>false</code>.
- */
- public boolean isCollapsed(Object itemId);
-
-}
diff --git a/src/com/vaadin/data/Container.java b/src/com/vaadin/data/Container.java
deleted file mode 100644
index f4c0ed9794..0000000000
--- a/src/com/vaadin/data/Container.java
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.data.util.filter.UnsupportedFilterException;
-
-/**
- * <p>
- * A specialized set of identified Items. Basically the Container is a set of
- * {@link Item}s, but it imposes certain constraints on its contents. These
- * constraints state the following:
- * </p>
- *
- * <ul>
- * <li>All Items in the Container must have the same number of Properties.
- * <li>All Items in the Container must have the same Property ID's (see
- * {@link Item#getItemPropertyIds()}).
- * <li>All Properties in the Items corresponding to the same Property ID must
- * have the same data type.
- * <li>All Items within a container are uniquely identified by their non-null
- * IDs.
- * </ul>
- *
- * <p>
- * The Container can be visualized as a representation of a relational database
- * table. Each Item in the Container represents a row in the table, and all
- * cells in a column (identified by a Property ID) have the same data type. Note
- * that as with the cells in a database table, no Property in a Container may be
- * empty, though they may contain <code>null</code> values.
- * </p>
- *
- * <p>
- * Note that though uniquely identified, the Items in a Container are not
- * necessarily {@link Container.Ordered ordered} or {@link Container.Indexed
- * indexed}.
- * </p>
- *
- * <p>
- * Containers can derive Item ID's from the item properties or use other,
- * container specific or user specified identifiers.
- * </p>
- *
- * <p>
- * If a container is {@link Filterable filtered} or {@link Sortable sorted},
- * most of the the methods of the container interface and its subinterfaces
- * (container size, {@link #containsId(Object)}, iteration and indices etc.)
- * relate to the filtered and sorted view, not to the full container contents.
- * See individual method javadoc for exceptions to this (adding and removing
- * items).
- * </p>
- *
- * <p>
- * <img src=doc-files/Container_full.gif>
- * </p>
- *
- * <p>
- * The Container interface is split to several subinterfaces so that a class can
- * implement only the ones it needs.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Container extends Serializable {
-
- /**
- * Gets the {@link Item} with the given Item ID from the Container. If the
- * Container does not contain the requested Item, <code>null</code> is
- * returned.
- *
- * Containers should not return Items that are filtered out.
- *
- * @param itemId
- * ID of the {@link Item} to retrieve
- * @return the {@link Item} with the given ID or <code>null</code> if the
- * Item is not found in the Container
- */
- public Item getItem(Object itemId);
-
- /**
- * Gets the ID's of all Properties stored in the Container. The ID's cannot
- * be modified through the returned collection.
- *
- * @return unmodifiable collection of Property IDs
- */
- public Collection<?> getContainerPropertyIds();
-
- /**
- * Gets the ID's of all visible (after filtering and sorting) Items stored
- * in the Container. The ID's cannot be modified through the returned
- * collection.
- *
- * If the container is {@link Ordered}, the collection returned by this
- * method should follow that order. If the container is {@link Sortable},
- * the items should be in the sorted order.
- *
- * Calling this method for large lazy containers can be an expensive
- * operation and should be avoided when practical.
- *
- * @return unmodifiable collection of Item IDs
- */
- public Collection<?> getItemIds();
-
- /**
- * Gets the Property identified by the given itemId and propertyId from the
- * Container. If the Container does not contain the item or it is filtered
- * out, or the Container does not have the Property, <code>null</code> is
- * returned.
- *
- * @param itemId
- * ID of the visible Item which contains the Property
- * @param propertyId
- * ID of the Property to retrieve
- * @return Property with the given ID or <code>null</code>
- */
- public Property<?> getContainerProperty(Object itemId, Object propertyId);
-
- /**
- * Gets the data type of all Properties identified by the given Property ID.
- *
- * @param propertyId
- * ID identifying the Properties
- * @return data type of the Properties
- */
- public Class<?> getType(Object propertyId);
-
- /**
- * Gets the number of visible Items in the Container.
- *
- * Filtering can hide items so that they will not be visible through the
- * container API.
- *
- * @return number of Items in the Container
- */
- public int size();
-
- /**
- * Tests if the Container contains the specified Item.
- *
- * Filtering can hide items so that they will not be visible through the
- * container API, and this method should respect visibility of items (i.e.
- * only indicate visible items as being in the container) if feasible for
- * the container.
- *
- * @param itemId
- * ID the of Item to be tested
- * @return boolean indicating if the Container holds the specified Item
- */
- public boolean containsId(Object itemId);
-
- /**
- * Creates a new Item with the given ID in the Container.
- *
- * <p>
- * The new Item is returned, and it is ready to have its Properties
- * modified. Returns <code>null</code> if the operation fails or the
- * Container already contains a Item with the given ID.
- * </p>
- *
- * <p>
- * This functionality is optional.
- * </p>
- *
- * @param itemId
- * ID of the Item to be created
- * @return Created new Item, or <code>null</code> in case of a failure
- * @throws UnsupportedOperationException
- * if adding an item with an explicit item ID is not supported
- * by the container
- */
- public Item addItem(Object itemId) throws UnsupportedOperationException;
-
- /**
- * Creates a new Item into the Container, and assign it an automatic ID.
- *
- * <p>
- * The new ID is returned, or <code>null</code> if the operation fails.
- * After a successful call you can use the {@link #getItem(Object ItemId)
- * <code>getItem</code>}method to fetch the Item.
- * </p>
- *
- * <p>
- * This functionality is optional.
- * </p>
- *
- * @return ID of the newly created Item, or <code>null</code> in case of a
- * failure
- * @throws UnsupportedOperationException
- * if adding an item without an explicit item ID is not
- * supported by the container
- */
- public Object addItem() throws UnsupportedOperationException;
-
- /**
- * Removes the Item identified by <code>ItemId</code> from the Container.
- *
- * <p>
- * Containers that support filtering should also allow removing an item that
- * is currently filtered out.
- * </p>
- *
- * <p>
- * This functionality is optional.
- * </p>
- *
- * @param itemId
- * ID of the Item to remove
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the container does not support removing individual items
- */
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException;
-
- /**
- * Adds a new Property to all Items in the Container. The Property ID, data
- * type and default value of the new Property are given as parameters.
- *
- * This functionality is optional.
- *
- * @param propertyId
- * ID of the Property
- * @param type
- * Data type of the new Property
- * @param defaultValue
- * The value all created Properties are initialized to
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the container does not support explicitly adding container
- * properties
- */
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException;
-
- /**
- * Removes a Property specified by the given Property ID from the Container.
- * Note that the Property will be removed from all Items in the Container.
- *
- * This functionality is optional.
- *
- * @param propertyId
- * ID of the Property to remove
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the container does not support removing container
- * properties
- */
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException;
-
- /**
- * Removes all Items from the Container.
- *
- * <p>
- * Note that Property ID and type information is preserved. This
- * functionality is optional.
- * </p>
- *
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the container does not support removing all items
- */
- public boolean removeAllItems() throws UnsupportedOperationException;
-
- /**
- * Interface for Container classes whose {@link Item}s can be traversed in
- * order.
- *
- * <p>
- * If the container is filtered or sorted, the traversal applies to the
- * filtered and sorted view.
- * </p>
- * <p>
- * The <code>addItemAfter()</code> methods should apply filters to the added
- * item after inserting it, possibly hiding it immediately. If the container
- * is being sorted, they may add items at the correct sorted position
- * instead of the given position. See also {@link Filterable} and
- * {@link Sortable} for more information.
- * </p>
- */
- public interface Ordered extends Container {
-
- /**
- * Gets the ID of the Item following the Item that corresponds to
- * <code>itemId</code>. If the given Item is the last or not found in
- * the Container, <code>null</code> is returned.
- *
- * @param itemId
- * ID of a visible Item in the Container
- * @return ID of the next visible Item or <code>null</code>
- */
- public Object nextItemId(Object itemId);
-
- /**
- * Gets the ID of the Item preceding the Item that corresponds to
- * <code>itemId</code>. If the given Item is the first or not found in
- * the Container, <code>null</code> is returned.
- *
- * @param itemId
- * ID of a visible Item in the Container
- * @return ID of the previous visible Item or <code>null</code>
- */
- public Object prevItemId(Object itemId);
-
- /**
- * Gets the ID of the first Item in the Container.
- *
- * @return ID of the first visible Item in the Container
- */
- public Object firstItemId();
-
- /**
- * Gets the ID of the last Item in the Container..
- *
- * @return ID of the last visible Item in the Container
- */
- public Object lastItemId();
-
- /**
- * Tests if the Item corresponding to the given Item ID is the first
- * Item in the Container.
- *
- * @param itemId
- * ID of an Item in the Container
- * @return <code>true</code> if the Item is first visible item in the
- * Container, <code>false</code> if not
- */
- public boolean isFirstId(Object itemId);
-
- /**
- * Tests if the Item corresponding to the given Item ID is the last Item
- * in the Container.
- *
- * @return <code>true</code> if the Item is last visible item in the
- * Container, <code>false</code> if not
- */
- public boolean isLastId(Object itemId);
-
- /**
- * Adds a new item after the given item.
- * <p>
- * Adding an item after null item adds the item as first item of the
- * ordered container.
- * </p>
- *
- * @see Ordered Ordered: adding items in filtered or sorted containers
- *
- * @param previousItemId
- * Id of the visible item in ordered container after which to
- * insert the new item.
- * @return item id the the created new item or null if the operation
- * fails.
- * @throws UnsupportedOperationException
- * if the operation is not supported by the container
- */
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException;
-
- /**
- * Adds a new item after the given item.
- * <p>
- * Adding an item after null item adds the item as first item of the
- * ordered container.
- * </p>
- *
- * @see Ordered Ordered: adding items in filtered or sorted containers
- *
- * @param previousItemId
- * Id of the visible item in ordered container after which to
- * insert the new item.
- * @param newItemId
- * Id of the new item to be added.
- * @return new item or null if the operation fails.
- * @throws UnsupportedOperationException
- * if the operation is not supported by the container
- */
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException;
-
- }
-
- /**
- * Interface for Container classes whose {@link Item}s can be sorted.
- * <p>
- * When an {@link Ordered} or {@link Indexed} container is sorted, all
- * relevant operations of these interfaces should only use the filtered and
- * sorted contents and the filtered indices to the container. Indices or
- * item identifiers in the public API refer to the visible view unless
- * otherwise stated. However, the <code>addItem*()</code> methods may add
- * items that will be filtered out after addition or moved to another
- * position based on sorting.
- * </p>
- * <p>
- * How sorting is performed when a {@link Hierarchical} container implements
- * {@link Sortable} is implementation specific and should be documented in
- * the implementing class. However, the recommended approach is sorting the
- * roots and the sets of children of each item separately.
- * </p>
- * <p>
- * Depending on the container type, sorting a container may permanently
- * change the internal order of items in the container.
- * </p>
- */
- public interface Sortable extends Ordered {
-
- /**
- * Sort method.
- *
- * Sorts the container items.
- *
- * Sorting a container can irreversibly change the order of its items or
- * only change the order temporarily, depending on the container.
- *
- * @param propertyId
- * Array of container property IDs, whose values are used to
- * sort the items in container as primary, secondary, ...
- * sorting criterion. All of the item IDs must be in the
- * collection returned by
- * {@link #getSortableContainerPropertyIds()}
- * @param ascending
- * Array of sorting order flags corresponding to each
- * property ID used in sorting. If this array is shorter than
- * propertyId array, ascending order is assumed for items
- * where the order is not specified. Use <code>true</code> to
- * sort in ascending order, <code>false</code> to use
- * descending order.
- */
- void sort(Object[] propertyId, boolean[] ascending);
-
- /**
- * Gets the container property IDs which can be used to sort the items.
- *
- * @return the IDs of the properties that can be used for sorting the
- * container
- */
- Collection<?> getSortableContainerPropertyIds();
-
- }
-
- /**
- * Interface for Container classes whose {@link Item}s can be accessed by
- * their position in the container.
- * <p>
- * If the container is filtered or sorted, all indices refer to the filtered
- * and sorted view. However, the <code>addItemAt()</code> methods may add
- * items that will be filtered out after addition or moved to another
- * position based on sorting.
- * </p>
- */
- public interface Indexed extends Ordered {
-
- /**
- * Gets the index of the Item corresponding to the itemId. The following
- * is <code>true</code> for the returned index: 0 <= index < size(), or
- * index = -1 if there is no visible item with that id in the container.
- *
- * @param itemId
- * ID of an Item in the Container
- * @return index of the Item, or -1 if (the filtered and sorted view of)
- * the Container does not include the Item
- */
- public int indexOfId(Object itemId);
-
- /**
- * Gets the ID of an Item by an index number.
- *
- * @param index
- * Index of the requested id in (the filtered and sorted view
- * of) the Container
- * @return ID of the Item in the given index
- */
- public Object getIdByIndex(int index);
-
- /**
- * Adds a new item at given index (in the filtered view).
- * <p>
- * The indices of the item currently in the given position and all the
- * following items are incremented.
- * </p>
- * <p>
- * This method should apply filters to the added item after inserting
- * it, possibly hiding it immediately. If the container is being sorted,
- * the item may be added at the correct sorted position instead of the
- * given position. See {@link Indexed}, {@link Ordered},
- * {@link Filterable} and {@link Sortable} for more information.
- * </p>
- *
- * @param index
- * Index (in the filtered and sorted view) to add the new
- * item.
- * @return item id of the created item or null if the operation fails.
- * @throws UnsupportedOperationException
- * if the operation is not supported by the container
- */
- public Object addItemAt(int index) throws UnsupportedOperationException;
-
- /**
- * Adds a new item at given index (in the filtered view).
- * <p>
- * The indexes of the item currently in the given position and all the
- * following items are incremented.
- * </p>
- * <p>
- * This method should apply filters to the added item after inserting
- * it, possibly hiding it immediately. If the container is being sorted,
- * the item may be added at the correct sorted position instead of the
- * given position. See {@link Indexed}, {@link Filterable} and
- * {@link Sortable} for more information.
- * </p>
- *
- * @param index
- * Index (in the filtered and sorted view) at which to add
- * the new item.
- * @param newItemId
- * Id of the new item to be added.
- * @return new {@link Item} or null if the operation fails.
- * @throws UnsupportedOperationException
- * if the operation is not supported by the container
- */
- public Item addItemAt(int index, Object newItemId)
- throws UnsupportedOperationException;
-
- }
-
- /**
- * <p>
- * Interface for <code>Container</code> classes whose Items can be arranged
- * hierarchically. This means that the Items in the container belong in a
- * tree-like structure, with the following quirks:
- * </p>
- *
- * <ul>
- * <li>The Item structure may have more than one root elements
- * <li>The Items in the hierarchy can be declared explicitly to be able or
- * unable to have children.
- * </ul>
- */
- public interface Hierarchical extends Container {
-
- /**
- * Gets the IDs of all Items that are children of the specified Item.
- * The returned collection is unmodifiable.
- *
- * @param itemId
- * ID of the Item whose children the caller is interested in
- * @return An unmodifiable {@link java.util.Collection collection}
- * containing the IDs of all other Items that are children in
- * the container hierarchy
- */
- public Collection<?> getChildren(Object itemId);
-
- /**
- * Gets the ID of the parent Item of the specified Item.
- *
- * @param itemId
- * ID of the Item whose parent the caller wishes to find out.
- * @return the ID of the parent Item. Will be <code>null</code> if the
- * specified Item is a root element.
- */
- public Object getParent(Object itemId);
-
- /**
- * Gets the IDs of all Items in the container that don't have a parent.
- * Such items are called <code>root</code> Items. The returned
- * collection is unmodifiable.
- *
- * @return An unmodifiable {@link java.util.Collection collection}
- * containing IDs of all root elements of the container
- */
- public Collection<?> rootItemIds();
-
- /**
- * <p>
- * Sets the parent of an Item. The new parent item must exist and be
- * able to have children. (
- * <code>{@link #areChildrenAllowed(Object)} == true</code> ). It is
- * also possible to detach a node from the hierarchy (and thus make it
- * root) by setting the parent <code>null</code>.
- * </p>
- *
- * <p>
- * This operation is optional.
- * </p>
- *
- * @param itemId
- * ID of the item to be set as the child of the Item
- * identified with <code>newParentId</code>
- * @param newParentId
- * ID of the Item that's to be the new parent of the Item
- * identified with <code>itemId</code>
- * @return <code>true</code> if the operation succeeded,
- * <code>false</code> if not
- */
- public boolean setParent(Object itemId, Object newParentId)
- throws UnsupportedOperationException;
-
- /**
- * Tests if the Item with given ID can have children.
- *
- * @param itemId
- * ID of the Item in the container whose child capability is
- * to be tested
- * @return <code>true</code> if the specified Item exists in the
- * Container and it can have children, <code>false</code> if
- * it's not found from the container or it can't have children.
- */
- public boolean areChildrenAllowed(Object itemId);
-
- /**
- * <p>
- * Sets the given Item's capability to have children. If the Item
- * identified with <code>itemId</code> already has children and
- * <code>{@link #areChildrenAllowed(Object)}</code> is false this method
- * fails and <code>false</code> is returned.
- * </p>
- * <p>
- * The children must be first explicitly removed with
- * {@link #setParent(Object itemId, Object newParentId)}or
- * {@link com.vaadin.data.Container#removeItem(Object itemId)}.
- * </p>
- *
- * <p>
- * This operation is optional. If it is not implemented, the method
- * always returns <code>false</code>.
- * </p>
- *
- * @param itemId
- * ID of the Item in the container whose child capability is
- * to be set
- * @param areChildrenAllowed
- * boolean value specifying if the Item can have children or
- * not
- * @return <code>true</code> if the operation succeeded,
- * <code>false</code> if not
- */
- public boolean setChildrenAllowed(Object itemId,
- boolean areChildrenAllowed)
- throws UnsupportedOperationException;
-
- /**
- * Tests if the Item specified with <code>itemId</code> is a root Item.
- * The hierarchical container can have more than one root and must have
- * at least one unless it is empty. The {@link #getParent(Object itemId)}
- * method always returns <code>null</code> for root Items.
- *
- * @param itemId
- * ID of the Item whose root status is to be tested
- * @return <code>true</code> if the specified Item is a root,
- * <code>false</code> if not
- */
- public boolean isRoot(Object itemId);
-
- /**
- * <p>
- * Tests if the Item specified with <code>itemId</code> has child Items
- * or if it is a leaf. The {@link #getChildren(Object itemId)} method
- * always returns <code>null</code> for leaf Items.
- * </p>
- *
- * <p>
- * Note that being a leaf does not imply whether or not an Item is
- * allowed to have children.
- * </p>
- * .
- *
- * @param itemId
- * ID of the Item to be tested
- * @return <code>true</code> if the specified Item has children,
- * <code>false</code> if not (is a leaf)
- */
- public boolean hasChildren(Object itemId);
-
- /**
- * <p>
- * Removes the Item identified by <code>ItemId</code> from the
- * Container.
- * </p>
- *
- * <p>
- * Note that this does not remove any children the item might have.
- * </p>
- *
- * @param itemId
- * ID of the Item to remove
- * @return <code>true</code> if the operation succeeded,
- * <code>false</code> if not
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException;
- }
-
- /**
- * Interface that is implemented by containers which allow reducing their
- * visible contents based on a set of filters. This interface has been
- * renamed from {@link Filterable}, and implementing the new
- * {@link Filterable} instead of or in addition to {@link SimpleFilterable}
- * is recommended. This interface might be removed in future Vaadin
- * versions.
- * <p>
- * When a set of filters are set, only items that match all the filters are
- * included in the visible contents of the container. Still new items that
- * do not match filters can be added to the container. Multiple filters can
- * be added and the container remembers the state of the filters. When
- * multiple filters are added, all filters must match for an item to be
- * visible in the container.
- * </p>
- * <p>
- * When an {@link Ordered} or {@link Indexed} container is filtered, all
- * operations of these interfaces should only use the filtered contents and
- * the filtered indices to the container.
- * </p>
- * <p>
- * How filtering is performed when a {@link Hierarchical} container
- * implements {@link SimpleFilterable} is implementation specific and should
- * be documented in the implementing class.
- * </p>
- * <p>
- * Adding items (if supported) to a filtered {@link Ordered} or
- * {@link Indexed} container should insert them immediately after the
- * indicated visible item. The unfiltered position of items added at index
- * 0, at index {@link com.vaadin.data.Container#size()} or at an undefined
- * position is up to the implementation.
- * </p>
- * <p>
- * The functionality of SimpleFilterable can be implemented using the
- * {@link Filterable} API and {@link SimpleStringFilter}.
- * </p>
- *
- * @since 5.0 (renamed from Filterable to SimpleFilterable in 6.6)
- */
- public interface SimpleFilterable extends Container, Serializable {
-
- /**
- * Add a filter for given property.
- *
- * The API {@link Filterable#addContainerFilter(Filter)} is recommended
- * instead of this method. A {@link SimpleStringFilter} can be used with
- * the new API to implement the old string filtering functionality.
- *
- * The filter accepts items for which toString() of the value of the
- * given property contains or starts with given filterString. Other
- * items are not visible in the container when filtered.
- *
- * If a container has multiple filters, only items accepted by all
- * filters are visible.
- *
- * @param propertyId
- * Property for which the filter is applied to.
- * @param filterString
- * String that must match the value of the property
- * @param ignoreCase
- * Determine if the casing can be ignored when comparing
- * strings.
- * @param onlyMatchPrefix
- * Only match prefixes; no other matches are included.
- */
- public void addContainerFilter(Object propertyId, String filterString,
- boolean ignoreCase, boolean onlyMatchPrefix);
-
- /**
- * Remove all filters from all properties.
- */
- public void removeAllContainerFilters();
-
- /**
- * Remove all filters from the given property.
- *
- * @param propertyId
- * for which to remove filters
- */
- public void removeContainerFilters(Object propertyId);
- }
-
- /**
- * Filter interface for container filtering.
- *
- * If a filter does not support in-memory filtering,
- * {@link #passesFilter(Item)} should throw
- * {@link UnsupportedOperationException}.
- *
- * Lazy containers must be able to map filters to their internal
- * representation (e.g. SQL or JPA 2.0 Criteria).
- *
- * An {@link UnsupportedFilterException} can be thrown by the container if a
- * particular filter is not supported by the container.
- *
- * An {@link Filter} should implement {@link #equals(Object)} and
- * {@link #hashCode()} correctly to avoid duplicate filter registrations
- * etc.
- *
- * @see Filterable
- *
- * @since 6.6
- */
- public interface Filter extends Serializable {
-
- /**
- * Check if an item passes the filter (in-memory filtering).
- *
- * @param itemId
- * identifier of the item being filtered; may be null when
- * the item is being added to the container
- * @param item
- * the item being filtered
- * @return true if the item is accepted by this filter
- * @throws UnsupportedOperationException
- * if the filter cannot be used for in-memory filtering
- */
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException;
-
- /**
- * Check if a change in the value of a property can affect the filtering
- * result. May always return true, at the cost of performance.
- *
- * If the filter cannot determine whether it may depend on the property
- * or not, should return true.
- *
- * @param propertyId
- * @return true if the filtering result may/does change based on changes
- * to the property identified by propertyId
- */
- public boolean appliesToProperty(Object propertyId);
-
- }
-
- /**
- * Interface that is implemented by containers which allow reducing their
- * visible contents based on a set of filters.
- * <p>
- * When a set of filters are set, only items that match all the filters are
- * included in the visible contents of the container. Still new items that
- * do not match filters can be added to the container. Multiple filters can
- * be added and the container remembers the state of the filters. When
- * multiple filters are added, all filters must match for an item to be
- * visible in the container.
- * </p>
- * <p>
- * When an {@link Ordered} or {@link Indexed} container is filtered, all
- * operations of these interfaces should only use the filtered and sorted
- * contents and the filtered indices to the container. Indices or item
- * identifiers in the public API refer to the visible view unless otherwise
- * stated. However, the <code>addItem*()</code> methods may add items that
- * will be filtered out after addition or moved to another position based on
- * sorting.
- * </p>
- * <p>
- * How filtering is performed when a {@link Hierarchical} container
- * implements {@link Filterable} is implementation specific and should be
- * documented in the implementing class.
- * </p>
- * <p>
- * Adding items (if supported) to a filtered {@link Ordered} or
- * {@link Indexed} container should insert them immediately after the
- * indicated visible item. However, the unfiltered position of items added
- * at index 0, at index {@link com.vaadin.data.Container#size()} or at an
- * undefined position is up to the implementation.
- * </p>
- *
- * <p>
- * This API replaces the old Filterable interface, renamed to
- * {@link SimpleFilterable} in Vaadin 6.6.
- * </p>
- *
- * @since 6.6
- */
- public interface Filterable extends Container, Serializable {
- /**
- * Adds a filter for the container.
- *
- * If a container has multiple filters, only items accepted by all
- * filters are visible.
- *
- * @throws UnsupportedFilterException
- * if the filter is not supported by the container
- */
- public void addContainerFilter(Filter filter)
- throws UnsupportedFilterException;
-
- /**
- * Removes a filter from the container.
- *
- * This requires that the equals() method considers the filters as
- * equivalent (same instance or properly implemented equals() method).
- */
- public void removeContainerFilter(Filter filter);
-
- /**
- * Remove all active filters from the container.
- */
- public void removeAllContainerFilters();
-
- }
-
- /**
- * Interface implemented by viewer classes capable of using a Container as a
- * data source.
- */
- public interface Viewer extends Serializable {
-
- /**
- * Sets the Container that serves as the data source of the viewer.
- *
- * @param newDataSource
- * The new data source Item
- */
- public void setContainerDataSource(Container newDataSource);
-
- /**
- * Gets the Container serving as the data source of the viewer.
- *
- * @return data source Container
- */
- public Container getContainerDataSource();
-
- }
-
- /**
- * <p>
- * Interface implemented by the editor classes supporting editing the
- * Container. Implementing this interface means that the Container serving
- * as the data source of the editor can be modified through it.
- * </p>
- * <p>
- * Note that not implementing the <code>Container.Editor</code> interface
- * does not restrict the class from editing the Container contents
- * internally.
- * </p>
- */
- public interface Editor extends Container.Viewer, Serializable {
-
- }
-
- /* Contents change event */
-
- /**
- * An <code>Event</code> object specifying the Container whose Item set has
- * changed (items added, removed or reordered).
- *
- * A simple property value change is not an item set change.
- */
- public interface ItemSetChangeEvent extends Serializable {
-
- /**
- * Gets the Property where the event occurred.
- *
- * @return source of the event
- */
- public Container getContainer();
- }
-
- /**
- * Container Item set change listener interface.
- *
- * An item set change refers to addition, removal or reordering of items in
- * the container. A simple property value change is not an item set change.
- */
- public interface ItemSetChangeListener extends Serializable {
-
- /**
- * Lets the listener know a Containers visible (filtered and/or sorted,
- * if applicable) Item set has changed.
- *
- * @param event
- * change event text
- */
- public void containerItemSetChange(Container.ItemSetChangeEvent event);
- }
-
- /**
- * The interface for adding and removing <code>ItemSetChangeEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate a <code>ItemSetChangeEvent</code> when its contents
- * are modified.
- *
- * An item set change refers to addition, removal or reordering of items in
- * the container. A simple property value change is not an item set change.
- *
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- */
- public interface ItemSetChangeNotifier extends Serializable {
-
- /**
- * Adds an Item set change listener for the object.
- *
- * @param listener
- * listener to be added
- */
- public void addListener(Container.ItemSetChangeListener listener);
-
- /**
- * Removes the Item set change listener from the object.
- *
- * @param listener
- * listener to be removed
- */
- public void removeListener(Container.ItemSetChangeListener listener);
- }
-
- /* Property set change event */
-
- /**
- * An <code>Event</code> object specifying the Container whose Property set
- * has changed.
- *
- * A property set change means the addition, removal or other structural
- * changes to the properties of a container. Changes concerning the set of
- * items in the container and their property values are not property set
- * changes.
- */
- public interface PropertySetChangeEvent extends Serializable {
-
- /**
- * Retrieves the Container whose contents have been modified.
- *
- * @return Source Container of the event.
- */
- public Container getContainer();
- }
-
- /**
- * The listener interface for receiving <code>PropertySetChangeEvent</code>
- * objects.
- *
- * A property set change means the addition, removal or other structural
- * change of the properties (supported property IDs) of a container. Changes
- * concerning the set of items in the container and their property values
- * are not property set changes.
- */
- public interface PropertySetChangeListener extends Serializable {
-
- /**
- * Notifies this listener that the set of property IDs supported by the
- * Container has changed.
- *
- * @param event
- * Change event.
- */
- public void containerPropertySetChange(
- Container.PropertySetChangeEvent event);
- }
-
- /**
- * <p>
- * The interface for adding and removing <code>PropertySetChangeEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate a <code>PropertySetChangeEvent</code> when the set
- * of property IDs supported by the container is modified.
- * </p>
- *
- * <p>
- * A property set change means the addition, removal or other structural
- * changes to the properties of a container. Changes concerning the set of
- * items in the container and their property values are not property set
- * changes.
- * </p>
- *
- * <p>
- * Note that the general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- */
- public interface PropertySetChangeNotifier extends Serializable {
-
- /**
- * Registers a new Property set change listener for this Container.
- *
- * @param listener
- * The new Listener to be registered
- */
- public void addListener(Container.PropertySetChangeListener listener);
-
- /**
- * Removes a previously registered Property set change listener.
- *
- * @param listener
- * Listener to be removed
- */
- public void removeListener(Container.PropertySetChangeListener listener);
- }
-}
diff --git a/src/com/vaadin/data/Item.java b/src/com/vaadin/data/Item.java
deleted file mode 100644
index 98b95aecff..0000000000
--- a/src/com/vaadin/data/Item.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-/**
- * <p>
- * Provides a mechanism for handling a set of Properties, each associated to a
- * locally unique non-null identifier. The interface is split into subinterfaces
- * to enable a class to implement only the functionalities it needs.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Item extends Serializable {
-
- /**
- * Gets the Property corresponding to the given Property ID stored in the
- * Item. If the Item does not contain the Property, <code>null</code> is
- * returned.
- *
- * @param id
- * identifier of the Property to get
- * @return the Property with the given ID or <code>null</code>
- */
- public Property<?> getItemProperty(Object id);
-
- /**
- * Gets the collection of IDs of all Properties stored in the Item.
- *
- * @return unmodifiable collection containing IDs of the Properties stored
- * the Item
- */
- public Collection<?> getItemPropertyIds();
-
- /**
- * Tries to add a new Property into the Item.
- *
- * <p>
- * This functionality is optional.
- * </p>
- *
- * @param id
- * ID of the new Property
- * @param property
- * the Property to be added and associated with the id
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the operation is not supported.
- */
- public boolean addItemProperty(Object id, Property property)
- throws UnsupportedOperationException;
-
- /**
- * Removes the Property identified by ID from the Item.
- *
- * <p>
- * This functionality is optional.
- * </p>
- *
- * @param id
- * ID of the Property to be removed
- * @return <code>true</code> if the operation succeeded
- * @throws UnsupportedOperationException
- * if the operation is not supported. <code>false</code> if not
- */
- public boolean removeItemProperty(Object id)
- throws UnsupportedOperationException;
-
- /**
- * Interface implemented by viewer classes capable of using an Item as a
- * data source.
- */
- public interface Viewer extends Serializable {
-
- /**
- * Sets the Item that serves as the data source of the viewer.
- *
- * @param newDataSource
- * The new data source Item
- */
- public void setItemDataSource(Item newDataSource);
-
- /**
- * Gets the Item serving as the data source of the viewer.
- *
- * @return data source Item
- */
- public Item getItemDataSource();
- }
-
- /**
- * Interface implemented by the <code>Editor</code> classes capable of
- * editing the Item. Implementing this interface means that the Item serving
- * as the data source of the editor can be modified through it.
- * <p>
- * Note : Not implementing the <code>Item.Editor</code> interface does not
- * restrict the class from editing the contents of an internally.
- * </p>
- */
- public interface Editor extends Item.Viewer, Serializable {
-
- }
-
- /* Property set change event */
-
- /**
- * An <code>Event</code> object specifying the Item whose contents has been
- * changed through the <code>Property</code> interface.
- * <p>
- * Note: The values stored in the Properties may change without triggering
- * this event.
- * </p>
- */
- public interface PropertySetChangeEvent extends Serializable {
-
- /**
- * Retrieves the Item whose contents has been modified.
- *
- * @return source Item of the event
- */
- public Item getItem();
- }
-
- /**
- * The listener interface for receiving <code>PropertySetChangeEvent</code>
- * objects.
- */
- public interface PropertySetChangeListener extends Serializable {
-
- /**
- * Notifies this listener that the Item's property set has changed.
- *
- * @param event
- * Property set change event object
- */
- public void itemPropertySetChange(Item.PropertySetChangeEvent event);
- }
-
- /**
- * The interface for adding and removing <code>PropertySetChangeEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate a <code>PropertySetChangeEvent</code> when its
- * Property set is modified.
- * <p>
- * Note : The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- */
- public interface PropertySetChangeNotifier extends Serializable {
-
- /**
- * Registers a new property set change listener for this Item.
- *
- * @param listener
- * The new Listener to be registered.
- */
- public void addListener(Item.PropertySetChangeListener listener);
-
- /**
- * Removes a previously registered property set change listener.
- *
- * @param listener
- * Listener to be removed.
- */
- public void removeListener(Item.PropertySetChangeListener listener);
- }
-}
diff --git a/src/com/vaadin/data/Property.java b/src/com/vaadin/data/Property.java
deleted file mode 100644
index 9fab642381..0000000000
--- a/src/com/vaadin/data/Property.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-
-/**
- * <p>
- * The <code>Property</code> is a simple data object that contains one typed
- * value. This interface contains methods to inspect and modify the stored value
- * and its type, and the object's read-only state.
- * </p>
- *
- * <p>
- * The <code>Property</code> also defines the events
- * <code>ReadOnlyStatusChangeEvent</code> and <code>ValueChangeEvent</code>, and
- * the associated <code>listener</code> and <code>notifier</code> interfaces.
- * </p>
- *
- * <p>
- * The <code>Property.Viewer</code> interface should be used to attach the
- * Property to an external data source. This way the value in the data source
- * can be inspected using the <code>Property</code> interface.
- * </p>
- *
- * <p>
- * The <code>Property.editor</code> interface should be implemented if the value
- * needs to be changed through the implementing class.
- * </p>
- *
- * @param T
- * type of values of the property
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Property<T> extends Serializable {
-
- /**
- * Gets the value stored in the Property. The returned object is compatible
- * with the class returned by getType().
- *
- * @return the value stored in the Property
- */
- public T getValue();
-
- /**
- * Sets the value of the Property.
- * <p>
- * Implementing this functionality is optional. If the functionality is
- * missing, one should declare the Property to be in read-only mode and
- * throw <code>Property.ReadOnlyException</code> in this function.
- * </p>
- *
- * Note : Since Vaadin 7.0, setting the value of a non-String property as a
- * String is no longer supported.
- *
- * @param newValue
- * New value of the Property. This should be assignable to the
- * type returned by getType
- *
- * @throws Property.ReadOnlyException
- * if the object is in read-only mode
- */
- public void setValue(Object newValue) throws Property.ReadOnlyException;
-
- /**
- * Returns the type of the Property. The methods <code>getValue</code> and
- * <code>setValue</code> must be compatible with this type: one must be able
- * to safely cast the value returned from <code>getValue</code> to the given
- * type and pass any variable assignable to this type as an argument to
- * <code>setValue</code>.
- *
- * @return type of the Property
- */
- public Class<? extends T> getType();
-
- /**
- * Tests if the Property is in read-only mode. In read-only mode calls to
- * the method <code>setValue</code> will throw
- * <code>ReadOnlyException</code> and will not modify the value of the
- * Property.
- *
- * @return <code>true</code> if the Property is in read-only mode,
- * <code>false</code> if it's not
- */
- public boolean isReadOnly();
-
- /**
- * Sets the Property's read-only mode to the specified status.
- *
- * This functionality is optional, but all properties must implement the
- * <code>isReadOnly</code> mode query correctly.
- *
- * @param newStatus
- * new read-only status of the Property
- */
- public void setReadOnly(boolean newStatus);
-
- /**
- * A Property that is capable of handle a transaction that can end in commit
- * or rollback.
- *
- * Note that this does not refer to e.g. database transactions but rather
- * two-phase commit that allows resetting old field values on a form etc. if
- * the commit of one of the properties fails after others have already been
- * committed. If
- *
- * @param <T>
- * The type of the property
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- */
- public interface Transactional<T> extends Property<T> {
-
- /**
- * Starts a transaction.
- *
- * <p>
- * If the value is set during a transaction the value must not replace
- * the original value until {@link #commit()} is called. Still,
- * {@link #getValue()} must return the current value set in the
- * transaction. Calling {@link #rollback()} while in a transaction must
- * rollback the value to what it was before the transaction started.
- * </p>
- * <p>
- * {@link ValueChangeEvent}s must not be emitted for internal value
- * changes during a transaction. If the value changes as a result of
- * {@link #commit()}, a {@link ValueChangeEvent} should be emitted.
- * </p>
- */
- public void startTransaction();
-
- /**
- * Commits and ends the transaction that is in progress.
- * <p>
- * If the value is changed as a result of this operation, a
- * {@link ValueChangeEvent} is emitted if such are supported.
- * <p>
- * This method has no effect if there is no transaction is in progress.
- * <p>
- * This method must never throw an exception.
- */
- public void commit();
-
- /**
- * Aborts and rolls back the transaction that is in progress.
- * <p>
- * The value is reset to the value before the transaction started. No
- * {@link ValueChangeEvent} is emitted as a result of this.
- * <p>
- * This method has no effect if there is no transaction is in progress.
- * <p>
- * This method must never throw an exception.
- */
- public void rollback();
- }
-
- /**
- * <code>Exception</code> object that signals that a requested Property
- * modification failed because it's in read-only mode.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public class ReadOnlyException extends RuntimeException {
-
- /**
- * Constructs a new <code>ReadOnlyException</code> without a detail
- * message.
- */
- public ReadOnlyException() {
- }
-
- /**
- * Constructs a new <code>ReadOnlyException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public ReadOnlyException(String msg) {
- super(msg);
- }
- }
-
- /**
- * Interface implemented by the viewer classes capable of using a Property
- * as a data source.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface Viewer extends Serializable {
-
- /**
- * Sets the Property that serves as the data source of the viewer.
- *
- * @param newDataSource
- * the new data source Property
- */
- public void setPropertyDataSource(Property newDataSource);
-
- /**
- * Gets the Property serving as the data source of the viewer.
- *
- * @return the Property serving as the viewers data source
- */
- public Property getPropertyDataSource();
- }
-
- /**
- * Interface implemented by the editor classes capable of editing the
- * Property.
- * <p>
- * Implementing this interface means that the Property serving as the data
- * source of the editor can be modified through the editor. It does not
- * restrict the editor from editing the Property internally, though if the
- * Property is in a read-only mode, attempts to modify it will result in the
- * <code>ReadOnlyException</code> being thrown.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface Editor extends Property.Viewer, Serializable {
-
- }
-
- /* Value change event */
-
- /**
- * An <code>Event</code> object specifying the Property whose value has been
- * changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ValueChangeEvent extends Serializable {
-
- /**
- * Retrieves the Property that has been modified.
- *
- * @return source Property of the event
- */
- public Property getProperty();
- }
-
- /**
- * The <code>listener</code> interface for receiving
- * <code>ValueChangeEvent</code> objects.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ValueChangeListener extends Serializable {
-
- /**
- * Notifies this listener that the Property's value has changed.
- *
- * @param event
- * value change event object
- */
- public void valueChange(Property.ValueChangeEvent event);
- }
-
- /**
- * The interface for adding and removing <code>ValueChangeEvent</code>
- * listeners. If a Property wishes to allow other objects to receive
- * <code>ValueChangeEvent</code> generated by it, it must implement this
- * interface.
- * <p>
- * Note : The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ValueChangeNotifier extends Serializable {
-
- /**
- * Registers a new value change listener for this Property.
- *
- * @param listener
- * the new Listener to be registered
- */
- public void addListener(Property.ValueChangeListener listener);
-
- /**
- * Removes a previously registered value change listener.
- *
- * @param listener
- * listener to be removed
- */
- public void removeListener(Property.ValueChangeListener listener);
- }
-
- /* ReadOnly Status change event */
-
- /**
- * An <code>Event</code> object specifying the Property whose read-only
- * status has been changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ReadOnlyStatusChangeEvent extends Serializable {
-
- /**
- * Property whose read-only state has changed.
- *
- * @return source Property of the event.
- */
- public Property getProperty();
- }
-
- /**
- * The listener interface for receiving
- * <code>ReadOnlyStatusChangeEvent</code> objects.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ReadOnlyStatusChangeListener extends Serializable {
-
- /**
- * Notifies this listener that a Property's read-only status has
- * changed.
- *
- * @param event
- * Read-only status change event object
- */
- public void readOnlyStatusChange(
- Property.ReadOnlyStatusChangeEvent event);
- }
-
- /**
- * The interface for adding and removing
- * <code>ReadOnlyStatusChangeEvent</code> listeners. If a Property wishes to
- * allow other objects to receive <code>ReadOnlyStatusChangeEvent</code>
- * generated by it, it must implement this interface.
- * <p>
- * Note : The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ReadOnlyStatusChangeNotifier extends Serializable {
-
- /**
- * Registers a new read-only status change listener for this Property.
- *
- * @param listener
- * the new Listener to be registered
- */
- public void addListener(Property.ReadOnlyStatusChangeListener listener);
-
- /**
- * Removes a previously registered read-only status change listener.
- *
- * @param listener
- * listener to be removed
- */
- public void removeListener(
- Property.ReadOnlyStatusChangeListener listener);
- }
-}
diff --git a/src/com/vaadin/data/Validatable.java b/src/com/vaadin/data/Validatable.java
deleted file mode 100644
index 4a7a0fda10..0000000000
--- a/src/com/vaadin/data/Validatable.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-/**
- * <p>
- * Interface for validatable objects. Defines methods to verify if the object's
- * value is valid or not, and to add, remove and list registered validators of
- * the object.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- * @see com.vaadin.data.Validator
- */
-public interface Validatable extends Serializable {
-
- /**
- * <p>
- * Adds a new validator for this object. The validator's
- * {@link Validator#validate(Object)} method is activated every time the
- * object's value needs to be verified, that is, when the {@link #isValid()}
- * method is called. This usually happens when the object's value changes.
- * </p>
- *
- * @param validator
- * the new validator
- */
- void addValidator(Validator validator);
-
- /**
- * <p>
- * Removes a previously registered validator from the object. The specified
- * validator is removed from the object and its <code>validate</code> method
- * is no longer called in {@link #isValid()}.
- * </p>
- *
- * @param validator
- * the validator to remove
- */
- void removeValidator(Validator validator);
-
- /**
- * <p>
- * Lists all validators currently registered for the object. If no
- * validators are registered, returns <code>null</code>.
- * </p>
- *
- * @return collection of validators or <code>null</code>
- */
- public Collection<Validator> getValidators();
-
- /**
- * <p>
- * Tests the current value of the object against all registered validators.
- * The registered validators are iterated and for each the
- * {@link Validator#validate(Object)} method is called. If any validator
- * throws the {@link Validator.InvalidValueException} this method returns
- * <code>false</code>.
- * </p>
- *
- * @return <code>true</code> if the registered validators concur that the
- * value is valid, <code>false</code> otherwise
- */
- public boolean isValid();
-
- /**
- * <p>
- * Checks the validity of the validatable. If the validatable is valid this
- * method should do nothing, and if it's not valid, it should throw
- * <code>Validator.InvalidValueException</code>
- * </p>
- *
- * @throws Validator.InvalidValueException
- * if the value is not valid
- */
- public void validate() throws Validator.InvalidValueException;
-
- /**
- * <p>
- * Checks the validabtable object accept invalid values.The default value is
- * <code>true</code>.
- * </p>
- *
- */
- public boolean isInvalidAllowed();
-
- /**
- * <p>
- * Should the validabtable object accept invalid values. Supporting this
- * configuration possibility is optional. By default invalid values are
- * allowed.
- * </p>
- *
- * @param invalidValueAllowed
- *
- * @throws UnsupportedOperationException
- * if the setInvalidAllowed is not supported.
- */
- public void setInvalidAllowed(boolean invalidValueAllowed)
- throws UnsupportedOperationException;
-
-}
diff --git a/src/com/vaadin/data/Validator.java b/src/com/vaadin/data/Validator.java
deleted file mode 100644
index 768a02babe..0000000000
--- a/src/com/vaadin/data/Validator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-
-/**
- * Interface that implements a method for validating if an {@link Object} is
- * valid or not.
- * <p>
- * Implementors of this class can be added to any
- * {@link com.vaadin.data.Validatable Validatable} implementor to verify its
- * value.
- * </p>
- * <p>
- * {@link #validate(Object)} can be used to check if a value is valid. An
- * {@link InvalidValueException} with an appropriate validation error message is
- * thrown if the value is not valid.
- * </p>
- * <p>
- * Validators must not have any side effects.
- * </p>
- * <p>
- * Since Vaadin 7, the method isValid(Object) does not exist in the interface -
- * {@link #validate(Object)} should be used instead, and the exception caught
- * where applicable. Concrete classes implementing {@link Validator} can still
- * internally implement and use isValid(Object) for convenience or to ease
- * migration from earlier Vaadin versions.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Validator extends Serializable {
-
- /**
- * Checks the given value against this validator. If the value is valid the
- * method does nothing. If the value is invalid, an
- * {@link InvalidValueException} is thrown.
- *
- * @param value
- * the value to check
- * @throws Validator.InvalidValueException
- * if the value is invalid
- */
- public void validate(Object value) throws Validator.InvalidValueException;
-
- /**
- * Exception that is thrown by a {@link Validator} when a value is invalid.
- *
- * <p>
- * The default implementation of InvalidValueException does not support HTML
- * in error messages. To enable HTML support, override
- * {@link #getHtmlMessage()} and use the subclass in validators.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public class InvalidValueException extends RuntimeException {
-
- /**
- * Array of one or more validation errors that are causing this
- * validation error.
- */
- private InvalidValueException[] causes = null;
-
- /**
- * Constructs a new {@code InvalidValueException} with the specified
- * message.
- *
- * @param message
- * The detail message of the problem.
- */
- public InvalidValueException(String message) {
- this(message, new InvalidValueException[] {});
- }
-
- /**
- * Constructs a new {@code InvalidValueException} with a set of causing
- * validation exceptions. The causing validation exceptions are included
- * when the exception is painted to the client.
- *
- * @param message
- * The detail message of the problem.
- * @param causes
- * One or more {@code InvalidValueException}s that caused
- * this exception.
- */
- public InvalidValueException(String message,
- InvalidValueException[] causes) {
- super(message);
- if (causes == null) {
- throw new NullPointerException(
- "Possible causes array must not be null");
- }
-
- this.causes = causes;
- }
-
- /**
- * Check if the error message should be hidden.
- *
- * An empty (null or "") message is invisible unless it contains nested
- * exceptions that are visible.
- *
- * @return true if the error message should be hidden, false otherwise
- */
- public boolean isInvisible() {
- String msg = getMessage();
- if (msg != null && msg.length() > 0) {
- return false;
- }
- if (causes != null) {
- for (int i = 0; i < causes.length; i++) {
- if (!causes[i].isInvisible()) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
- * Returns the message of the error in HTML.
- *
- * Note that this API may change in future versions.
- */
- public String getHtmlMessage() {
- return AbstractApplicationServlet
- .safeEscapeForHtml(getLocalizedMessage());
- }
-
- /**
- * Returns the {@code InvalidValueExceptions} that caused this
- * exception.
- *
- * @return An array containing the {@code InvalidValueExceptions} that
- * caused this exception. Returns an empty array if this
- * exception was not caused by other exceptions.
- */
- public InvalidValueException[] getCauses() {
- return causes;
- }
-
- }
-
- /**
- * A specific type of {@link InvalidValueException} that indicates that
- * validation failed because the value was empty. What empty means is up to
- * the thrower.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.3.0
- */
- @SuppressWarnings("serial")
- public class EmptyValueException extends Validator.InvalidValueException {
-
- public EmptyValueException(String message) {
- super(message);
- }
-
- }
-}
diff --git a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java b/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
deleted file mode 100644
index b8efa5b1e4..0000000000
--- a/src/com/vaadin/data/fieldgroup/BeanFieldGroup.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.reflect.Method;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.util.BeanItem;
-import com.vaadin.data.validator.BeanValidator;
-import com.vaadin.ui.Field;
-
-public class BeanFieldGroup<T> extends FieldGroup {
-
- private Class<T> beanType;
-
- private static Boolean beanValidationImplementationAvailable = null;
-
- public BeanFieldGroup(Class<T> beanType) {
- this.beanType = beanType;
- }
-
- @Override
- protected Class<?> getPropertyType(Object propertyId) {
- if (getItemDataSource() != null) {
- return super.getPropertyType(propertyId);
- } else {
- // Data source not set so we need to figure out the type manually
- /*
- * toString should never really be needed as propertyId should be of
- * form "fieldName" or "fieldName.subField[.subField2]" but the
- * method declaration comes from parent.
- */
- java.lang.reflect.Field f;
- try {
- f = getField(beanType, propertyId.toString());
- return f.getType();
- } catch (SecurityException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'.", e);
- } catch (NoSuchFieldException e) {
- throw new BindException("Cannot determine type of propertyId '"
- + propertyId + "'. The propertyId was not found in "
- + beanType.getName(), e);
- }
- }
- }
-
- private static java.lang.reflect.Field getField(Class<?> cls,
- String propertyId) throws SecurityException, NoSuchFieldException {
- if (propertyId.contains(".")) {
- String[] parts = propertyId.split("\\.", 2);
- // Get the type of the field in the "cls" class
- java.lang.reflect.Field field1 = getField(cls, parts[0]);
- // Find the rest from the sub type
- return getField(field1.getType(), parts[1]);
- } else {
- try {
- // Try to find the field directly in the given class
- java.lang.reflect.Field field1 = cls
- .getDeclaredField(propertyId);
- return field1;
- } catch (NoSuchFieldError e) {
- // Try super classes until we reach Object
- Class<?> superClass = cls.getSuperclass();
- if (superClass != Object.class) {
- return getField(superClass, propertyId);
- } else {
- throw e;
- }
- }
- }
- }
-
- /**
- * Helper method for setting the data source directly using a bean. This
- * method wraps the bean in a {@link BeanItem} and calls
- * {@link #setItemDataSource(Item)}.
- *
- * @param bean
- * The bean to use as data source.
- */
- public void setItemDataSource(T bean) {
- setItemDataSource(new BeanItem(bean));
- }
-
- @Override
- public void setItemDataSource(Item item) {
- if (!(item instanceof BeanItem)) {
- throw new RuntimeException(getClass().getSimpleName()
- + " only supports BeanItems as item data source");
- }
- super.setItemDataSource(item);
- }
-
- @Override
- public BeanItem<T> getItemDataSource() {
- return (BeanItem<T>) super.getItemDataSource();
- }
-
- @Override
- public void bind(Field field, Object propertyId) {
- if (getItemDataSource() != null) {
- // The data source is set so the property must be found in the item.
- // If it is not we try to add it.
- try {
- getItemProperty(propertyId);
- } catch (BindException e) {
- // Not found, try to add a nested property;
- // BeanItem property ids are always strings so this is safe
- getItemDataSource().addNestedProperty((String) propertyId);
- }
- }
-
- super.bind(field, propertyId);
- }
-
- @Override
- protected void configureField(Field<?> field) {
- super.configureField(field);
- // Add Bean validators if there are annotations
- if (isBeanValidationImplementationAvailable()) {
- BeanValidator validator = new BeanValidator(beanType,
- getPropertyId(field).toString());
- field.addValidator(validator);
- if (field.getLocale() != null) {
- validator.setLocale(field.getLocale());
- }
- }
- }
-
- /**
- * Checks whether a bean validation implementation (e.g. Hibernate Validator
- * or Apache Bean Validation) is available.
- *
- * TODO move this method to some more generic location
- *
- * @return true if a JSR-303 bean validation implementation is available
- */
- protected static boolean isBeanValidationImplementationAvailable() {
- if (beanValidationImplementationAvailable != null) {
- return beanValidationImplementationAvailable;
- }
- try {
- Class<?> validationClass = Class
- .forName("javax.validation.Validation");
- Method buildFactoryMethod = validationClass
- .getMethod("buildDefaultValidatorFactory");
- Object factory = buildFactoryMethod.invoke(null);
- beanValidationImplementationAvailable = (factory != null);
- } catch (Exception e) {
- // no bean validation implementation available
- beanValidationImplementationAvailable = false;
- }
- return beanValidationImplementationAvailable;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/Caption.java b/src/com/vaadin/data/fieldgroup/Caption.java
deleted file mode 100644
index b990b720cd..0000000000
--- a/src/com/vaadin/data/fieldgroup/Caption.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Caption {
- String value();
-}
diff --git a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
deleted file mode 100644
index be0db328f2..0000000000
--- a/src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.util.EnumSet;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.fieldgroup.FieldGroup.BindException;
-import com.vaadin.ui.AbstractSelect;
-import com.vaadin.ui.AbstractTextField;
-import com.vaadin.ui.CheckBox;
-import com.vaadin.ui.ComboBox;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.ListSelect;
-import com.vaadin.ui.NativeSelect;
-import com.vaadin.ui.OptionGroup;
-import com.vaadin.ui.RichTextArea;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.TextField;
-
-public class DefaultFieldGroupFieldFactory implements FieldGroupFieldFactory {
-
- public static final Object CAPTION_PROPERTY_ID = "Caption";
-
- @Override
- public <T extends Field> T createField(Class<?> type, Class<T> fieldType) {
- if (Enum.class.isAssignableFrom(type)) {
- return createEnumField(type, fieldType);
- } else if (Boolean.class.isAssignableFrom(type)
- || boolean.class.isAssignableFrom(type)) {
- return createBooleanField(fieldType);
- }
- if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return fieldType.cast(createAbstractTextField(fieldType
- .asSubclass(AbstractTextField.class)));
- } else if (fieldType == RichTextArea.class) {
- return fieldType.cast(createRichTextArea());
- }
- return createDefaultField(type, fieldType);
- }
-
- protected RichTextArea createRichTextArea() {
- RichTextArea rta = new RichTextArea();
- rta.setImmediate(true);
-
- return rta;
- }
-
- private <T extends Field> T createEnumField(Class<?> type,
- Class<T> fieldType) {
- if (AbstractSelect.class.isAssignableFrom(fieldType)) {
- AbstractSelect s = createCompatibleSelect((Class<? extends AbstractSelect>) fieldType);
- populateWithEnumData(s, (Class<? extends Enum>) type);
- return (T) s;
- }
-
- return null;
- }
-
- protected AbstractSelect createCompatibleSelect(
- Class<? extends AbstractSelect> fieldType) {
- AbstractSelect select;
- if (fieldType.isAssignableFrom(ListSelect.class)) {
- select = new ListSelect();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(NativeSelect.class)) {
- select = new NativeSelect();
- } else if (fieldType.isAssignableFrom(OptionGroup.class)) {
- select = new OptionGroup();
- select.setMultiSelect(false);
- } else if (fieldType.isAssignableFrom(Table.class)) {
- Table t = new Table();
- t.setSelectable(true);
- select = t;
- } else {
- select = new ComboBox(null);
- }
- select.setImmediate(true);
- select.setNullSelectionAllowed(false);
-
- return select;
- }
-
- protected <T extends Field> T createBooleanField(Class<T> fieldType) {
- if (fieldType.isAssignableFrom(CheckBox.class)) {
- CheckBox cb = new CheckBox(null);
- cb.setImmediate(true);
- return (T) cb;
- } else if (AbstractTextField.class.isAssignableFrom(fieldType)) {
- return (T) createAbstractTextField((Class<? extends AbstractTextField>) fieldType);
- }
-
- return null;
- }
-
- protected <T extends AbstractTextField> T createAbstractTextField(
- Class<T> fieldType) {
- if (fieldType == AbstractTextField.class) {
- fieldType = (Class<T>) TextField.class;
- }
- try {
- T field = fieldType.newInstance();
- field.setImmediate(true);
- return field;
- } catch (Exception e) {
- throw new BindException("Could not create a field of type "
- + fieldType, e);
- }
- }
-
- /**
- * Fallback when no specific field has been created. Typically returns a
- * TextField.
- *
- * @param <T>
- * The type of field to create
- * @param type
- * The type of data that should be edited
- * @param fieldType
- * The type of field to create
- * @return A field capable of editing the data or null if no field could be
- * created
- */
- protected <T extends Field> T createDefaultField(Class<?> type,
- Class<T> fieldType) {
- if (fieldType.isAssignableFrom(TextField.class)) {
- return fieldType.cast(createAbstractTextField(TextField.class));
- }
- return null;
- }
-
- /**
- * Populates the given select with all the enums in the given {@link Enum}
- * class. Uses {@link Enum}.toString() for caption.
- *
- * @param select
- * The select to populate
- * @param enumClass
- * The Enum class to use
- */
- protected void populateWithEnumData(AbstractSelect select,
- Class<? extends Enum> enumClass) {
- select.removeAllItems();
- for (Object p : select.getContainerPropertyIds()) {
- select.removeContainerProperty(p);
- }
- select.addContainerProperty(CAPTION_PROPERTY_ID, String.class, "");
- select.setItemCaptionPropertyId(CAPTION_PROPERTY_ID);
- @SuppressWarnings("unchecked")
- EnumSet<?> enumSet = EnumSet.allOf(enumClass);
- for (Object r : enumSet) {
- Item newItem = select.addItem(r);
- newItem.getItemProperty(CAPTION_PROPERTY_ID).setValue(r.toString());
- }
- }
-}
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroup.java b/src/com/vaadin/data/fieldgroup/FieldGroup.java
deleted file mode 100644
index 3df19f5bc9..0000000000
--- a/src/com/vaadin/data/fieldgroup/FieldGroup.java
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.TransactionalPropertyWrapper;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.DefaultFieldFactory;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Form;
-
-/**
- * FieldGroup provides an easy way of binding fields to data and handling
- * commits of these fields.
- * <p>
- * The functionality of FieldGroup is similar to {@link Form} but
- * {@link FieldGroup} does not handle layouts in any way. The typical use case
- * is to create a layout outside the FieldGroup and then use FieldGroup to bind
- * the fields to a data source.
- * </p>
- * <p>
- * {@link FieldGroup} is not a UI component so it cannot be added to a layout.
- * Using the buildAndBind methods {@link FieldGroup} can create fields for you
- * using a FieldGroupFieldFactory but you still have to add them to the correct
- * position in your layout.
- * </p>
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- */
-public class FieldGroup implements Serializable {
-
- private static final Logger logger = Logger.getLogger(FieldGroup.class
- .getName());
-
- private Item itemDataSource;
- private boolean buffered = true;
-
- private boolean enabled = true;
- private boolean readOnly = false;
-
- private HashMap<Object, Field<?>> propertyIdToField = new HashMap<Object, Field<?>>();
- private LinkedHashMap<Field<?>, Object> fieldToPropertyId = new LinkedHashMap<Field<?>, Object>();
- private List<CommitHandler> commitHandlers = new ArrayList<CommitHandler>();
-
- /**
- * The field factory used by builder methods.
- */
- private FieldGroupFieldFactory fieldFactory = new DefaultFieldGroupFieldFactory();
-
- /**
- * Constructs a field binder. Use {@link #setItemDataSource(Item)} to set a
- * data source for the field binder.
- *
- */
- public FieldGroup() {
-
- }
-
- /**
- * Constructs a field binder that uses the given data source.
- *
- * @param itemDataSource
- * The data source to bind the fields to
- */
- public FieldGroup(Item itemDataSource) {
- setItemDataSource(itemDataSource);
- }
-
- /**
- * Updates the item that is used by this FieldBinder. Rebinds all fields to
- * the properties in the new item.
- *
- * @param itemDataSource
- * The new item to use
- */
- public void setItemDataSource(Item itemDataSource) {
- this.itemDataSource = itemDataSource;
-
- for (Field<?> f : fieldToPropertyId.keySet()) {
- bind(f, fieldToPropertyId.get(f));
- }
- }
-
- /**
- * Gets the item used by this FieldBinder. Note that you must call
- * {@link #commit()} for the item to be updated unless buffered mode has
- * been switched off.
- *
- * @see #setBuffered(boolean)
- * @see #commit()
- *
- * @return The item used by this FieldBinder
- */
- public Item getItemDataSource() {
- return itemDataSource;
- }
-
- /**
- * Checks the buffered mode for the bound fields.
- * <p>
- *
- * @see #setBuffered(boolean) for more details on buffered mode
- *
- * @see Field#isBuffered()
- * @return true if buffered mode is on, false otherwise
- *
- */
- public boolean isBuffered() {
- return buffered;
- }
-
- /**
- * Sets the buffered mode for the bound fields.
- * <p>
- * When buffered mode is on the item will not be updated until
- * {@link #commit()} is called. If buffered mode is off the item will be
- * updated once the fields are updated.
- * </p>
- * <p>
- * The default is to use buffered mode.
- * </p>
- *
- * @see Field#setBuffered(boolean)
- * @param buffered
- * true to turn on buffered mode, false otherwise
- */
- public void setBuffered(boolean buffered) {
- if (buffered == this.buffered) {
- return;
- }
-
- this.buffered = buffered;
- for (Field<?> field : getFields()) {
- field.setBuffered(buffered);
- }
- }
-
- /**
- * Returns the enabled status for the fields.
- * <p>
- * Note that this will not accurately represent the enabled status of all
- * fields if you change the enabled status of the fields through some other
- * method than {@link #setEnabled(boolean)}.
- *
- * @return true if the fields are enabled, false otherwise
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Updates the enabled state of all bound fields.
- *
- * @param fieldsEnabled
- * true to enable all bound fields, false to disable them
- */
- public void setEnabled(boolean fieldsEnabled) {
- enabled = fieldsEnabled;
- for (Field<?> field : getFields()) {
- field.setEnabled(fieldsEnabled);
- }
- }
-
- /**
- * Returns the read only status for the fields.
- * <p>
- * Note that this will not accurately represent the read only status of all
- * fields if you change the read only status of the fields through some
- * other method than {@link #setReadOnly(boolean)}.
- *
- * @return true if the fields are set to read only, false otherwise
- */
- public boolean isReadOnly() {
- return readOnly;
- }
-
- /**
- * Updates the read only state of all bound fields.
- *
- * @param fieldsReadOnly
- * true to set all bound fields to read only, false to set them
- * to read write
- */
- public void setReadOnly(boolean fieldsReadOnly) {
- readOnly = fieldsReadOnly;
- }
-
- /**
- * Returns a collection of all fields that have been bound.
- * <p>
- * The fields are not returned in any specific order.
- * </p>
- *
- * @return A collection with all bound Fields
- */
- public Collection<Field<?>> getFields() {
- return fieldToPropertyId.keySet();
- }
-
- /**
- * Binds the field with the given propertyId from the current item. If an
- * item has not been set then the binding is postponed until the item is set
- * using {@link #setItemDataSource(Item)}.
- * <p>
- * This method also adds validators when applicable.
- * </p>
- *
- * @param field
- * The field to bind
- * @param propertyId
- * The propertyId to bind to the field
- * @throws BindException
- * If the property id is already bound to another field by this
- * field binder
- */
- public void bind(Field<?> field, Object propertyId) throws BindException {
- if (propertyIdToField.containsKey(propertyId)
- && propertyIdToField.get(propertyId) != field) {
- throw new BindException("Property id " + propertyId
- + " is already bound to another field");
- }
- fieldToPropertyId.put(field, propertyId);
- propertyIdToField.put(propertyId, field);
- if (itemDataSource == null) {
- // Will be bound when data source is set
- return;
- }
-
- field.setPropertyDataSource(wrapInTransactionalProperty(getItemProperty(propertyId)));
- configureField(field);
- }
-
- private <T> Property.Transactional<T> wrapInTransactionalProperty(
- Property<T> itemProperty) {
- return new TransactionalPropertyWrapper<T>(itemProperty);
- }
-
- /**
- * Gets the property with the given property id from the item.
- *
- * @param propertyId
- * The id if the property to find
- * @return The property with the given id from the item
- * @throws BindException
- * If the property was not found in the item or no item has been
- * set
- */
- protected Property<?> getItemProperty(Object propertyId)
- throws BindException {
- Item item = getItemDataSource();
- if (item == null) {
- throw new BindException("Could not lookup property with id "
- + propertyId + " as no item has been set");
- }
- Property<?> p = item.getItemProperty(propertyId);
- if (p == null) {
- throw new BindException("A property with id " + propertyId
- + " was not found in the item");
- }
- return p;
- }
-
- /**
- * Detaches the field from its property id and removes it from this
- * FieldBinder.
- * <p>
- * Note that the field is not detached from its property data source if it
- * is no longer connected to the same property id it was bound to using this
- * FieldBinder.
- *
- * @param field
- * The field to detach
- * @throws BindException
- * If the field is not bound by this field binder or not bound
- * to the correct property id
- */
- public void unbind(Field<?> field) throws BindException {
- Object propertyId = fieldToPropertyId.get(field);
- if (propertyId == null) {
- throw new BindException(
- "The given field is not part of this FieldBinder");
- }
-
- Property fieldDataSource = field.getPropertyDataSource();
- if (fieldDataSource instanceof TransactionalPropertyWrapper) {
- fieldDataSource = ((TransactionalPropertyWrapper) fieldDataSource)
- .getWrappedProperty();
- }
- if (fieldDataSource == getItemProperty(propertyId)) {
- field.setPropertyDataSource(null);
- }
- fieldToPropertyId.remove(field);
- propertyIdToField.remove(propertyId);
- }
-
- /**
- * Configures a field with the settings set for this FieldBinder.
- * <p>
- * By default this updates the buffered, read only and enabled state of the
- * field. Also adds validators when applicable.
- *
- * @param field
- * The field to update
- */
- protected void configureField(Field<?> field) {
- field.setBuffered(isBuffered());
-
- field.setEnabled(isEnabled());
- field.setReadOnly(isReadOnly());
- }
-
- /**
- * Gets the type of the property with the given property id.
- *
- * @param propertyId
- * The propertyId. Must be find
- * @return The type of the property
- */
- protected Class<?> getPropertyType(Object propertyId) throws BindException {
- if (getItemDataSource() == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No item data source has been set.");
- }
- Property<?> p = getItemDataSource().getItemProperty(propertyId);
- if (p == null) {
- throw new BindException(
- "Property type for '"
- + propertyId
- + "' could not be determined. No property with that id was found.");
- }
-
- return p.getType();
- }
-
- /**
- * Returns a collection of all property ids that have been bound to fields.
- * <p>
- * Note that this will return property ids even before the item has been
- * set. In that case it returns the property ids that will be bound once the
- * item is set.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of bound property ids
- */
- public Collection<Object> getBoundPropertyIds() {
- return Collections.unmodifiableCollection(propertyIdToField.keySet());
- }
-
- /**
- * Returns a collection of all property ids that exist in the item set using
- * {@link #setItemDataSource(Item)} but have not been bound to fields.
- * <p>
- * Will always return an empty collection before an item has been set using
- * {@link #setItemDataSource(Item)}.
- * </p>
- * <p>
- * No guarantee is given for the order of the property ids
- * </p>
- *
- * @return A collection of property ids that have not been bound to fields
- */
- public Collection<Object> getUnboundPropertyIds() {
- if (getItemDataSource() == null) {
- return new ArrayList<Object>();
- }
- List<Object> unboundPropertyIds = new ArrayList<Object>();
- unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds());
- unboundPropertyIds.removeAll(propertyIdToField.keySet());
- return unboundPropertyIds;
- }
-
- /**
- * Commits all changes done to the bound fields.
- * <p>
- * Calls all {@link CommitHandler}s before and after committing the field
- * changes to the item data source. The whole commit is aborted and state is
- * restored to what it was before commit was called if any
- * {@link CommitHandler} throws a CommitException or there is a problem
- * committing the fields
- *
- * @throws CommitException
- * If the commit was aborted
- */
- public void commit() throws CommitException {
- if (!isBuffered()) {
- // Not using buffered mode, nothing to do
- return;
- }
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .startTransaction();
- }
- try {
- firePreCommitEvent();
- // Commit the field values to the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- f.commit();
- }
- firePostCommitEvent();
-
- // Commit the properties
- for (Field<?> f : fieldToPropertyId.keySet()) {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .commit();
- }
-
- } catch (Exception e) {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- ((Property.Transactional<?>) f.getPropertyDataSource())
- .rollback();
- } catch (Exception rollbackException) {
- // FIXME: What to do ?
- }
- }
-
- throw new CommitException("Commit failed", e);
- }
-
- }
-
- /**
- * Sends a preCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePreCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.preCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Sends a postCommit event to all registered commit handlers
- *
- * @throws CommitException
- * If the commit should be aborted
- */
- private void firePostCommitEvent() throws CommitException {
- CommitHandler[] handlers = commitHandlers
- .toArray(new CommitHandler[commitHandlers.size()]);
-
- for (CommitHandler handler : handlers) {
- handler.postCommit(new CommitEvent(this));
- }
- }
-
- /**
- * Discards all changes done to the bound fields.
- * <p>
- * Only has effect if buffered mode is used.
- *
- */
- public void discard() {
- for (Field<?> f : fieldToPropertyId.keySet()) {
- try {
- f.discard();
- } catch (Exception e) {
- // TODO: handle exception
- // What can we do if discard fails other than try to discard all
- // other fields?
- }
- }
- }
-
- /**
- * Returns the field that is bound to the given property id
- *
- * @param propertyId
- * The property id to use to lookup the field
- * @return The field that is bound to the property id or null if no field is
- * bound to that property id
- */
- public Field<?> getField(Object propertyId) {
- return propertyIdToField.get(propertyId);
- }
-
- /**
- * Returns the property id that is bound to the given field
- *
- * @param field
- * The field to use to lookup the property id
- * @return The property id that is bound to the field or null if the field
- * is not bound to any property id by this FieldBinder
- */
- public Object getPropertyId(Field<?> field) {
- return fieldToPropertyId.get(field);
- }
-
- /**
- * Adds a commit handler.
- * <p>
- * The commit handler is called before the field values are committed to the
- * item ( {@link CommitHandler#preCommit(CommitEvent)}) and after the item
- * has been updated ({@link CommitHandler#postCommit(CommitEvent)}). If a
- * {@link CommitHandler} throws a CommitException the whole commit is
- * aborted and the fields retain their old values.
- *
- * @param commitHandler
- * The commit handler to add
- */
- public void addCommitHandler(CommitHandler commitHandler) {
- commitHandlers.add(commitHandler);
- }
-
- /**
- * Removes the given commit handler.
- *
- * @see #addCommitHandler(CommitHandler)
- *
- * @param commitHandler
- * The commit handler to remove
- */
- public void removeCommitHandler(CommitHandler commitHandler) {
- commitHandlers.remove(commitHandler);
- }
-
- /**
- * Returns a list of all commit handlers for this {@link FieldGroup}.
- * <p>
- * Use {@link #addCommitHandler(CommitHandler)} and
- * {@link #removeCommitHandler(CommitHandler)} to register or unregister a
- * commit handler.
- *
- * @return A collection of commit handlers
- */
- protected Collection<CommitHandler> getCommitHandlers() {
- return Collections.unmodifiableCollection(commitHandlers);
- }
-
- /**
- * CommitHandlers are used by {@link FieldGroup#commit()} as part of the
- * commit transactions. CommitHandlers can perform custom operations as part
- * of the commit and cause the commit to be aborted by throwing a
- * {@link CommitException}.
- */
- public interface CommitHandler extends Serializable {
- /**
- * Called before changes are committed to the field and the item is
- * updated.
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void preCommit(CommitEvent commitEvent) throws CommitException;
-
- /**
- * Called after changes are committed to the fields and the item is
- * updated..
- * <p>
- * Throw a {@link CommitException} to abort the commit.
- *
- * @param commitEvent
- * An event containing information regarding the commit
- * @throws CommitException
- * if the commit should be aborted
- */
- public void postCommit(CommitEvent commitEvent) throws CommitException;
- }
-
- /**
- * FIXME javadoc
- *
- */
- public static class CommitEvent implements Serializable {
- private FieldGroup fieldBinder;
-
- private CommitEvent(FieldGroup fieldBinder) {
- this.fieldBinder = fieldBinder;
- }
-
- /**
- * Returns the field binder that this commit relates to
- *
- * @return The FieldBinder that is being committed.
- */
- public FieldGroup getFieldBinder() {
- return fieldBinder;
- }
-
- }
-
- /**
- * Checks the validity of the bound fields.
- * <p>
- * Call the {@link Field#validate()} for the fields to get the individual
- * error messages.
- *
- * @return true if all bound fields are valid, false otherwise.
- */
- public boolean isValid() {
- try {
- for (Field<?> field : getFields()) {
- field.validate();
- }
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks if any bound field has been modified.
- *
- * @return true if at least on field has been modified, false otherwise
- */
- public boolean isModified() {
- for (Field<?> field : getFields()) {
- if (field.isModified()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Gets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @return The field factory in use
- *
- */
- public FieldGroupFieldFactory getFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Sets the field factory for the {@link FieldGroup}. The field factory is
- * only used when {@link FieldGroup} creates a new field.
- *
- * @param fieldFactory
- * The field factory to use
- */
- public void setFieldFactory(FieldGroupFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
- }
-
- /**
- * Binds member fields found in the given object.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age = new TextField("Age"); ... }
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.bindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and the age TextField to a "age"
- * property.
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to bind
- * @throws BindException
- * If there is a problem binding a field
- */
- public void bindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, false);
- }
-
- /**
- * Binds member fields found in the given object and builds member fields
- * that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory. All non-null fields for which a property id can
- * be determined are bound to the property id.
- * </p>
- * <p>
- * For example:
- *
- * <pre>
- * public class MyForm extends VerticalLayout {
- * private TextField firstName = new TextField("First name");
- * @PropertyId("last")
- * private TextField lastName = new TextField("Last name");
- * private TextField age;
- *
- * MyForm myForm = new MyForm();
- * ...
- * fieldGroup.buildAndBindMemberFields(myForm);
- * </pre>
- *
- * </p>
- * <p>
- * This binds the firstName TextField to a "firstName" property in the item,
- * lastName TextField to a "last" property and builds an age TextField using
- * the field factory and then binds it to the "age" property.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- public void buildAndBindMemberFields(Object objectWithMemberFields)
- throws BindException {
- buildAndBindMemberFields(objectWithMemberFields, true);
- }
-
- /**
- * Binds member fields found in the given object and optionally builds
- * member fields that have not been initialized.
- * <p>
- * This method processes all (Java) member fields whose type extends
- * {@link Field} and that can be mapped to a property id. Property id
- * mapping is done based on the field name or on a @{@link PropertyId}
- * annotation on the field. Fields that are not initialized (null) are built
- * using the field factory is buildFields is true. All non-null fields for
- * which a property id can be determined are bound to the property id.
- * </p>
- *
- * @param objectWithMemberFields
- * The object that contains (Java) member fields to build and
- * bind
- * @throws BindException
- * If there is a problem binding or building a field
- */
- protected void buildAndBindMemberFields(Object objectWithMemberFields,
- boolean buildFields) throws BindException {
- Class<?> objectClass = objectWithMemberFields.getClass();
-
- for (java.lang.reflect.Field memberField : objectClass
- .getDeclaredFields()) {
-
- if (!Field.class.isAssignableFrom(memberField.getType())) {
- // Process next field
- continue;
- }
-
- PropertyId propertyIdAnnotation = memberField
- .getAnnotation(PropertyId.class);
-
- Class<? extends Field> fieldType = (Class<? extends Field>) memberField
- .getType();
-
- Object propertyId = null;
- if (propertyIdAnnotation != null) {
- // @PropertyId(propertyId) always overrides property id
- propertyId = propertyIdAnnotation.value();
- } else {
- propertyId = memberField.getName();
- }
-
- // Ensure that the property id exists
- Class<?> propertyType;
-
- try {
- propertyType = getPropertyType(propertyId);
- } catch (BindException e) {
- // Property id was not found, skip this field
- continue;
- }
-
- Field<?> field;
- try {
- // Get the field from the object
- field = (Field<?>) ReflectTools.getJavaFieldValue(
- objectWithMemberFields, memberField);
- } catch (Exception e) {
- // If we cannot determine the value, just skip the field and try
- // the next one
- continue;
- }
-
- if (field == null && buildFields) {
- Caption captionAnnotation = memberField
- .getAnnotation(Caption.class);
- String caption;
- if (captionAnnotation != null) {
- caption = captionAnnotation.value();
- } else {
- caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- }
-
- // Create the component (Field)
- field = build(caption, propertyType, fieldType);
-
- // Store it in the field
- try {
- ReflectTools.setJavaFieldValue(objectWithMemberFields,
- memberField, field);
- } catch (IllegalArgumentException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (IllegalAccessException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- } catch (InvocationTargetException e) {
- throw new BindException("Could not assign value to field '"
- + memberField.getName() + "'", e);
- }
- }
-
- if (field != null) {
- // Bind it to the property id
- bind(field, propertyId);
- }
- }
- }
-
- public static class CommitException extends Exception {
-
- public CommitException() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- public CommitException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
- }
-
- public static class BindException extends RuntimeException {
-
- public BindException(String message) {
- super(message);
- }
-
- public BindException(String message, Throwable t) {
- super(message, t);
- }
-
- }
-
- /**
- * Builds a field and binds it to the given property id using the field
- * binder.
- *
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field
- */
- public Field<?> buildAndBind(Object propertyId) throws BindException {
- String caption = DefaultFieldFactory
- .createCaptionByPropertyId(propertyId);
- return buildAndBind(caption, propertyId);
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If there is a problem while building or binding
- * @return The created and bound field. Can be any type of {@link Field}.
- */
- public Field<?> buildAndBind(String caption, Object propertyId)
- throws BindException {
- Class<?> type = getPropertyType(propertyId);
- return buildAndBind(caption, propertyId, Field.class);
-
- }
-
- /**
- * Builds a field using the given caption and binds it to the given property
- * id using the field binder. Ensures the new field is of the given type.
- *
- * @param caption
- * The caption for the field
- * @param propertyId
- * The property id to bind to. Must be present in the field
- * finder.
- * @throws BindException
- * If the field could not be created
- * @return The created and bound field. Can be any type of {@link Field}.
- */
-
- public <T extends Field> T buildAndBind(String caption, Object propertyId,
- Class<T> fieldType) throws BindException {
- Class<?> type = getPropertyType(propertyId);
-
- T field = build(caption, type, fieldType);
- bind(field, propertyId);
-
- return field;
- }
-
- /**
- * Creates a field based on the given data type.
- * <p>
- * The data type is the type that we want to edit using the field. The field
- * type is the type of field we want to create, can be {@link Field} if any
- * Field is good.
- * </p>
- *
- * @param caption
- * The caption for the new field
- * @param dataType
- * The data model type that we want to edit using the field
- * @param fieldType
- * The type of field that we want to create
- * @return A Field capable of editing the given type
- * @throws BindException
- * If the field could not be created
- */
- protected <T extends Field> T build(String caption, Class<?> dataType,
- Class<T> fieldType) throws BindException {
- T field = getFieldFactory().createField(dataType, fieldType);
- if (field == null) {
- throw new BindException("Unable to build a field of type "
- + fieldType.getName() + " for editing "
- + dataType.getName());
- }
-
- field.setCaption(caption);
- return field;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java b/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
deleted file mode 100644
index 80c012cbdc..0000000000
--- a/src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Field;
-
-/**
- * Factory interface for creating new Field-instances based on the data type
- * that should be edited.
- *
- * @author Vaadin Ltd.
- * @version @version@
- * @since 7.0
- */
-public interface FieldGroupFieldFactory extends Serializable {
- /**
- * Creates a field based on the data type that we want to edit
- *
- * @param dataType
- * The type that we want to edit using the field
- * @param fieldType
- * The type of field we want to create. If set to {@link Field}
- * then any type of field is accepted
- * @return A field that can be assigned to the given fieldType and that is
- * capable of editing the given type of data
- */
- <T extends Field> T createField(Class<?> dataType, Class<T> fieldType);
-}
diff --git a/src/com/vaadin/data/fieldgroup/PropertyId.java b/src/com/vaadin/data/fieldgroup/PropertyId.java
deleted file mode 100644
index 268047401d..0000000000
--- a/src/com/vaadin/data/fieldgroup/PropertyId.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.fieldgroup;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface PropertyId {
- String value();
-}
diff --git a/src/com/vaadin/data/package.html b/src/com/vaadin/data/package.html
deleted file mode 100644
index a14ea1ac88..0000000000
--- a/src/com/vaadin/data/package.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-
-<p>Contains interfaces for the data layer, mainly for binding typed
-data and data collections to components, and for validating data.</p>
-
-<h2>Data binding</h2>
-
-<p>The package contains a three-tiered structure for typed data
-objects and collections of them:</p>
-
-<ul>
- <li>A {@link com.vaadin.data.Property Property} represents a
- single, typed data value.
-
- <li>An {@link com.vaadin.data.Item Item} embodies a set of <i>Properties</i>.
- A locally unique (inside the {@link com.vaadin.data.Item Item})
- Property identifier corresponds to each Property inside the Item.</li>
- <li>A {@link com.vaadin.data.Container Container} contains a set
- of Items, each corresponding to a locally unique Item identifier. Note
- that Container imposes a few restrictions on the data stored in it, see
- {@link com.vaadin.data.Container Container} for further information.</li>
-</ul>
-
-<p>For more information on the data model, see the <a
- href="http://vaadin.com/book/-/page/datamodel.html">Data model
-chapter</a> in Book of Vaadin.</p>
-
-<h2>Buffering</h2>
-
-<p>A {@link com.vaadin.data.Buffered Buffered} implementor is able
-to track and buffer changes and commit or discard them later.</p>
-
-<h2>Validation</h2>
-
-<p>{@link com.vaadin.data.Validator Validator} implementations are
-used to validate data, typically the value of a {@link
-com.vaadin.ui.Field Field}. One or more {@link com.vaadin.data.Validator
-Validators} can be added to a {@link com.vaadin.data.Validatable
-Validatable} implementor and then used to validate the value of the
-Validatable. </p>
-
-<!-- Put @see and @since tags down here. -->
-</body>
-</html>
diff --git a/src/com/vaadin/data/util/AbstractBeanContainer.java b/src/com/vaadin/data/util/AbstractBeanContainer.java
deleted file mode 100644
index 2f428d2cb6..0000000000
--- a/src/com/vaadin/data/util/AbstractBeanContainer.java
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Container.Filterable;
-import com.vaadin.data.Container.PropertySetChangeNotifier;
-import com.vaadin.data.Container.SimpleFilterable;
-import com.vaadin.data.Container.Sortable;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Property.ValueChangeEvent;
-import com.vaadin.data.Property.ValueChangeListener;
-import com.vaadin.data.Property.ValueChangeNotifier;
-import com.vaadin.data.util.MethodProperty.MethodException;
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.data.util.filter.UnsupportedFilterException;
-
-/**
- * An abstract base class for in-memory containers for JavaBeans.
- *
- * <p>
- * The properties of the container are determined automatically by introspecting
- * the used JavaBean class and explicitly adding or removing properties is not
- * supported. Only beans of the same type can be added to the container.
- * </p>
- *
- * <p>
- * Subclasses should implement any public methods adding items to the container,
- * typically calling the protected methods {@link #addItem(Object, Object)},
- * {@link #addItemAfter(Object, Object, Object)} and
- * {@link #addItemAt(int, Object, Object)}.
- * </p>
- *
- * @param <IDTYPE>
- * The type of the item identifier
- * @param <BEANTYPE>
- * The type of the Bean
- *
- * @since 6.5
- */
-public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends
- AbstractInMemoryContainer<IDTYPE, String, BeanItem<BEANTYPE>> implements
- Filterable, SimpleFilterable, Sortable, ValueChangeListener,
- PropertySetChangeNotifier {
-
- /**
- * Resolver that maps beans to their (item) identifiers, removing the need
- * to explicitly specify item identifiers when there is no need to customize
- * this.
- *
- * Note that beans can also be added with an explicit id even if a resolver
- * has been set.
- *
- * @param <IDTYPE>
- * @param <BEANTYPE>
- *
- * @since 6.5
- */
- public static interface BeanIdResolver<IDTYPE, BEANTYPE> extends
- Serializable {
- /**
- * Return the item identifier for a bean.
- *
- * @param bean
- * @return
- */
- public IDTYPE getIdForBean(BEANTYPE bean);
- }
-
- /**
- * A item identifier resolver that returns the value of a bean property.
- *
- * The bean must have a getter for the property, and the getter must return
- * an object of type IDTYPE.
- */
- protected class PropertyBasedBeanIdResolver implements
- BeanIdResolver<IDTYPE, BEANTYPE> {
-
- private final Object propertyId;
-
- public PropertyBasedBeanIdResolver(Object propertyId) {
- if (propertyId == null) {
- throw new IllegalArgumentException(
- "Property identifier must not be null");
- }
- this.propertyId = propertyId;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public IDTYPE getIdForBean(BEANTYPE bean)
- throws IllegalArgumentException {
- VaadinPropertyDescriptor<BEANTYPE> pd = model.get(propertyId);
- if (null == pd) {
- throw new IllegalStateException("Property " + propertyId
- + " not found");
- }
- try {
- Property<IDTYPE> property = (Property<IDTYPE>) pd
- .createProperty(bean);
- return property.getValue();
- } catch (MethodException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- }
-
- /**
- * The resolver that finds the item ID for a bean, or null not to use
- * automatic resolving.
- *
- * Methods that add a bean without specifying an ID must not be called if no
- * resolver has been set.
- */
- private BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver = null;
-
- /**
- * Maps all item ids in the container (including filtered) to their
- * corresponding BeanItem.
- */
- private final Map<IDTYPE, BeanItem<BEANTYPE>> itemIdToItem = new HashMap<IDTYPE, BeanItem<BEANTYPE>>();
-
- /**
- * The type of the beans in the container.
- */
- private final Class<? super BEANTYPE> type;
-
- /**
- * A description of the properties found in beans of type {@link #type}.
- * Determines the property ids that are present in the container.
- */
- private LinkedHashMap<String, VaadinPropertyDescriptor<BEANTYPE>> model;
-
- /**
- * Constructs a {@code AbstractBeanContainer} for beans of the given type.
- *
- * @param type
- * the type of the beans that will be added to the container.
- * @throws IllegalArgumentException
- * If {@code type} is null
- */
- protected AbstractBeanContainer(Class<? super BEANTYPE> type) {
- if (type == null) {
- throw new IllegalArgumentException(
- "The bean type passed to AbstractBeanContainer must not be null");
- }
- this.type = type;
- model = BeanItem.getPropertyDescriptors((Class<BEANTYPE>) type);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getType(java.lang.Object)
- */
- @Override
- public Class<?> getType(Object propertyId) {
- return model.get(propertyId).getPropertyType();
- }
-
- /**
- * Create a BeanItem for a bean using pre-parsed bean metadata (based on
- * {@link #getBeanType()}).
- *
- * @param bean
- * @return created {@link BeanItem} or null if bean is null
- */
- protected BeanItem<BEANTYPE> createBeanItem(BEANTYPE bean) {
- return bean == null ? null : new BeanItem<BEANTYPE>(bean, model);
- }
-
- /**
- * Returns the type of beans this Container can contain.
- *
- * This comes from the bean type constructor parameter, and bean metadata
- * (including container properties) is based on this.
- *
- * @return
- */
- public Class<? super BEANTYPE> getBeanType() {
- return type;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerPropertyIds()
- */
- @Override
- public Collection<String> getContainerPropertyIds() {
- return model.keySet();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeAllItems()
- */
- @Override
- public boolean removeAllItems() {
- int origSize = size();
-
- internalRemoveAllItems();
-
- // detach listeners from all Items
- for (Item item : itemIdToItem.values()) {
- removeAllValueChangeListeners(item);
- }
- itemIdToItem.clear();
-
- // fire event only if the visible view changed, regardless of whether
- // filtered out items were removed or not
- if (origSize != 0) {
- fireItemSetChange();
- }
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getItem(java.lang.Object)
- */
- @Override
- public BeanItem<BEANTYPE> getItem(Object itemId) {
- // TODO return only if visible?
- return getUnfilteredItem(itemId);
- }
-
- @Override
- protected BeanItem<BEANTYPE> getUnfilteredItem(Object itemId) {
- return itemIdToItem.get(itemId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getItemIds()
- */
- @Override
- @SuppressWarnings("unchecked")
- public List<IDTYPE> getItemIds() {
- return (List<IDTYPE>) super.getItemIds();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- Item item = getItem(itemId);
- if (item == null) {
- return null;
- }
- return item.getItemProperty(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeItem(java.lang.Object)
- */
- @Override
- public boolean removeItem(Object itemId) {
- // TODO should also remove items that are filtered out
- int origSize = size();
- Item item = getItem(itemId);
- int position = indexOfId(itemId);
-
- if (internalRemoveItem(itemId)) {
- // detach listeners from Item
- removeAllValueChangeListeners(item);
-
- // remove item
- itemIdToItem.remove(itemId);
-
- // fire event only if the visible view changed, regardless of
- // whether filtered out items were removed or not
- if (size() != origSize) {
- fireItemRemoved(position, itemId);
- }
-
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Re-filter the container when one of the monitored properties changes.
- */
- @Override
- public void valueChange(ValueChangeEvent event) {
- // if a property that is used in a filter is changed, refresh filtering
- filterAll();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.Container.Filterable#addContainerFilter(java.lang.Object,
- * java.lang.String, boolean, boolean)
- */
- @Override
- public void addContainerFilter(Object propertyId, String filterString,
- boolean ignoreCase, boolean onlyMatchPrefix) {
- try {
- addFilter(new SimpleStringFilter(propertyId, filterString,
- ignoreCase, onlyMatchPrefix));
- } catch (UnsupportedFilterException e) {
- // the filter instance created here is always valid for in-memory
- // containers
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Filterable#removeAllContainerFilters()
- */
- @Override
- public void removeAllContainerFilters() {
- if (!getFilters().isEmpty()) {
- for (Item item : itemIdToItem.values()) {
- removeAllValueChangeListeners(item);
- }
- removeAllFilters();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.Container.Filterable#removeContainerFilters(java.lang
- * .Object)
- */
- @Override
- public void removeContainerFilters(Object propertyId) {
- Collection<Filter> removedFilters = super.removeFilters(propertyId);
- if (!removedFilters.isEmpty()) {
- // stop listening to change events for the property
- for (Item item : itemIdToItem.values()) {
- removeValueChangeListener(item, propertyId);
- }
- }
- }
-
- @Override
- public void addContainerFilter(Filter filter)
- throws UnsupportedFilterException {
- addFilter(filter);
- }
-
- @Override
- public void removeContainerFilter(Filter filter) {
- removeFilter(filter);
- }
-
- /**
- * Make this container listen to the given property provided it notifies
- * when its value changes.
- *
- * @param item
- * The {@link Item} that contains the property
- * @param propertyId
- * The id of the property
- */
- private void addValueChangeListener(Item item, Object propertyId) {
- Property<?> property = item.getItemProperty(propertyId);
- if (property instanceof ValueChangeNotifier) {
- // avoid multiple notifications for the same property if
- // multiple filters are in use
- ValueChangeNotifier notifier = (ValueChangeNotifier) property;
- notifier.removeListener(this);
- notifier.addListener(this);
- }
- }
-
- /**
- * Remove this container as a listener for the given property.
- *
- * @param item
- * The {@link Item} that contains the property
- * @param propertyId
- * The id of the property
- */
- private void removeValueChangeListener(Item item, Object propertyId) {
- Property<?> property = item.getItemProperty(propertyId);
- if (property instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) property).removeListener(this);
- }
- }
-
- /**
- * Remove this contains as a listener for all the properties in the given
- * {@link Item}.
- *
- * @param item
- * The {@link Item} that contains the properties
- */
- private void removeAllValueChangeListeners(Item item) {
- for (Object propertyId : item.getItemPropertyIds()) {
- removeValueChangeListener(item, propertyId);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds()
- */
- @Override
- public Collection<?> getSortableContainerPropertyIds() {
- return getSortablePropertyIds();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
- * boolean[])
- */
- @Override
- public void sort(Object[] propertyId, boolean[] ascending) {
- sortContainer(propertyId, ascending);
- }
-
- @Override
- public ItemSorter getItemSorter() {
- return super.getItemSorter();
- }
-
- @Override
- public void setItemSorter(ItemSorter itemSorter) {
- super.setItemSorter(itemSorter);
- }
-
- @Override
- protected void registerNewItem(int position, IDTYPE itemId,
- BeanItem<BEANTYPE> item) {
- itemIdToItem.put(itemId, item);
-
- // add listeners to be able to update filtering on property
- // changes
- for (Filter filter : getFilters()) {
- for (String propertyId : getContainerPropertyIds()) {
- if (filter.appliesToProperty(propertyId)) {
- // addValueChangeListener avoids adding duplicates
- addValueChangeListener(item, propertyId);
- }
- }
- }
- }
-
- /**
- * Check that a bean can be added to the container (is of the correct type
- * for the container).
- *
- * @param bean
- * @return
- */
- private boolean validateBean(BEANTYPE bean) {
- return bean != null && getBeanType().isAssignableFrom(bean.getClass());
- }
-
- /**
- * Adds the bean to the Container.
- *
- * Note: the behavior of this method changed in Vaadin 6.6 - now items are
- * added at the very end of the unfiltered container and not after the last
- * visible item if filtering is used.
- *
- * @see com.vaadin.data.Container#addItem(Object)
- */
- protected BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) {
- if (!validateBean(bean)) {
- return null;
- }
- return internalAddItemAtEnd(itemId, createBeanItem(bean), true);
- }
-
- /**
- * Adds the bean after the given bean.
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object)
- */
- protected BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId,
- IDTYPE newItemId, BEANTYPE bean) {
- if (!validateBean(bean)) {
- return null;
- }
- return internalAddItemAfter(previousItemId, newItemId,
- createBeanItem(bean), true);
- }
-
- /**
- * Adds a new bean at the given index.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @param index
- * Index at which the bean should be added.
- * @param newItemId
- * The item id for the bean to add to the container.
- * @param bean
- * The bean to add to the container.
- *
- * @return Returns the new BeanItem or null if the operation fails.
- */
- protected BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId,
- BEANTYPE bean) {
- if (!validateBean(bean)) {
- return null;
- }
- return internalAddItemAt(index, newItemId, createBeanItem(bean), true);
- }
-
- /**
- * Adds a bean to the container using the bean item id resolver to find its
- * identifier.
- *
- * A bean id resolver must be set before calling this method.
- *
- * @see #addItem(Object, Object)
- *
- * @param bean
- * the bean to add
- * @return BeanItem<BEANTYPE> item added or null
- * @throws IllegalStateException
- * if no bean identifier resolver has been set
- * @throws IllegalArgumentException
- * if an identifier cannot be resolved for the bean
- */
- protected BeanItem<BEANTYPE> addBean(BEANTYPE bean)
- throws IllegalStateException, IllegalArgumentException {
- if (bean == null) {
- return null;
- }
- IDTYPE itemId = resolveBeanId(bean);
- if (itemId == null) {
- throw new IllegalArgumentException(
- "Resolved identifier for a bean must not be null");
- }
- return addItem(itemId, bean);
- }
-
- /**
- * Adds a bean to the container after a specified item identifier, using the
- * bean item id resolver to find its identifier.
- *
- * A bean id resolver must be set before calling this method.
- *
- * @see #addItemAfter(Object, Object, Object)
- *
- * @param previousItemId
- * the identifier of the bean after which this bean should be
- * added, null to add to the beginning
- * @param bean
- * the bean to add
- * @return BeanItem<BEANTYPE> item added or null
- * @throws IllegalStateException
- * if no bean identifier resolver has been set
- * @throws IllegalArgumentException
- * if an identifier cannot be resolved for the bean
- */
- protected BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId,
- BEANTYPE bean) throws IllegalStateException,
- IllegalArgumentException {
- if (bean == null) {
- return null;
- }
- IDTYPE itemId = resolveBeanId(bean);
- if (itemId == null) {
- throw new IllegalArgumentException(
- "Resolved identifier for a bean must not be null");
- }
- return addItemAfter(previousItemId, itemId, bean);
- }
-
- /**
- * Adds a bean at a specified (filtered view) position in the container
- * using the bean item id resolver to find its identifier.
- *
- * A bean id resolver must be set before calling this method.
- *
- * @see #addItemAfter(Object, Object, Object)
- *
- * @param index
- * the index (in the filtered view) at which to add the item
- * @param bean
- * the bean to add
- * @return BeanItem<BEANTYPE> item added or null
- * @throws IllegalStateException
- * if no bean identifier resolver has been set
- * @throws IllegalArgumentException
- * if an identifier cannot be resolved for the bean
- */
- protected BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean)
- throws IllegalStateException, IllegalArgumentException {
- if (bean == null) {
- return null;
- }
- IDTYPE itemId = resolveBeanId(bean);
- if (itemId == null) {
- throw new IllegalArgumentException(
- "Resolved identifier for a bean must not be null");
- }
- return addItemAt(index, itemId, bean);
- }
-
- /**
- * Adds all the beans from a {@link Collection} in one operation using the
- * bean item identifier resolver. More efficient than adding them one by
- * one.
- *
- * A bean id resolver must be set before calling this method.
- *
- * Note: the behavior of this method changed in Vaadin 6.6 - now items are
- * added at the very end of the unfiltered container and not after the last
- * visible item if filtering is used.
- *
- * @param collection
- * The collection of beans to add. Must not be null.
- * @throws IllegalStateException
- * if no bean identifier resolver has been set
- * @throws IllegalArgumentException
- * if the resolver returns a null itemId for one of the beans in
- * the collection
- */
- protected void addAll(Collection<? extends BEANTYPE> collection)
- throws IllegalStateException, IllegalArgumentException {
- boolean modified = false;
- for (BEANTYPE bean : collection) {
- // TODO skipping invalid beans - should not allow them in javadoc?
- if (bean == null
- || !getBeanType().isAssignableFrom(bean.getClass())) {
- continue;
- }
- IDTYPE itemId = resolveBeanId(bean);
- if (itemId == null) {
- throw new IllegalArgumentException(
- "Resolved identifier for a bean must not be null");
- }
-
- if (internalAddItemAtEnd(itemId, createBeanItem(bean), false) != null) {
- modified = true;
- }
- }
-
- if (modified) {
- // Filter the contents when all items have been added
- if (isFiltered()) {
- filterAll();
- } else {
- fireItemSetChange();
- }
- }
- }
-
- /**
- * Use the bean resolver to get the identifier for a bean.
- *
- * @param bean
- * @return resolved bean identifier, null if could not be resolved
- * @throws IllegalStateException
- * if no bean resolver is set
- */
- protected IDTYPE resolveBeanId(BEANTYPE bean) {
- if (beanIdResolver == null) {
- throw new IllegalStateException(
- "Bean item identifier resolver is required.");
- }
- return beanIdResolver.getIdForBean(bean);
- }
-
- /**
- * Sets the resolver that finds the item id for a bean, or null not to use
- * automatic resolving.
- *
- * Methods that add a bean without specifying an id must not be called if no
- * resolver has been set.
- *
- * Note that methods taking an explicit id can be used whether a resolver
- * has been defined or not.
- *
- * @param beanIdResolver
- * to use or null to disable automatic id resolution
- */
- protected void setBeanIdResolver(
- BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) {
- this.beanIdResolver = beanIdResolver;
- }
-
- /**
- * Returns the resolver that finds the item ID for a bean.
- *
- * @return resolver used or null if automatic item id resolving is disabled
- */
- public BeanIdResolver<IDTYPE, BEANTYPE> getBeanIdResolver() {
- return beanIdResolver;
- }
-
- /**
- * Create an item identifier resolver using a named bean property.
- *
- * @param propertyId
- * property identifier, which must map to a getter in BEANTYPE
- * @return created resolver
- */
- protected BeanIdResolver<IDTYPE, BEANTYPE> createBeanPropertyResolver(
- Object propertyId) {
- return new PropertyBasedBeanIdResolver(propertyId);
- }
-
- @Override
- public void addListener(Container.PropertySetChangeListener listener) {
- super.addListener(listener);
- }
-
- @Override
- public void removeListener(Container.PropertySetChangeListener listener) {
- super.removeListener(listener);
- }
-
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Use addNestedContainerProperty(String) to add container properties to a "
- + getClass().getSimpleName());
- }
-
- /**
- * Adds a property for the container and all its items.
- *
- * Primarily for internal use, may change in future versions.
- *
- * @param propertyId
- * @param propertyDescriptor
- * @return true if the property was added
- */
- protected final boolean addContainerProperty(String propertyId,
- VaadinPropertyDescriptor<BEANTYPE> propertyDescriptor) {
- if (null == propertyId || null == propertyDescriptor) {
- return false;
- }
-
- // Fails if the Property is already present
- if (model.containsKey(propertyId)) {
- return false;
- }
-
- model.put(propertyId, propertyDescriptor);
- for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
- item.addItemProperty(propertyId,
- propertyDescriptor.createProperty(item.getBean()));
- }
-
- // Sends a change event
- fireContainerPropertySetChange();
-
- return true;
- }
-
- /**
- * Adds a nested container property for the container, e.g.
- * "manager.address.street".
- *
- * All intermediate getters must exist and must return non-null values when
- * the property value is accessed.
- *
- * @see NestedMethodProperty
- *
- * @param propertyId
- * @return true if the property was added
- */
- public boolean addNestedContainerProperty(String propertyId) {
- return addContainerProperty(propertyId, new NestedPropertyDescriptor(
- propertyId, type));
- }
-
- /**
- * Adds a nested container properties for all sub-properties of a named
- * property to the container. The named property itself is removed from the
- * model as its subproperties are added.
- *
- * All intermediate getters must exist and must return non-null values when
- * the property value is accessed.
- *
- * @see NestedMethodProperty
- * @see #addNestedContainerProperty(String)
- *
- * @param propertyId
- */
- @SuppressWarnings("unchecked")
- public void addNestedContainerBean(String propertyId) {
- Class<?> propertyType = getType(propertyId);
- LinkedHashMap<String, VaadinPropertyDescriptor<Object>> pds = BeanItem
- .getPropertyDescriptors((Class<Object>) propertyType);
- for (String subPropertyId : pds.keySet()) {
- String qualifiedPropertyId = propertyId + "." + subPropertyId;
- NestedPropertyDescriptor<BEANTYPE> pd = new NestedPropertyDescriptor<BEANTYPE>(
- qualifiedPropertyId, (Class<BEANTYPE>) type);
- model.put(qualifiedPropertyId, pd);
- model.remove(propertyId);
- for (BeanItem<BEANTYPE> item : itemIdToItem.values()) {
- item.addItemProperty(propertyId,
- pd.createProperty(item.getBean()));
- item.removeItemProperty(propertyId);
- }
- }
-
- // Sends a change event
- fireContainerPropertySetChange();
- }
-
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- // Fails if the Property is not present
- if (!model.containsKey(propertyId)) {
- return false;
- }
-
- // Removes the Property to Property list and types
- model.remove(propertyId);
-
- // If remove the Property from all Items
- for (final Iterator<IDTYPE> i = getAllItemIds().iterator(); i.hasNext();) {
- getUnfilteredItem(i.next()).removeItemProperty(propertyId);
- }
-
- // Sends a change event
- fireContainerPropertySetChange();
-
- return true;
- }
-
-}
diff --git a/src/com/vaadin/data/util/AbstractContainer.java b/src/com/vaadin/data/util/AbstractContainer.java
deleted file mode 100644
index 7d96c2d757..0000000000
--- a/src/com/vaadin/data/util/AbstractContainer.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EventObject;
-import java.util.LinkedList;
-
-import com.vaadin.data.Container;
-
-/**
- * Abstract container class that manages event listeners and sending events to
- * them ({@link PropertySetChangeNotifier}, {@link ItemSetChangeNotifier}).
- *
- * Note that this class provides the internal implementations for both types of
- * events and notifiers as protected methods, but does not implement the
- * {@link PropertySetChangeNotifier} and {@link ItemSetChangeNotifier}
- * interfaces directly. This way, subclasses can choose not to implement them.
- * Subclasses implementing those interfaces should also override the
- * corresponding {@link #addListener()} and {@link #removeListener()} methods to
- * make them public.
- *
- * @since 6.6
- */
-public abstract class AbstractContainer implements Container {
-
- /**
- * List of all Property set change event listeners.
- */
- private Collection<Container.PropertySetChangeListener> propertySetChangeListeners = null;
-
- /**
- * List of all container Item set change event listeners.
- */
- private Collection<Container.ItemSetChangeListener> itemSetChangeListeners = null;
-
- /**
- * An <code>event</code> object specifying the container whose Property set
- * has changed.
- *
- * This class does not provide information about which properties were
- * concerned by the change, but subclasses can provide additional
- * information about the changes.
- */
- protected static class BasePropertySetChangeEvent extends EventObject
- implements Container.PropertySetChangeEvent, Serializable {
-
- protected BasePropertySetChangeEvent(Container source) {
- super(source);
- }
-
- @Override
- public Container getContainer() {
- return (Container) getSource();
- }
- }
-
- /**
- * An <code>event</code> object specifying the container whose Item set has
- * changed.
- *
- * This class does not provide information about the exact changes
- * performed, but subclasses can add provide additional information about
- * the changes.
- */
- protected static class BaseItemSetChangeEvent extends EventObject implements
- Container.ItemSetChangeEvent, Serializable {
-
- protected BaseItemSetChangeEvent(Container source) {
- super(source);
- }
-
- @Override
- public Container getContainer() {
- return (Container) getSource();
- }
- }
-
- // PropertySetChangeNotifier
-
- /**
- * Implementation of the corresponding method in
- * {@link PropertySetChangeNotifier}, override with the corresponding public
- * method and implement the interface to use this.
- *
- * @see PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener)
- */
- protected void addListener(Container.PropertySetChangeListener listener) {
- if (getPropertySetChangeListeners() == null) {
- setPropertySetChangeListeners(new LinkedList<Container.PropertySetChangeListener>());
- }
- getPropertySetChangeListeners().add(listener);
- }
-
- /**
- * Implementation of the corresponding method in
- * {@link PropertySetChangeNotifier}, override with the corresponding public
- * method and implement the interface to use this.
- *
- * @see PropertySetChangeNotifier#removeListener(com.vaadin.data.Container.
- * PropertySetChangeListener)
- */
- protected void removeListener(Container.PropertySetChangeListener listener) {
- if (getPropertySetChangeListeners() != null) {
- getPropertySetChangeListeners().remove(listener);
- }
- }
-
- // ItemSetChangeNotifier
-
- /**
- * Implementation of the corresponding method in
- * {@link ItemSetChangeNotifier}, override with the corresponding public
- * method and implement the interface to use this.
- *
- * @see ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener)
- */
- protected void addListener(Container.ItemSetChangeListener listener) {
- if (getItemSetChangeListeners() == null) {
- setItemSetChangeListeners(new LinkedList<Container.ItemSetChangeListener>());
- }
- getItemSetChangeListeners().add(listener);
- }
-
- /**
- * Implementation of the corresponding method in
- * {@link ItemSetChangeNotifier}, override with the corresponding public
- * method and implement the interface to use this.
- *
- * @see ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener)
- */
- protected void removeListener(Container.ItemSetChangeListener listener) {
- if (getItemSetChangeListeners() != null) {
- getItemSetChangeListeners().remove(listener);
- }
- }
-
- /**
- * Sends a simple Property set change event to all interested listeners.
- */
- protected void fireContainerPropertySetChange() {
- fireContainerPropertySetChange(new BasePropertySetChangeEvent(this));
- }
-
- /**
- * Sends a Property set change event to all interested listeners.
- *
- * Use {@link #fireContainerPropertySetChange()} instead of this method
- * unless additional information about the exact changes is available and
- * should be included in the event.
- *
- * @param event
- * the property change event to send, optionally with additional
- * information
- */
- protected void fireContainerPropertySetChange(
- Container.PropertySetChangeEvent event) {
- if (getPropertySetChangeListeners() != null) {
- final Object[] l = getPropertySetChangeListeners().toArray();
- for (int i = 0; i < l.length; i++) {
- ((Container.PropertySetChangeListener) l[i])
- .containerPropertySetChange(event);
- }
- }
- }
-
- /**
- * Sends a simple Item set change event to all interested listeners,
- * indicating that anything in the contents may have changed (items added,
- * removed etc.).
- */
- protected void fireItemSetChange() {
- fireItemSetChange(new BaseItemSetChangeEvent(this));
- }
-
- /**
- * Sends an Item set change event to all registered interested listeners.
- *
- * @param event
- * the item set change event to send, optionally with additional
- * information
- */
- protected void fireItemSetChange(ItemSetChangeEvent event) {
- if (getItemSetChangeListeners() != null) {
- final Object[] l = getItemSetChangeListeners().toArray();
- for (int i = 0; i < l.length; i++) {
- ((Container.ItemSetChangeListener) l[i])
- .containerItemSetChange(event);
- }
- }
- }
-
- /**
- * Sets the property set change listener collection. For internal use only.
- *
- * @param propertySetChangeListeners
- */
- protected void setPropertySetChangeListeners(
- Collection<Container.PropertySetChangeListener> propertySetChangeListeners) {
- this.propertySetChangeListeners = propertySetChangeListeners;
- }
-
- /**
- * Returns the property set change listener collection. For internal use
- * only.
- */
- protected Collection<Container.PropertySetChangeListener> getPropertySetChangeListeners() {
- return propertySetChangeListeners;
- }
-
- /**
- * Sets the item set change listener collection. For internal use only.
- *
- * @param itemSetChangeListeners
- */
- protected void setItemSetChangeListeners(
- Collection<Container.ItemSetChangeListener> itemSetChangeListeners) {
- this.itemSetChangeListeners = itemSetChangeListeners;
- }
-
- /**
- * Returns the item set change listener collection. For internal use only.
- */
- protected Collection<Container.ItemSetChangeListener> getItemSetChangeListeners() {
- return itemSetChangeListeners;
- }
-
- public Collection<?> getListeners(Class<?> eventType) {
- if (Container.PropertySetChangeEvent.class.isAssignableFrom(eventType)) {
- if (propertySetChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(propertySetChangeListeners);
- }
- } else if (Container.ItemSetChangeEvent.class
- .isAssignableFrom(eventType)) {
- if (itemSetChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(itemSetChangeListeners);
- }
- }
-
- return Collections.EMPTY_LIST;
- }
-}
diff --git a/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/src/com/vaadin/data/util/AbstractInMemoryContainer.java
deleted file mode 100644
index b7832756f2..0000000000
--- a/src/com/vaadin/data/util/AbstractInMemoryContainer.java
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Container.ItemSetChangeNotifier;
-import com.vaadin.data.Item;
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.data.util.filter.UnsupportedFilterException;
-
-/**
- * Abstract {@link Container} class that handles common functionality for
- * in-memory containers. Concrete in-memory container classes can either inherit
- * this class, inherit {@link AbstractContainer}, or implement the
- * {@link Container} interface directly.
- *
- * Adding and removing items (if desired) must be implemented in subclasses by
- * overriding the appropriate add*Item() and remove*Item() and removeAllItems()
- * methods, calling the corresponding
- * {@link #internalAddItemAfter(Object, Object, Item)},
- * {@link #internalAddItemAt(int, Object, Item)},
- * {@link #internalAddItemAtEnd(Object, Item, boolean)},
- * {@link #internalRemoveItem(Object)} and {@link #internalRemoveAllItems()}
- * methods.
- *
- * By default, adding and removing container properties is not supported, and
- * subclasses need to implement {@link #getContainerPropertyIds()}. Optionally,
- * subclasses can override {@link #addContainerProperty(Object, Class, Object)}
- * and {@link #removeContainerProperty(Object)} to implement them.
- *
- * Features:
- * <ul>
- * <li> {@link Container.Ordered}
- * <li> {@link Container.Indexed}
- * <li> {@link Filterable} and {@link SimpleFilterable} (internal implementation,
- * does not implement the interface directly)
- * <li> {@link Sortable} (internal implementation, does not implement the
- * interface directly)
- * </ul>
- *
- * To implement {@link Sortable}, subclasses need to implement
- * {@link #getSortablePropertyIds()} and call the superclass method
- * {@link #sortContainer(Object[], boolean[])} in the method
- * <code>sort(Object[], boolean[])</code>.
- *
- * To implement {@link Filterable}, subclasses need to implement the methods
- * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)}
- * (calling {@link #addFilter(Filter)}),
- * {@link Filterable#removeAllContainerFilters()} (calling
- * {@link #removeAllFilters()}) and
- * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)}
- * (calling {@link #removeFilter(com.vaadin.data.Container.Filter)}).
- *
- * To implement {@link SimpleFilterable}, subclasses also need to implement the
- * methods
- * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)}
- * and {@link SimpleFilterable#removeContainerFilters(Object)} calling
- * {@link #addFilter(com.vaadin.data.Container.Filter)} and
- * {@link #removeFilters(Object)} respectively.
- *
- * @param <ITEMIDTYPE>
- * the class of item identifiers in the container, use Object if can
- * be any class
- * @param <PROPERTYIDCLASS>
- * the class of property identifiers for the items in the container,
- * use Object if can be any class
- * @param <ITEMCLASS>
- * the (base) class of the Item instances in the container, use
- * {@link Item} if unknown
- *
- * @since 6.6
- */
-public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITEMCLASS extends Item>
- extends AbstractContainer implements ItemSetChangeNotifier,
- Container.Indexed {
-
- /**
- * An ordered {@link List} of all item identifiers in the container,
- * including those that have been filtered out.
- *
- * Must not be null.
- */
- private List<ITEMIDTYPE> allItemIds;
-
- /**
- * An ordered {@link List} of item identifiers in the container after
- * filtering, excluding those that have been filtered out.
- *
- * This is what the external API of the {@link Container} interface and its
- * subinterfaces shows (e.g. {@link #size()}, {@link #nextItemId(Object)}).
- *
- * If null, the full item id list is used instead.
- */
- private List<ITEMIDTYPE> filteredItemIds;
-
- /**
- * Filters that are applied to the container to limit the items visible in
- * it
- */
- private Set<Filter> filters = new HashSet<Filter>();
-
- /**
- * The item sorter which is used for sorting the container.
- */
- private ItemSorter itemSorter = new DefaultItemSorter();
-
- // Constructors
-
- /**
- * Constructor for an abstract in-memory container.
- */
- protected AbstractInMemoryContainer() {
- setAllItemIds(new ListSet<ITEMIDTYPE>());
- }
-
- // Container interface methods with more specific return class
-
- // default implementation, can be overridden
- @Override
- public ITEMCLASS getItem(Object itemId) {
- if (containsId(itemId)) {
- return getUnfilteredItem(itemId);
- } else {
- return null;
- }
- }
-
- /**
- * Get an item even if filtered out.
- *
- * For internal use only.
- *
- * @param itemId
- * @return
- */
- protected abstract ITEMCLASS getUnfilteredItem(Object itemId);
-
- // cannot override getContainerPropertyIds() and getItemIds(): if subclass
- // uses Object as ITEMIDCLASS or PROPERTYIDCLASS, Collection<Object> cannot
- // be cast to Collection<MyInterface>
-
- // public abstract Collection<PROPERTYIDCLASS> getContainerPropertyIds();
- // public abstract Collection<ITEMIDCLASS> getItemIds();
-
- // Container interface method implementations
-
- @Override
- public int size() {
- return getVisibleItemIds().size();
- }
-
- @Override
- public boolean containsId(Object itemId) {
- // only look at visible items after filtering
- if (itemId == null) {
- return false;
- } else {
- return getVisibleItemIds().contains(itemId);
- }
- }
-
- @Override
- public List<?> getItemIds() {
- return Collections.unmodifiableList(getVisibleItemIds());
- }
-
- // Container.Ordered
-
- @Override
- public ITEMIDTYPE nextItemId(Object itemId) {
- int index = indexOfId(itemId);
- if (index >= 0 && index < size() - 1) {
- return getIdByIndex(index + 1);
- } else {
- // out of bounds
- return null;
- }
- }
-
- @Override
- public ITEMIDTYPE prevItemId(Object itemId) {
- int index = indexOfId(itemId);
- if (index > 0) {
- return getIdByIndex(index - 1);
- } else {
- // out of bounds
- return null;
- }
- }
-
- @Override
- public ITEMIDTYPE firstItemId() {
- if (size() > 0) {
- return getIdByIndex(0);
- } else {
- return null;
- }
- }
-
- @Override
- public ITEMIDTYPE lastItemId() {
- if (size() > 0) {
- return getIdByIndex(size() - 1);
- } else {
- return null;
- }
- }
-
- @Override
- public boolean isFirstId(Object itemId) {
- if (itemId == null) {
- return false;
- }
- return itemId.equals(firstItemId());
- }
-
- @Override
- public boolean isLastId(Object itemId) {
- if (itemId == null) {
- return false;
- }
- return itemId.equals(lastItemId());
- }
-
- // Container.Indexed
-
- @Override
- public ITEMIDTYPE getIdByIndex(int index) {
- return getVisibleItemIds().get(index);
- }
-
- @Override
- public int indexOfId(Object itemId) {
- return getVisibleItemIds().indexOf(itemId);
- }
-
- // methods that are unsupported by default, override to support
-
- @Override
- public Object addItemAt(int index) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public Item addItemAt(int index, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public Object addItem() throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding items not supported. Override the relevant addItem*() methods if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Removing items not supported. Override the removeItem() method if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Removing items not supported. Override the removeAllItems() method if required as specified in AbstractInMemoryContainer javadoc.");
- }
-
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Adding container properties not supported. Override the addContainerProperty() method if required.");
- }
-
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Removing container properties not supported. Override the addContainerProperty() method if required.");
- }
-
- // ItemSetChangeNotifier
-
- @Override
- public void addListener(Container.ItemSetChangeListener listener) {
- super.addListener(listener);
- }
-
- @Override
- public void removeListener(Container.ItemSetChangeListener listener) {
- super.removeListener(listener);
- }
-
- // internal methods
-
- // Filtering support
-
- /**
- * Filter the view to recreate the visible item list from the unfiltered
- * items, and send a notification if the set of visible items changed in any
- * way.
- */
- protected void filterAll() {
- if (doFilterContainer(!getFilters().isEmpty())) {
- fireItemSetChange();
- }
- }
-
- /**
- * Filters the data in the container and updates internal data structures.
- * This method should reset any internal data structures and then repopulate
- * them so {@link #getItemIds()} and other methods only return the filtered
- * items.
- *
- * @param hasFilters
- * true if filters has been set for the container, false
- * otherwise
- * @return true if the item set has changed as a result of the filtering
- */
- protected boolean doFilterContainer(boolean hasFilters) {
- if (!hasFilters) {
- boolean changed = getAllItemIds().size() != getVisibleItemIds()
- .size();
- setFilteredItemIds(null);
- return changed;
- }
-
- // Reset filtered list
- List<ITEMIDTYPE> originalFilteredItemIds = getFilteredItemIds();
- boolean wasUnfiltered = false;
- if (originalFilteredItemIds == null) {
- originalFilteredItemIds = Collections.emptyList();
- wasUnfiltered = true;
- }
- setFilteredItemIds(new ListSet<ITEMIDTYPE>());
-
- // Filter
- boolean equal = true;
- Iterator<ITEMIDTYPE> origIt = originalFilteredItemIds.iterator();
- for (final Iterator<ITEMIDTYPE> i = getAllItemIds().iterator(); i
- .hasNext();) {
- final ITEMIDTYPE id = i.next();
- if (passesFilters(id)) {
- // filtered list comes from the full list, can use ==
- equal = equal && origIt.hasNext() && origIt.next() == id;
- getFilteredItemIds().add(id);
- }
- }
-
- return (wasUnfiltered && !getAllItemIds().isEmpty()) || !equal
- || origIt.hasNext();
- }
-
- /**
- * Checks if the given itemId passes the filters set for the container. The
- * caller should make sure the itemId exists in the container. For
- * non-existing itemIds the behavior is undefined.
- *
- * @param itemId
- * An itemId that exists in the container.
- * @return true if the itemId passes all filters or no filters are set,
- * false otherwise.
- */
- protected boolean passesFilters(Object itemId) {
- ITEMCLASS item = getUnfilteredItem(itemId);
- if (getFilters().isEmpty()) {
- return true;
- }
- final Iterator<Filter> i = getFilters().iterator();
- while (i.hasNext()) {
- final Filter f = i.next();
- if (!f.passesFilter(itemId, item)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Adds a container filter and re-filter the view.
- *
- * The filter must implement Filter and its sub-filters (if any) must also
- * be in-memory filterable.
- *
- * This can be used to implement
- * {@link Filterable#addContainerFilter(com.vaadin.data.Container.Filter)}
- * and optionally also
- * {@link SimpleFilterable#addContainerFilter(Object, String, boolean, boolean)}
- * (with {@link SimpleStringFilter}).
- *
- * Note that in some cases, incompatible filters cannot be detected when
- * added and an {@link UnsupportedFilterException} may occur when performing
- * filtering.
- *
- * @throws UnsupportedFilterException
- * if the filter is detected as not supported by the container
- */
- protected void addFilter(Filter filter) throws UnsupportedFilterException {
- getFilters().add(filter);
- filterAll();
- }
-
- /**
- * Remove a specific container filter and re-filter the view (if necessary).
- *
- * This can be used to implement
- * {@link Filterable#removeContainerFilter(com.vaadin.data.Container.Filter)}
- * .
- */
- protected void removeFilter(Filter filter) {
- for (Iterator<Filter> iterator = getFilters().iterator(); iterator
- .hasNext();) {
- Filter f = iterator.next();
- if (f.equals(filter)) {
- iterator.remove();
- filterAll();
- return;
- }
- }
- }
-
- /**
- * Remove all container filters for all properties and re-filter the view.
- *
- * This can be used to implement
- * {@link Filterable#removeAllContainerFilters()}.
- */
- protected void removeAllFilters() {
- if (getFilters().isEmpty()) {
- return;
- }
- getFilters().clear();
- filterAll();
- }
-
- /**
- * Checks if there is a filter that applies to a given property.
- *
- * @param propertyId
- * @return true if there is an active filter for the property
- */
- protected boolean isPropertyFiltered(Object propertyId) {
- if (getFilters().isEmpty() || propertyId == null) {
- return false;
- }
- final Iterator<Filter> i = getFilters().iterator();
- while (i.hasNext()) {
- final Filter f = i.next();
- if (f.appliesToProperty(propertyId)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Remove all container filters for a given property identifier and
- * re-filter the view. This also removes filters applying to multiple
- * properties including the one identified by propertyId.
- *
- * This can be used to implement
- * {@link Filterable#removeContainerFilters(Object)}.
- *
- * @param propertyId
- * @return Collection<Filter> removed filters
- */
- protected Collection<Filter> removeFilters(Object propertyId) {
- if (getFilters().isEmpty() || propertyId == null) {
- return Collections.emptyList();
- }
- List<Filter> removedFilters = new LinkedList<Filter>();
- for (Iterator<Filter> iterator = getFilters().iterator(); iterator
- .hasNext();) {
- Filter f = iterator.next();
- if (f.appliesToProperty(propertyId)) {
- removedFilters.add(f);
- iterator.remove();
- }
- }
- if (!removedFilters.isEmpty()) {
- filterAll();
- return removedFilters;
- }
- return Collections.emptyList();
- }
-
- // sorting
-
- /**
- * Returns the ItemSorter used for comparing items in a sort. See
- * {@link #setItemSorter(ItemSorter)} for more information.
- *
- * @return The ItemSorter used for comparing two items in a sort.
- */
- protected ItemSorter getItemSorter() {
- return itemSorter;
- }
-
- /**
- * Sets the ItemSorter used for comparing items in a sort. The
- * {@link ItemSorter#compare(Object, Object)} method is called with item ids
- * to perform the sorting. A default ItemSorter is used if this is not
- * explicitly set.
- *
- * @param itemSorter
- * The ItemSorter used for comparing two items in a sort (not
- * null).
- */
- protected void setItemSorter(ItemSorter itemSorter) {
- this.itemSorter = itemSorter;
- }
-
- /**
- * Sort base implementation to be used to implement {@link Sortable}.
- *
- * Subclasses should call this from a public
- * {@link #sort(Object[], boolean[])} method when implementing Sortable.
- *
- * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
- * boolean[])
- */
- protected void sortContainer(Object[] propertyId, boolean[] ascending) {
- if (!(this instanceof Sortable)) {
- throw new UnsupportedOperationException(
- "Cannot sort a Container that does not implement Sortable");
- }
-
- // Set up the item sorter for the sort operation
- getItemSorter().setSortProperties((Sortable) this, propertyId,
- ascending);
-
- // Perform the actual sort
- doSort();
-
- // Post sort updates
- if (isFiltered()) {
- filterAll();
- } else {
- fireItemSetChange();
- }
-
- }
-
- /**
- * Perform the sorting of the data structures in the container. This is
- * invoked when the <code>itemSorter</code> has been prepared for the sort
- * operation. Typically this method calls
- * <code>Collections.sort(aCollection, getItemSorter())</code> on all arrays
- * (containing item ids) that need to be sorted.
- *
- */
- protected void doSort() {
- Collections.sort(getAllItemIds(), getItemSorter());
- }
-
- /**
- * Returns the sortable property identifiers for the container. Can be used
- * to implement {@link Sortable#getSortableContainerPropertyIds()}.
- */
- protected Collection<?> getSortablePropertyIds() {
- LinkedList<Object> sortables = new LinkedList<Object>();
- for (Object propertyId : getContainerPropertyIds()) {
- Class<?> propertyType = getType(propertyId);
- if (Comparable.class.isAssignableFrom(propertyType)
- || propertyType.isPrimitive()) {
- sortables.add(propertyId);
- }
- }
- return sortables;
- }
-
- // removing items
-
- /**
- * Removes all items from the internal data structures of this class. This
- * can be used to implement {@link #removeAllItems()} in subclasses.
- *
- * No notification is sent, the caller has to fire a suitable item set
- * change notification.
- */
- protected void internalRemoveAllItems() {
- // Removes all Items
- getAllItemIds().clear();
- if (isFiltered()) {
- getFilteredItemIds().clear();
- }
- }
-
- /**
- * Removes a single item from the internal data structures of this class.
- * This can be used to implement {@link #removeItem(Object)} in subclasses.
- *
- * No notification is sent, the caller has to fire a suitable item set
- * change notification.
- *
- * @param itemId
- * the identifier of the item to remove
- * @return true if an item was successfully removed, false if failed to
- * remove or no such item
- */
- protected boolean internalRemoveItem(Object itemId) {
- if (itemId == null) {
- return false;
- }
-
- boolean result = getAllItemIds().remove(itemId);
- if (result && isFiltered()) {
- getFilteredItemIds().remove(itemId);
- }
-
- return result;
- }
-
- // adding items
-
- /**
- * Adds the bean to all internal data structures at the given position.
- * Fails if an item with itemId is already in the container. Returns a the
- * item if it was added successfully, null otherwise.
- *
- * <p>
- * Caller should initiate filtering after calling this method.
- * </p>
- *
- * For internal use only - subclasses should use
- * {@link #internalAddItemAtEnd(Object, Item, boolean)},
- * {@link #internalAddItemAt(int, Object, Item, boolean)} and
- * {@link #internalAddItemAfter(Object, Object, Item, boolean)} instead.
- *
- * @param position
- * The position at which the item should be inserted in the
- * unfiltered collection of items
- * @param itemId
- * The item identifier for the item to insert
- * @param item
- * The item to insert
- *
- * @return ITEMCLASS if the item was added successfully, null otherwise
- */
- private ITEMCLASS internalAddAt(int position, ITEMIDTYPE itemId,
- ITEMCLASS item) {
- if (position < 0 || position > getAllItemIds().size() || itemId == null
- || item == null) {
- return null;
- }
- // Make sure that the item has not been added previously
- if (getAllItemIds().contains(itemId)) {
- return null;
- }
-
- // "filteredList" will be updated in filterAll() which should be invoked
- // by the caller after calling this method.
- getAllItemIds().add(position, itemId);
- registerNewItem(position, itemId, item);
-
- return item;
- }
-
- /**
- * Add an item at the end of the container, and perform filtering if
- * necessary. An event is fired if the filtered view changes.
- *
- * @param newItemId
- * @param item
- * new item to add
- * @param filter
- * true to perform filtering and send event after adding the
- * item, false to skip these operations for batch inserts - if
- * false, caller needs to make sure these operations are
- * performed at the end of the batch
- * @return item added or null if no item was added
- */
- protected ITEMCLASS internalAddItemAtEnd(ITEMIDTYPE newItemId,
- ITEMCLASS item, boolean filter) {
- ITEMCLASS newItem = internalAddAt(getAllItemIds().size(), newItemId,
- item);
- if (newItem != null && filter) {
- // TODO filter only this item, use fireItemAdded()
- filterAll();
- if (!isFiltered()) {
- // TODO hack: does not detect change in filterAll() in this case
- fireItemAdded(indexOfId(newItemId), newItemId, item);
- }
- }
- return newItem;
- }
-
- /**
- * Add an item after a given (visible) item, and perform filtering. An event
- * is fired if the filtered view changes.
- *
- * The new item is added at the beginning if previousItemId is null.
- *
- * @param previousItemId
- * item id of a visible item after which to add the new item, or
- * null to add at the beginning
- * @param newItemId
- * @param item
- * new item to add
- * @param filter
- * true to perform filtering and send event after adding the
- * item, false to skip these operations for batch inserts - if
- * false, caller needs to make sure these operations are
- * performed at the end of the batch
- * @return item added or null if no item was added
- */
- protected ITEMCLASS internalAddItemAfter(ITEMIDTYPE previousItemId,
- ITEMIDTYPE newItemId, ITEMCLASS item, boolean filter) {
- // only add if the previous item is visible
- ITEMCLASS newItem = null;
- if (previousItemId == null) {
- newItem = internalAddAt(0, newItemId, item);
- } else if (containsId(previousItemId)) {
- newItem = internalAddAt(
- getAllItemIds().indexOf(previousItemId) + 1, newItemId,
- item);
- }
- if (newItem != null && filter) {
- // TODO filter only this item, use fireItemAdded()
- filterAll();
- if (!isFiltered()) {
- // TODO hack: does not detect change in filterAll() in this case
- fireItemAdded(indexOfId(newItemId), newItemId, item);
- }
- }
- return newItem;
- }
-
- /**
- * Add an item at a given (visible after filtering) item index, and perform
- * filtering. An event is fired if the filtered view changes.
- *
- * @param index
- * position where to add the item (visible/view index)
- * @param newItemId
- * @param item
- * new item to add
- * @param filter
- * true to perform filtering and send event after adding the
- * item, false to skip these operations for batch inserts - if
- * false, caller needs to make sure these operations are
- * performed at the end of the batch
- * @return item added or null if no item was added
- */
- protected ITEMCLASS internalAddItemAt(int index, ITEMIDTYPE newItemId,
- ITEMCLASS item, boolean filter) {
- if (index < 0 || index > size()) {
- return null;
- } else if (index == 0) {
- // add before any item, visible or not
- return internalAddItemAfter(null, newItemId, item, filter);
- } else {
- // if index==size(), adds immediately after last visible item
- return internalAddItemAfter(getIdByIndex(index - 1), newItemId,
- item, filter);
- }
- }
-
- /**
- * Registers a new item as having been added to the container. This can
- * involve storing the item or any relevant information about it in internal
- * container-specific collections if necessary, as well as registering
- * listeners etc.
- *
- * The full identifier list in {@link AbstractInMemoryContainer} has already
- * been updated to reflect the new item when this method is called.
- *
- * @param position
- * @param itemId
- * @param item
- */
- protected void registerNewItem(int position, ITEMIDTYPE itemId,
- ITEMCLASS item) {
- }
-
- // item set change notifications
-
- /**
- * Notify item set change listeners that an item has been added to the
- * container.
- *
- * Unless subclasses specify otherwise, the default notification indicates a
- * full refresh.
- *
- * @param postion
- * position of the added item in the view (if visible)
- * @param itemId
- * id of the added item
- * @param item
- * the added item
- */
- protected void fireItemAdded(int position, ITEMIDTYPE itemId, ITEMCLASS item) {
- fireItemSetChange();
- }
-
- /**
- * Notify item set change listeners that an item has been removed from the
- * container.
- *
- * Unless subclasses specify otherwise, the default notification indicates a
- * full refresh.
- *
- * @param postion
- * position of the removed item in the view prior to removal (if
- * was visible)
- * @param itemId
- * id of the removed item, of type {@link Object} to satisfy
- * {@link Container#removeItem(Object)} API
- */
- protected void fireItemRemoved(int position, Object itemId) {
- fireItemSetChange();
- }
-
- // visible and filtered item identifier lists
-
- /**
- * Returns the internal list of visible item identifiers after filtering.
- *
- * For internal use only.
- */
- protected List<ITEMIDTYPE> getVisibleItemIds() {
- if (isFiltered()) {
- return getFilteredItemIds();
- } else {
- return getAllItemIds();
- }
- }
-
- /**
- * Returns true is the container has active filters.
- *
- * @return true if the container is currently filtered
- */
- protected boolean isFiltered() {
- return filteredItemIds != null;
- }
-
- /**
- * Internal helper method to set the internal list of filtered item
- * identifiers. Should not be used outside this class except for
- * implementing clone(), may disappear from future versions.
- *
- * @param filteredItemIds
- */
- @Deprecated
- protected void setFilteredItemIds(List<ITEMIDTYPE> filteredItemIds) {
- this.filteredItemIds = filteredItemIds;
- }
-
- /**
- * Internal helper method to get the internal list of filtered item
- * identifiers. Should not be used outside this class except for
- * implementing clone(), may disappear from future versions - use
- * {@link #getVisibleItemIds()} in other contexts.
- *
- * @return List<ITEMIDTYPE>
- */
- protected List<ITEMIDTYPE> getFilteredItemIds() {
- return filteredItemIds;
- }
-
- /**
- * Internal helper method to set the internal list of all item identifiers.
- * Should not be used outside this class except for implementing clone(),
- * may disappear from future versions.
- *
- * @param allItemIds
- */
- @Deprecated
- protected void setAllItemIds(List<ITEMIDTYPE> allItemIds) {
- this.allItemIds = allItemIds;
- }
-
- /**
- * Internal helper method to get the internal list of all item identifiers.
- * Avoid using this method outside this class, may disappear in future
- * versions.
- *
- * @return List<ITEMIDTYPE>
- */
- protected List<ITEMIDTYPE> getAllItemIds() {
- return allItemIds;
- }
-
- /**
- * Set the internal collection of filters without performing filtering.
- *
- * This method is mostly for internal use, use
- * {@link #addFilter(com.vaadin.data.Container.Filter)} and
- * <code>remove*Filter*</code> (which also re-filter the container) instead
- * when possible.
- *
- * @param filters
- */
- protected void setFilters(Set<Filter> filters) {
- this.filters = filters;
- }
-
- /**
- * Returns the internal collection of filters. The returned collection
- * should not be modified by callers outside this class.
- *
- * @return Set<Filter>
- */
- protected Set<Filter> getFilters() {
- return filters;
- }
-
-}
diff --git a/src/com/vaadin/data/util/AbstractProperty.java b/src/com/vaadin/data/util/AbstractProperty.java
deleted file mode 100644
index 373a8dfd58..0000000000
--- a/src/com/vaadin/data/util/AbstractProperty.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-
-import com.vaadin.data.Property;
-
-/**
- * Abstract base class for {@link Property} implementations.
- *
- * Handles listener management for {@link ValueChangeListener}s and
- * {@link ReadOnlyStatusChangeListener}s.
- *
- * @since 6.6
- */
-public abstract class AbstractProperty<T> implements Property<T>,
- Property.ValueChangeNotifier, Property.ReadOnlyStatusChangeNotifier {
-
- /**
- * List of listeners who are interested in the read-only status changes of
- * the Property
- */
- private LinkedList<ReadOnlyStatusChangeListener> readOnlyStatusChangeListeners = null;
-
- /**
- * List of listeners who are interested in the value changes of the Property
- */
- private LinkedList<ValueChangeListener> valueChangeListeners = null;
-
- /**
- * Is the Property read-only?
- */
- private boolean readOnly;
-
- /**
- * {@inheritDoc}
- *
- * Override for additional restrictions on what is considered a read-only
- * property.
- */
- @Override
- public boolean isReadOnly() {
- return readOnly;
- }
-
- @Override
- public void setReadOnly(boolean newStatus) {
- boolean oldStatus = isReadOnly();
- readOnly = newStatus;
- if (oldStatus != isReadOnly()) {
- fireReadOnlyStatusChange();
- }
- }
-
- /**
- * Returns the value of the <code>Property</code> in human readable textual
- * format.
- *
- * @return String representation of the value stored in the Property
- * @deprecated use {@link #getValue()} instead and possibly toString on that
- */
- @Deprecated
- @Override
- public String toString() {
- throw new UnsupportedOperationException(
- "Use Property.getValue() instead of " + getClass()
- + ".toString()");
- }
-
- /* Events */
-
- /**
- * An <code>Event</code> object specifying the Property whose read-only
- * status has been changed.
- */
- protected static class ReadOnlyStatusChangeEvent extends
- java.util.EventObject implements Property.ReadOnlyStatusChangeEvent {
-
- /**
- * Constructs a new read-only status change event for this object.
- *
- * @param source
- * source object of the event.
- */
- protected ReadOnlyStatusChangeEvent(Property source) {
- super(source);
- }
-
- /**
- * Gets the Property whose read-only state has changed.
- *
- * @return source Property of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
-
- }
-
- /**
- * Registers a new read-only status change listener for this Property.
- *
- * @param listener
- * the new Listener to be registered.
- */
- @Override
- public void addListener(Property.ReadOnlyStatusChangeListener listener) {
- if (readOnlyStatusChangeListeners == null) {
- readOnlyStatusChangeListeners = new LinkedList<ReadOnlyStatusChangeListener>();
- }
- readOnlyStatusChangeListeners.add(listener);
- }
-
- /**
- * Removes a previously registered read-only status change listener.
- *
- * @param listener
- * the listener to be removed.
- */
- @Override
- public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
- if (readOnlyStatusChangeListeners != null) {
- readOnlyStatusChangeListeners.remove(listener);
- }
- }
-
- /**
- * Sends a read only status change event to all registered listeners.
- */
- protected void fireReadOnlyStatusChange() {
- if (readOnlyStatusChangeListeners != null) {
- final Object[] l = readOnlyStatusChangeListeners.toArray();
- final Property.ReadOnlyStatusChangeEvent event = new ReadOnlyStatusChangeEvent(
- this);
- for (int i = 0; i < l.length; i++) {
- ((Property.ReadOnlyStatusChangeListener) l[i])
- .readOnlyStatusChange(event);
- }
- }
- }
-
- /**
- * An <code>Event</code> object specifying the Property whose value has been
- * changed.
- */
- private static class ValueChangeEvent extends java.util.EventObject
- implements Property.ValueChangeEvent {
-
- /**
- * Constructs a new value change event for this object.
- *
- * @param source
- * source object of the event.
- */
- protected ValueChangeEvent(Property source) {
- super(source);
- }
-
- /**
- * Gets the Property whose value has changed.
- *
- * @return source Property of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
-
- }
-
- @Override
- public void addListener(ValueChangeListener listener) {
- if (valueChangeListeners == null) {
- valueChangeListeners = new LinkedList<ValueChangeListener>();
- }
- valueChangeListeners.add(listener);
-
- }
-
- @Override
- public void removeListener(ValueChangeListener listener) {
- if (valueChangeListeners != null) {
- valueChangeListeners.remove(listener);
- }
-
- }
-
- /**
- * Sends a value change event to all registered listeners.
- */
- protected void fireValueChange() {
- if (valueChangeListeners != null) {
- final Object[] l = valueChangeListeners.toArray();
- final Property.ValueChangeEvent event = new ValueChangeEvent(this);
- for (int i = 0; i < l.length; i++) {
- ((Property.ValueChangeListener) l[i]).valueChange(event);
- }
- }
- }
-
- public Collection<?> getListeners(Class<?> eventType) {
- if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) {
- if (valueChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections.unmodifiableCollection(valueChangeListeners);
- }
- } else if (Property.ReadOnlyStatusChangeEvent.class
- .isAssignableFrom(eventType)) {
- if (readOnlyStatusChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(readOnlyStatusChangeListeners);
- }
- }
-
- return Collections.EMPTY_LIST;
- }
-
-}
diff --git a/src/com/vaadin/data/util/BeanContainer.java b/src/com/vaadin/data/util/BeanContainer.java
deleted file mode 100644
index bc1ee3c39e..0000000000
--- a/src/com/vaadin/data/util/BeanContainer.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.Collection;
-
-/**
- * An in-memory container for JavaBeans.
- *
- * <p>
- * The properties of the container are determined automatically by introspecting
- * the used JavaBean class. Only beans of the same type can be added to the
- * container.
- * </p>
- *
- * <p>
- * In BeanContainer (unlike {@link BeanItemContainer}), the item IDs do not have
- * to be the beans themselves. The container can be used either with explicit
- * item IDs or the item IDs can be generated when adding beans.
- * </p>
- *
- * <p>
- * To use explicit item IDs, use the methods {@link #addItem(Object, Object)},
- * {@link #addItemAfter(Object, Object, Object)} and
- * {@link #addItemAt(int, Object, Object)}.
- * </p>
- *
- * <p>
- * If a bean id resolver is set using
- * {@link #setBeanIdResolver(com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver)}
- * or {@link #setBeanIdProperty(Object)}, the methods {@link #addBean(Object)},
- * {@link #addBeanAfter(Object, Object)}, {@link #addBeanAt(int, Object)} and
- * {@link #addAll(java.util.Collection)} can be used to add items to the
- * container. If one of these methods is called, the resolver is used to
- * generate an identifier for the item (must not return null).
- * </p>
- *
- * <p>
- * Note that explicit item identifiers can also be used when a resolver has been
- * set by calling the addItem*() methods - the resolver is only used when adding
- * beans using the addBean*() or {@link #addAll(Collection)} methods.
- * </p>
- *
- * <p>
- * It is not possible to add additional properties to the container and nested
- * bean properties are not supported.
- * </p>
- *
- * @param <IDTYPE>
- * The type of the item identifier
- * @param <BEANTYPE>
- * The type of the Bean
- *
- * @see AbstractBeanContainer
- * @see BeanItemContainer
- *
- * @since 6.5
- */
-public class BeanContainer<IDTYPE, BEANTYPE> extends
- AbstractBeanContainer<IDTYPE, BEANTYPE> {
-
- public BeanContainer(Class<? super BEANTYPE> type) {
- super(type);
- }
-
- /**
- * Adds the bean to the Container.
- *
- * @see com.vaadin.data.Container#addItem(Object)
- */
- @Override
- public BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) {
- if (itemId != null && bean != null) {
- return super.addItem(itemId, bean);
- } else {
- return null;
- }
- }
-
- /**
- * Adds the bean after the given item id.
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object)
- */
- @Override
- public BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId,
- IDTYPE newItemId, BEANTYPE bean) {
- if (newItemId != null && bean != null) {
- return super.addItemAfter(previousItemId, newItemId, bean);
- } else {
- return null;
- }
- }
-
- /**
- * Adds a new bean at the given index.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @param index
- * Index at which the bean should be added.
- * @param newItemId
- * The item id for the bean to add to the container.
- * @param bean
- * The bean to add to the container.
- *
- * @return Returns the new BeanItem or null if the operation fails.
- */
- @Override
- public BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId,
- BEANTYPE bean) {
- if (newItemId != null && bean != null) {
- return super.addItemAt(index, newItemId, bean);
- } else {
- return null;
- }
- }
-
- // automatic item id resolution
-
- /**
- * Sets the bean id resolver to use a property of the beans as the
- * identifier.
- *
- * @param propertyId
- * the identifier of the property to use to find item identifiers
- */
- public void setBeanIdProperty(Object propertyId) {
- setBeanIdResolver(createBeanPropertyResolver(propertyId));
- }
-
- @Override
- // overridden to make public
- public void setBeanIdResolver(
- BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) {
- super.setBeanIdResolver(beanIdResolver);
- }
-
- @Override
- // overridden to make public
- public BeanItem<BEANTYPE> addBean(BEANTYPE bean)
- throws IllegalStateException, IllegalArgumentException {
- return super.addBean(bean);
- }
-
- @Override
- // overridden to make public
- public BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, BEANTYPE bean)
- throws IllegalStateException, IllegalArgumentException {
- return super.addBeanAfter(previousItemId, bean);
- }
-
- @Override
- // overridden to make public
- public BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean)
- throws IllegalStateException, IllegalArgumentException {
- return super.addBeanAt(index, bean);
- }
-
- @Override
- // overridden to make public
- public void addAll(Collection<? extends BEANTYPE> collection)
- throws IllegalStateException {
- super.addAll(collection);
- }
-
-}
diff --git a/src/com/vaadin/data/util/BeanItem.java b/src/com/vaadin/data/util/BeanItem.java
deleted file mode 100644
index 94439471f5..0000000000
--- a/src/com/vaadin/data/util/BeanItem.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A wrapper class for adding the Item interface to any Java Bean.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class BeanItem<BT> extends PropertysetItem {
-
- /**
- * The bean which this Item is based on.
- */
- private final BT bean;
-
- /**
- * <p>
- * Creates a new instance of <code>BeanItem</code> and adds all properties
- * of a Java Bean to it. The properties are identified by their respective
- * bean names.
- * </p>
- *
- * <p>
- * Note : This version only supports introspectable bean properties and
- * their getter and setter methods. Stand-alone <code>is</code> and
- * <code>are</code> methods are not supported.
- * </p>
- *
- * @param bean
- * the Java Bean to copy properties from.
- *
- */
- public BeanItem(BT bean) {
- this(bean, getPropertyDescriptors((Class<BT>) bean.getClass()));
- }
-
- /**
- * <p>
- * Creates a new instance of <code>BeanItem</code> using a pre-computed set
- * of properties. The properties are identified by their respective bean
- * names.
- * </p>
- *
- * @param bean
- * the Java Bean to copy properties from.
- * @param propertyDescriptors
- * pre-computed property descriptors
- */
- BeanItem(BT bean,
- Map<String, VaadinPropertyDescriptor<BT>> propertyDescriptors) {
-
- this.bean = bean;
-
- for (VaadinPropertyDescriptor<BT> pd : propertyDescriptors.values()) {
- addItemProperty(pd.getName(), pd.createProperty(bean));
- }
- }
-
- /**
- * <p>
- * Creates a new instance of <code>BeanItem</code> and adds all listed
- * properties of a Java Bean to it - in specified order. The properties are
- * identified by their respective bean names.
- * </p>
- *
- * <p>
- * Note : This version only supports introspectable bean properties and
- * their getter and setter methods. Stand-alone <code>is</code> and
- * <code>are</code> methods are not supported.
- * </p>
- *
- * @param bean
- * the Java Bean to copy properties from.
- * @param propertyIds
- * id of the property.
- */
- public BeanItem(BT bean, Collection<?> propertyIds) {
-
- this.bean = bean;
-
- // Create bean information
- LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pds = getPropertyDescriptors((Class<BT>) bean
- .getClass());
-
- // Add all the bean properties as MethodProperties to this Item
- for (Object id : propertyIds) {
- VaadinPropertyDescriptor<BT> pd = pds.get(id);
- if (pd != null) {
- addItemProperty(pd.getName(), pd.createProperty(bean));
- }
- }
-
- }
-
- /**
- * <p>
- * Creates a new instance of <code>BeanItem</code> and adds all listed
- * properties of a Java Bean to it - in specified order. The properties are
- * identified by their respective bean names.
- * </p>
- *
- * <p>
- * Note : This version only supports introspectable bean properties and
- * their getter and setter methods. Stand-alone <code>is</code> and
- * <code>are</code> methods are not supported.
- * </p>
- *
- * @param bean
- * the Java Bean to copy properties from.
- * @param propertyIds
- * ids of the properties.
- */
- public BeanItem(BT bean, String[] propertyIds) {
- this(bean, Arrays.asList(propertyIds));
- }
-
- /**
- * <p>
- * Perform introspection on a Java Bean class to find its properties.
- * </p>
- *
- * <p>
- * Note : This version only supports introspectable bean properties and
- * their getter and setter methods. Stand-alone <code>is</code> and
- * <code>are</code> methods are not supported.
- * </p>
- *
- * @param beanClass
- * the Java Bean class to get properties for.
- * @return an ordered map from property names to property descriptors
- */
- static <BT> LinkedHashMap<String, VaadinPropertyDescriptor<BT>> getPropertyDescriptors(
- final Class<BT> beanClass) {
- final LinkedHashMap<String, VaadinPropertyDescriptor<BT>> pdMap = new LinkedHashMap<String, VaadinPropertyDescriptor<BT>>();
-
- // Try to introspect, if it fails, we just have an empty Item
- try {
- List<PropertyDescriptor> propertyDescriptors = getBeanPropertyDescriptor(beanClass);
-
- // Add all the bean properties as MethodProperties to this Item
- // later entries on the list overwrite earlier ones
- for (PropertyDescriptor pd : propertyDescriptors) {
- final Method getMethod = pd.getReadMethod();
- if ((getMethod != null)
- && getMethod.getDeclaringClass() != Object.class) {
- VaadinPropertyDescriptor<BT> vaadinPropertyDescriptor = new MethodPropertyDescriptor<BT>(
- pd.getName(), pd.getPropertyType(),
- pd.getReadMethod(), pd.getWriteMethod());
- pdMap.put(pd.getName(), vaadinPropertyDescriptor);
- }
- }
- } catch (final java.beans.IntrospectionException ignored) {
- }
-
- return pdMap;
- }
-
- /**
- * Returns the property descriptors of a class or an interface.
- *
- * For an interface, superinterfaces are also iterated as Introspector does
- * not take them into account (Oracle Java bug 4275879), but in that case,
- * both the setter and the getter for a property must be in the same
- * interface and should not be overridden in subinterfaces for the discovery
- * to work correctly.
- *
- * For interfaces, the iteration is depth first and the properties of
- * superinterfaces are returned before those of their subinterfaces.
- *
- * @param beanClass
- * @return
- * @throws IntrospectionException
- */
- private static List<PropertyDescriptor> getBeanPropertyDescriptor(
- final Class<?> beanClass) throws IntrospectionException {
- // Oracle bug 4275879: Introspector does not consider superinterfaces of
- // an interface
- if (beanClass.isInterface()) {
- List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
-
- for (Class<?> cls : beanClass.getInterfaces()) {
- propertyDescriptors.addAll(getBeanPropertyDescriptor(cls));
- }
-
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- propertyDescriptors.addAll(Arrays.asList(info
- .getPropertyDescriptors()));
-
- return propertyDescriptors;
- } else {
- BeanInfo info = Introspector.getBeanInfo(beanClass);
- return Arrays.asList(info.getPropertyDescriptors());
- }
- }
-
- /**
- * Expands nested bean properties by replacing a top-level property with
- * some or all of its sub-properties. The expansion is not recursive.
- *
- * @param propertyId
- * property id for the property whose sub-properties are to be
- * expanded,
- * @param subPropertyIds
- * sub-properties to expand, all sub-properties are expanded if
- * not specified
- */
- public void expandProperty(String propertyId, String... subPropertyIds) {
- Set<String> subPropertySet = new HashSet<String>(
- Arrays.asList(subPropertyIds));
-
- if (0 == subPropertyIds.length) {
- // Enumerate all sub-properties
- Class<?> propertyType = getItemProperty(propertyId).getType();
- Map<String, ?> pds = getPropertyDescriptors(propertyType);
- subPropertySet.addAll(pds.keySet());
- }
-
- for (String subproperty : subPropertySet) {
- String qualifiedPropertyId = propertyId + "." + subproperty;
- addNestedProperty(qualifiedPropertyId);
- }
-
- removeItemProperty(propertyId);
- }
-
- /**
- * Adds a nested property to the item.
- *
- * @param nestedPropertyId
- * property id to add. This property must not exist in the item
- * already and must of of form "field1.field2" where field2 is a
- * field in the object referenced to by field1
- */
- public void addNestedProperty(String nestedPropertyId) {
- addItemProperty(nestedPropertyId, new NestedMethodProperty<Object>(
- getBean(), nestedPropertyId));
- }
-
- /**
- * Gets the underlying JavaBean object.
- *
- * @return the bean object.
- */
- public BT getBean() {
- return bean;
- }
-
-}
diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java
deleted file mode 100644
index dc4deaebdc..0000000000
--- a/src/com/vaadin/data/util/BeanItemContainer.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.Collection;
-
-/**
- * An in-memory container for JavaBeans.
- *
- * <p>
- * The properties of the container are determined automatically by introspecting
- * the used JavaBean class. Only beans of the same type can be added to the
- * container.
- * </p>
- *
- * <p>
- * BeanItemContainer uses the beans themselves as identifiers. The
- * {@link Object#hashCode()} of a bean is used when storing and looking up beans
- * so it must not change during the lifetime of the bean (it should not depend
- * on any part of the bean that can be modified). Typically this restricts the
- * implementation of {@link Object#equals(Object)} as well in order for it to
- * fulfill the contract between {@code equals()} and {@code hashCode()}.
- * </p>
- *
- * <p>
- * To add items to the container, use the methods {@link #addBean(Object)},
- * {@link #addBeanAfter(Object, Object)} and {@link #addBeanAt(int, Object)}.
- * Also {@link #addItem(Object)}, {@link #addItemAfter(Object, Object)} and
- * {@link #addItemAt(int, Object)} can be used as synonyms for them.
- * </p>
- *
- * <p>
- * It is not possible to add additional properties to the container and nested
- * bean properties are not supported.
- * </p>
- *
- * @param <BEANTYPE>
- * The type of the Bean
- *
- * @since 5.4
- */
-@SuppressWarnings("serial")
-public class BeanItemContainer<BEANTYPE> extends
- AbstractBeanContainer<BEANTYPE, BEANTYPE> {
-
- /**
- * Bean identity resolver that returns the bean itself as its item
- * identifier.
- *
- * This corresponds to the old behavior of {@link BeanItemContainer}, and
- * requires suitable (identity-based) equals() and hashCode() methods on the
- * beans.
- *
- * @param <BT>
- *
- * @since 6.5
- */
- private static class IdentityBeanIdResolver<BT> implements
- BeanIdResolver<BT, BT> {
-
- @Override
- public BT getIdForBean(BT bean) {
- return bean;
- }
-
- }
-
- /**
- * Constructs a {@code BeanItemContainer} for beans of the given type.
- *
- * @param type
- * the type of the beans that will be added to the container.
- * @throws IllegalArgumentException
- * If {@code type} is null
- */
- public BeanItemContainer(Class<? super BEANTYPE> type)
- throws IllegalArgumentException {
- super(type);
- super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>());
- }
-
- /**
- * Constructs a {@code BeanItemContainer} and adds the given beans to it.
- * The collection must not be empty.
- * {@link BeanItemContainer#BeanItemContainer(Class)} can be used for
- * creating an initially empty {@code BeanItemContainer}.
- *
- * Note that when using this constructor, the actual class of the first item
- * in the collection is used to determine the bean properties supported by
- * the container instance, and only beans of that class or its subclasses
- * can be added to the collection. If this is problematic or empty
- * collections need to be supported, use {@link #BeanItemContainer(Class)}
- * and {@link #addAll(Collection)} instead.
- *
- * @param collection
- * a non empty {@link Collection} of beans.
- * @throws IllegalArgumentException
- * If the collection is null or empty.
- *
- * @deprecated use {@link #BeanItemContainer(Class, Collection)} instead
- */
- @SuppressWarnings("unchecked")
- @Deprecated
- public BeanItemContainer(Collection<? extends BEANTYPE> collection)
- throws IllegalArgumentException {
- // must assume the class is BT
- // the class information is erased by the compiler
- this((Class<BEANTYPE>) getBeanClassForCollection(collection),
- collection);
- }
-
- /**
- * Internal helper method to support the deprecated {@link Collection}
- * container.
- *
- * @param <BT>
- * @param collection
- * @return
- * @throws IllegalArgumentException
- */
- @SuppressWarnings("unchecked")
- @Deprecated
- private static <BT> Class<? extends BT> getBeanClassForCollection(
- Collection<? extends BT> collection)
- throws IllegalArgumentException {
- if (collection == null || collection.isEmpty()) {
- throw new IllegalArgumentException(
- "The collection passed to BeanItemContainer constructor must not be null or empty. Use the other BeanItemContainer constructor.");
- }
- return (Class<? extends BT>) collection.iterator().next().getClass();
- }
-
- /**
- * Constructs a {@code BeanItemContainer} and adds the given beans to it.
- *
- * @param type
- * the type of the beans that will be added to the container.
- * @param collection
- * a {@link Collection} of beans (can be empty or null).
- * @throws IllegalArgumentException
- * If {@code type} is null
- */
- public BeanItemContainer(Class<? super BEANTYPE> type,
- Collection<? extends BEANTYPE> collection)
- throws IllegalArgumentException {
- super(type);
- super.setBeanIdResolver(new IdentityBeanIdResolver<BEANTYPE>());
-
- if (collection != null) {
- addAll(collection);
- }
- }
-
- /**
- * Adds all the beans from a {@link Collection} in one go. More efficient
- * than adding them one by one.
- *
- * @param collection
- * The collection of beans to add. Must not be null.
- */
- @Override
- public void addAll(Collection<? extends BEANTYPE> collection) {
- super.addAll(collection);
- }
-
- /**
- * Adds the bean after the given bean.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @param previousItemId
- * the bean (of type BT) after which to add newItemId
- * @param newItemId
- * the bean (of type BT) to add (not null)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(Object, Object)
- */
- @Override
- @SuppressWarnings("unchecked")
- public BeanItem<BEANTYPE> addItemAfter(Object previousItemId,
- Object newItemId) throws IllegalArgumentException {
- return super.addBeanAfter((BEANTYPE) previousItemId,
- (BEANTYPE) newItemId);
- }
-
- /**
- * Adds a new bean at the given index.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @param index
- * Index at which the bean should be added.
- * @param newItemId
- * The bean to add to the container.
- * @return Returns the new BeanItem or null if the operation fails.
- */
- @Override
- @SuppressWarnings("unchecked")
- public BeanItem<BEANTYPE> addItemAt(int index, Object newItemId)
- throws IllegalArgumentException {
- return super.addBeanAt(index, (BEANTYPE) newItemId);
- }
-
- /**
- * Adds the bean to the Container.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @see com.vaadin.data.Container#addItem(Object)
- */
- @Override
- @SuppressWarnings("unchecked")
- public BeanItem<BEANTYPE> addItem(Object itemId) {
- return super.addBean((BEANTYPE) itemId);
- }
-
- /**
- * Adds the bean to the Container.
- *
- * The bean is used both as the item contents and as the item identifier.
- *
- * @see com.vaadin.data.Container#addItem(Object)
- */
- @Override
- public BeanItem<BEANTYPE> addBean(BEANTYPE bean) {
- return addItem(bean);
- }
-
- /**
- * Unsupported in BeanItemContainer.
- */
- @Override
- protected void setBeanIdResolver(
- AbstractBeanContainer.BeanIdResolver<BEANTYPE, BEANTYPE> beanIdResolver)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "BeanItemContainer always uses an IdentityBeanIdResolver");
- }
-
-}
diff --git a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
deleted file mode 100644
index 717ce834cf..0000000000
--- a/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * <p>
- * A wrapper class for adding external hierarchy to containers not implementing
- * the {@link com.vaadin.data.Container.Hierarchical} interface.
- * </p>
- *
- * <p>
- * If the wrapped container is changed directly (that is, not through the
- * wrapper), and does not implement Container.ItemSetChangeNotifier and/or
- * Container.PropertySetChangeNotifier the hierarchy information must be updated
- * with the {@link #updateHierarchicalWrapper()} method.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ContainerHierarchicalWrapper implements Container.Hierarchical,
- Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier {
-
- /** The wrapped container */
- private final Container container;
-
- /** Set of IDs of those contained Items that can't have children. */
- private HashSet<Object> noChildrenAllowed = null;
-
- /** Mapping from Item ID to parent Item ID */
- private Hashtable<Object, Object> parent = null;
-
- /** Mapping from Item ID to a list of child IDs */
- private Hashtable<Object, LinkedList<Object>> children = null;
-
- /** List that contains all root elements of the container. */
- private LinkedHashSet<Object> roots = null;
-
- /** Is the wrapped container hierarchical by itself ? */
- private boolean hierarchical;
-
- /**
- * A comparator that sorts the listed items before other items. Otherwise,
- * the order is undefined.
- */
- private static class ListedItemsFirstComparator implements
- Comparator<Object>, Serializable {
- private final Collection<?> itemIds;
-
- private ListedItemsFirstComparator(Collection<?> itemIds) {
- this.itemIds = itemIds;
- }
-
- @Override
- public int compare(Object o1, Object o2) {
- if (o1.equals(o2)) {
- return 0;
- }
- for (Object id : itemIds) {
- if (id == o1) {
- return -1;
- } else if (id == o2) {
- return 1;
- }
- }
- return 0;
- }
- };
-
- /**
- * Constructs a new hierarchical wrapper for an existing Container. Works
- * even if the to-be-wrapped container already implements the
- * <code>Container.Hierarchical</code> interface.
- *
- * @param toBeWrapped
- * the container that needs to be accessed hierarchically
- * @see #updateHierarchicalWrapper()
- */
- public ContainerHierarchicalWrapper(Container toBeWrapped) {
-
- container = toBeWrapped;
- hierarchical = container instanceof Container.Hierarchical;
-
- // Check arguments
- if (container == null) {
- throw new NullPointerException("Null can not be wrapped");
- }
-
- // Create initial order if needed
- if (!hierarchical) {
- noChildrenAllowed = new HashSet<Object>();
- parent = new Hashtable<Object, Object>();
- children = new Hashtable<Object, LinkedList<Object>>();
- roots = new LinkedHashSet<Object>(container.getItemIds());
- }
-
- updateHierarchicalWrapper();
-
- }
-
- /**
- * Updates the wrapper's internal hierarchy data to include all Items in the
- * underlying container. If the contents of the wrapped container change
- * without the wrapper's knowledge, this method needs to be called to update
- * the hierarchy information of the Items.
- */
- public void updateHierarchicalWrapper() {
-
- if (!hierarchical) {
-
- // Recreate hierarchy and data structures if missing
- if (noChildrenAllowed == null || parent == null || children == null
- || roots == null) {
- noChildrenAllowed = new HashSet<Object>();
- parent = new Hashtable<Object, Object>();
- children = new Hashtable<Object, LinkedList<Object>>();
- roots = new LinkedHashSet<Object>(container.getItemIds());
- }
-
- // Check that the hierarchy is up-to-date
- else {
-
- // ensure order of root and child lists is same as in wrapped
- // container
- Collection<?> itemIds = container.getItemIds();
- Comparator<Object> basedOnOrderFromWrappedContainer = new ListedItemsFirstComparator(
- itemIds);
-
- // Calculate the set of all items in the hierarchy
- final HashSet<Object> s = new HashSet<Object>();
- s.addAll(parent.keySet());
- s.addAll(children.keySet());
- s.addAll(roots);
-
- // Remove unnecessary items
- for (final Iterator<Object> i = s.iterator(); i.hasNext();) {
- final Object id = i.next();
- if (!container.containsId(id)) {
- removeFromHierarchyWrapper(id);
- }
- }
-
- // Add all the missing items
- final Collection<?> ids = container.getItemIds();
- for (final Iterator<?> i = ids.iterator(); i.hasNext();) {
- final Object id = i.next();
- if (!s.contains(id)) {
- addToHierarchyWrapper(id);
- s.add(id);
- }
- }
-
- Object[] array = roots.toArray();
- Arrays.sort(array, basedOnOrderFromWrappedContainer);
- roots = new LinkedHashSet<Object>();
- for (int i = 0; i < array.length; i++) {
- roots.add(array[i]);
- }
- for (Object object : children.keySet()) {
- LinkedList<Object> object2 = children.get(object);
- Collections.sort(object2, basedOnOrderFromWrappedContainer);
- }
-
- }
- }
- }
-
- /**
- * Removes the specified Item from the wrapper's internal hierarchy
- * structure.
- * <p>
- * Note : The Item is not removed from the underlying Container.
- * </p>
- *
- * @param itemId
- * the ID of the item to remove from the hierarchy.
- */
- private void removeFromHierarchyWrapper(Object itemId) {
-
- LinkedList<Object> oprhanedChildren = children.remove(itemId);
- if (oprhanedChildren != null) {
- for (Object object : oprhanedChildren) {
- // make orphaned children root nodes
- setParent(object, null);
- }
- }
-
- roots.remove(itemId);
- final Object p = parent.get(itemId);
- if (p != null) {
- final LinkedList<Object> c = children.get(p);
- if (c != null) {
- c.remove(itemId);
- }
- }
- parent.remove(itemId);
- noChildrenAllowed.remove(itemId);
- }
-
- /**
- * Adds the specified Item specified to the internal hierarchy structure.
- * The new item is added as a root Item. The underlying container is not
- * modified.
- *
- * @param itemId
- * the ID of the item to add to the hierarchy.
- */
- private void addToHierarchyWrapper(Object itemId) {
- roots.add(itemId);
-
- }
-
- /*
- * Can the specified Item have any children? Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public boolean areChildrenAllowed(Object itemId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container)
- .areChildrenAllowed(itemId);
- }
-
- if (noChildrenAllowed.contains(itemId)) {
- return false;
- }
-
- return containsId(itemId);
- }
-
- /*
- * Gets the IDs of the children of the specified Item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getChildren(Object itemId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).getChildren(itemId);
- }
-
- final Collection<?> c = children.get(itemId);
- if (c == null) {
- return null;
- }
- return Collections.unmodifiableCollection(c);
- }
-
- /*
- * Gets the ID of the parent of the specified Item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object getParent(Object itemId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).getParent(itemId);
- }
-
- return parent.get(itemId);
- }
-
- /*
- * Is the Item corresponding to the given ID a leaf node? Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean hasChildren(Object itemId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).hasChildren(itemId);
- }
-
- LinkedList<Object> list = children.get(itemId);
- return (list != null && !list.isEmpty());
- }
-
- /*
- * Is the Item corresponding to the given ID a root node? Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean isRoot(Object itemId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).isRoot(itemId);
- }
-
- if (parent.containsKey(itemId)) {
- return false;
- }
-
- return containsId(itemId);
- }
-
- /*
- * Gets the IDs of the root elements in the container. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> rootItemIds() {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).rootItemIds();
- }
-
- return Collections.unmodifiableCollection(roots);
- }
-
- /**
- * <p>
- * Sets the given Item's capability to have children. If the Item identified
- * with the itemId already has children and the areChildrenAllowed is false
- * this method fails and <code>false</code> is returned; the children must
- * be first explicitly removed with
- * {@link #setParent(Object itemId, Object newParentId)} or
- * {@link com.vaadin.data.Container#removeItem(Object itemId)}.
- * </p>
- *
- * @param itemId
- * the ID of the Item in the container whose child capability is
- * to be set.
- * @param childrenAllowed
- * the boolean value specifying if the Item can have children or
- * not.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).setChildrenAllowed(
- itemId, childrenAllowed);
- }
-
- // Check that the item is in the container
- if (!containsId(itemId)) {
- return false;
- }
-
- // Update status
- if (childrenAllowed) {
- noChildrenAllowed.remove(itemId);
- } else {
- noChildrenAllowed.add(itemId);
- }
-
- return true;
- }
-
- /**
- * <p>
- * Sets the parent of an Item. The new parent item must exist and be able to
- * have children. (<code>canHaveChildren(newParentId) == true</code>). It is
- * also possible to detach a node from the hierarchy (and thus make it root)
- * by setting the parent <code>null</code>.
- * </p>
- *
- * @param itemId
- * the ID of the item to be set as the child of the Item
- * identified with newParentId.
- * @param newParentId
- * the ID of the Item that's to be the new parent of the Item
- * identified with itemId.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean setParent(Object itemId, Object newParentId) {
-
- // If the wrapped container implements the method directly, use it
- if (hierarchical) {
- return ((Container.Hierarchical) container).setParent(itemId,
- newParentId);
- }
-
- // Check that the item is in the container
- if (!containsId(itemId)) {
- return false;
- }
-
- // Get the old parent
- final Object oldParentId = parent.get(itemId);
-
- // Check if no change is necessary
- if ((newParentId == null && oldParentId == null)
- || (newParentId != null && newParentId.equals(oldParentId))) {
- return true;
- }
-
- // Making root
- if (newParentId == null) {
-
- // Remove from old parents children list
- final LinkedList<Object> l = children.get(oldParentId);
- if (l != null) {
- l.remove(itemId);
- if (l.isEmpty()) {
- children.remove(itemId);
- }
- }
-
- // Add to be a root
- roots.add(itemId);
-
- // Update parent
- parent.remove(itemId);
-
- return true;
- }
-
- // Check that the new parent exists in container and can have
- // children
- if (!containsId(newParentId) || noChildrenAllowed.contains(newParentId)) {
- return false;
- }
-
- // Check that setting parent doesn't result to a loop
- Object o = newParentId;
- while (o != null && !o.equals(itemId)) {
- o = parent.get(o);
- }
- if (o != null) {
- return false;
- }
-
- // Update parent
- parent.put(itemId, newParentId);
- LinkedList<Object> pcl = children.get(newParentId);
- if (pcl == null) {
- pcl = new LinkedList<Object>();
- children.put(newParentId, pcl);
- }
- pcl.add(itemId);
-
- // Remove from old parent or root
- if (oldParentId == null) {
- roots.remove(itemId);
- } else {
- final LinkedList<Object> l = children.get(oldParentId);
- if (l != null) {
- l.remove(itemId);
- if (l.isEmpty()) {
- children.remove(oldParentId);
- }
- }
- }
-
- return true;
- }
-
- /**
- * Creates a new Item into the Container, assigns it an automatic ID, and
- * adds it to the hierarchy.
- *
- * @return the autogenerated ID of the new Item or <code>null</code> if the
- * operation failed
- * @throws UnsupportedOperationException
- * if the addItem is not supported.
- */
- @Override
- public Object addItem() throws UnsupportedOperationException {
-
- final Object id = container.addItem();
- if (!hierarchical && id != null) {
- addToHierarchyWrapper(id);
- }
- return id;
- }
-
- /**
- * Adds a new Item by its ID to the underlying container and to the
- * hierarchy.
- *
- * @param itemId
- * the ID of the Item to be created.
- * @return the added Item or <code>null</code> if the operation failed.
- * @throws UnsupportedOperationException
- * if the addItem is not supported.
- */
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
-
- // Null ids are not accepted
- if (itemId == null) {
- throw new NullPointerException("Container item id can not be null");
- }
-
- final Item item = container.addItem(itemId);
- if (!hierarchical && item != null) {
- addToHierarchyWrapper(itemId);
- }
- return item;
- }
-
- /**
- * Removes all items from the underlying container and from the hierarcy.
- *
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the removeAllItems is not supported.
- */
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
-
- final boolean success = container.removeAllItems();
-
- if (!hierarchical && success) {
- roots.clear();
- parent.clear();
- children.clear();
- noChildrenAllowed.clear();
- }
- return success;
- }
-
- /**
- * Removes an Item specified by the itemId from the underlying container and
- * from the hierarchy.
- *
- * @param itemId
- * the ID of the Item to be removed.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the removeItem is not supported.
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
-
- final boolean success = container.removeItem(itemId);
-
- if (!hierarchical && success) {
- removeFromHierarchyWrapper(itemId);
- }
-
- return success;
- }
-
- /**
- * Removes the Item identified by given itemId and all its children.
- *
- * @see #removeItem(Object)
- * @param itemId
- * the identifier of the Item to be removed
- * @return true if the operation succeeded
- */
- public boolean removeItemRecursively(Object itemId) {
- return HierarchicalContainer.removeItemRecursively(this, itemId);
- }
-
- /**
- * Adds a new Property to all Items in the Container.
- *
- * @param propertyId
- * the ID of the new Property.
- * @param type
- * the Data type of the new Property.
- * @param defaultValue
- * the value all created Properties are initialized to.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the addContainerProperty is not supported.
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
-
- return container.addContainerProperty(propertyId, type, defaultValue);
- }
-
- /**
- * Removes the specified Property from the underlying container and from the
- * hierarchy.
- * <p>
- * Note : The Property will be removed from all Items in the Container.
- * </p>
- *
- * @param propertyId
- * the ID of the Property to remove.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the removeContainerProperty is not supported.
- */
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- return container.removeContainerProperty(propertyId);
- }
-
- /*
- * Does the container contain the specified Item? Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean containsId(Object itemId) {
- return container.containsId(itemId);
- }
-
- /*
- * Gets the specified Item from the container. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Item getItem(Object itemId) {
- return container.getItem(itemId);
- }
-
- /*
- * Gets the ID's of all Items stored in the Container Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getItemIds() {
- return container.getItemIds();
- }
-
- /*
- * Gets the Property identified by the given itemId and propertyId from the
- * Container Don't add a JavaDoc comment here, we use the default
- * documentation from implemented interface.
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- return container.getContainerProperty(itemId, propertyId);
- }
-
- /*
- * Gets the ID's of all Properties stored in the Container Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getContainerPropertyIds() {
- return container.getContainerPropertyIds();
- }
-
- /*
- * Gets the data type of all Properties identified by the given Property ID.
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public Class<?> getType(Object propertyId) {
- return container.getType(propertyId);
- }
-
- /*
- * Gets the number of Items in the Container. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public int size() {
- return container.size();
- }
-
- /*
- * Registers a new Item set change listener for this Container. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void addListener(Container.ItemSetChangeListener listener) {
- if (container instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) container)
- .addListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Removes a Item set change listener from the object. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Container.ItemSetChangeListener listener) {
- if (container instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) container)
- .removeListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Registers a new Property set change listener for this Container. Don't
- * add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void addListener(Container.PropertySetChangeListener listener) {
- if (container instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) container)
- .addListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Removes a Property set change listener from the object. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Container.PropertySetChangeListener listener) {
- if (container instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) container)
- .removeListener(new PiggybackListener(listener));
- }
- }
-
- /**
- * This listener 'piggybacks' on the real listener in order to update the
- * wrapper when needed. It proxies equals() and hashCode() to the real
- * listener so that the correct listener gets removed.
- *
- */
- private class PiggybackListener implements
- Container.PropertySetChangeListener,
- Container.ItemSetChangeListener {
-
- Object listener;
-
- public PiggybackListener(Object realListener) {
- listener = realListener;
- }
-
- @Override
- public void containerItemSetChange(ItemSetChangeEvent event) {
- updateHierarchicalWrapper();
- ((Container.ItemSetChangeListener) listener)
- .containerItemSetChange(event);
-
- }
-
- @Override
- public void containerPropertySetChange(PropertySetChangeEvent event) {
- updateHierarchicalWrapper();
- ((Container.PropertySetChangeListener) listener)
- .containerPropertySetChange(event);
-
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj == listener || (obj != null && obj.equals(listener));
- }
-
- @Override
- public int hashCode() {
- return listener.hashCode();
- }
-
- }
-}
diff --git a/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/src/com/vaadin/data/util/ContainerOrderedWrapper.java
deleted file mode 100644
index d3d6f88d3e..0000000000
--- a/src/com/vaadin/data/util/ContainerOrderedWrapper.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.util.Collection;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * <p>
- * A wrapper class for adding external ordering to containers not implementing
- * the {@link com.vaadin.data.Container.Ordered} interface.
- * </p>
- *
- * <p>
- * If the wrapped container is changed directly (that is, not through the
- * wrapper), and does not implement Container.ItemSetChangeNotifier and/or
- * Container.PropertySetChangeNotifier the hierarchy information must be updated
- * with the {@link #updateOrderWrapper()} method.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ContainerOrderedWrapper implements Container.Ordered,
- Container.ItemSetChangeNotifier, Container.PropertySetChangeNotifier {
-
- /**
- * The wrapped container
- */
- private final Container container;
-
- /**
- * Ordering information, ie. the mapping from Item ID to the next item ID
- */
- private Hashtable<Object, Object> next;
-
- /**
- * Reverse ordering information for convenience and performance reasons.
- */
- private Hashtable<Object, Object> prev;
-
- /**
- * ID of the first Item in the container.
- */
- private Object first;
-
- /**
- * ID of the last Item in the container.
- */
- private Object last;
-
- /**
- * Is the wrapped container ordered by itself, ie. does it implement the
- * Container.Ordered interface by itself? If it does, this class will use
- * the methods of the underlying container directly.
- */
- private boolean ordered = false;
-
- /**
- * The last known size of the wrapped container. Used to check whether items
- * have been added or removed to the wrapped container, when the wrapped
- * container does not send ItemSetChangeEvents.
- */
- private int lastKnownSize = -1;
-
- /**
- * Constructs a new ordered wrapper for an existing Container. Works even if
- * the to-be-wrapped container already implements the Container.Ordered
- * interface.
- *
- * @param toBeWrapped
- * the container whose contents need to be ordered.
- */
- public ContainerOrderedWrapper(Container toBeWrapped) {
-
- container = toBeWrapped;
- ordered = container instanceof Container.Ordered;
-
- // Checks arguments
- if (container == null) {
- throw new NullPointerException("Null can not be wrapped");
- }
-
- // Creates initial order if needed
- updateOrderWrapper();
- }
-
- /**
- * Removes the specified Item from the wrapper's internal hierarchy
- * structure.
- * <p>
- * Note : The Item is not removed from the underlying Container.
- * </p>
- *
- * @param id
- * the ID of the Item to be removed from the ordering.
- */
- private void removeFromOrderWrapper(Object id) {
- if (id != null) {
- final Object pid = prev.get(id);
- final Object nid = next.get(id);
- if (first.equals(id)) {
- first = nid;
- }
- if (last.equals(id)) {
- first = pid;
- }
- if (nid != null) {
- prev.put(nid, pid);
- }
- if (pid != null) {
- next.put(pid, nid);
- }
- next.remove(id);
- prev.remove(id);
- }
- }
-
- /**
- * Registers the specified Item to the last position in the wrapper's
- * internal ordering. The underlying container is not modified.
- *
- * @param id
- * the ID of the Item to be added to the ordering.
- */
- private void addToOrderWrapper(Object id) {
-
- // Adds the if to tail
- if (last != null) {
- next.put(last, id);
- prev.put(id, last);
- last = id;
- } else {
- first = last = id;
- }
- }
-
- /**
- * Registers the specified Item after the specified itemId in the wrapper's
- * internal ordering. The underlying container is not modified. Given item
- * id must be in the container, or must be null.
- *
- * @param id
- * the ID of the Item to be added to the ordering.
- * @param previousItemId
- * the Id of the previous item.
- */
- private void addToOrderWrapper(Object id, Object previousItemId) {
-
- if (last == previousItemId || last == null) {
- addToOrderWrapper(id);
- } else {
- if (previousItemId == null) {
- next.put(id, first);
- prev.put(first, id);
- first = id;
- } else {
- prev.put(id, previousItemId);
- next.put(id, next.get(previousItemId));
- prev.put(next.get(previousItemId), id);
- next.put(previousItemId, id);
- }
- }
- }
-
- /**
- * Updates the wrapper's internal ordering information to include all Items
- * in the underlying container.
- * <p>
- * Note : If the contents of the wrapped container change without the
- * wrapper's knowledge, this method needs to be called to update the
- * ordering information of the Items.
- * </p>
- */
- public void updateOrderWrapper() {
-
- if (!ordered) {
-
- final Collection<?> ids = container.getItemIds();
-
- // Recreates ordering if some parts of it are missing
- if (next == null || first == null || last == null || prev != null) {
- first = null;
- last = null;
- next = new Hashtable<Object, Object>();
- prev = new Hashtable<Object, Object>();
- }
-
- // Filter out all the missing items
- final LinkedList<?> l = new LinkedList<Object>(next.keySet());
- for (final Iterator<?> i = l.iterator(); i.hasNext();) {
- final Object id = i.next();
- if (!container.containsId(id)) {
- removeFromOrderWrapper(id);
- }
- }
-
- // Adds missing items
- for (final Iterator<?> i = ids.iterator(); i.hasNext();) {
- final Object id = i.next();
- if (!next.containsKey(id)) {
- addToOrderWrapper(id);
- }
- }
- }
- }
-
- /*
- * Gets the first item stored in the ordered container Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object firstItemId() {
- if (ordered) {
- return ((Container.Ordered) container).firstItemId();
- }
- return first;
- }
-
- /*
- * Tests if the given item is the first item in the container Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean isFirstId(Object itemId) {
- if (ordered) {
- return ((Container.Ordered) container).isFirstId(itemId);
- }
- return first != null && first.equals(itemId);
- }
-
- /*
- * Tests if the given item is the last item in the container Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean isLastId(Object itemId) {
- if (ordered) {
- return ((Container.Ordered) container).isLastId(itemId);
- }
- return last != null && last.equals(itemId);
- }
-
- /*
- * Gets the last item stored in the ordered container Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object lastItemId() {
- if (ordered) {
- return ((Container.Ordered) container).lastItemId();
- }
- return last;
- }
-
- /*
- * Gets the item that is next from the specified item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object nextItemId(Object itemId) {
- if (ordered) {
- return ((Container.Ordered) container).nextItemId(itemId);
- }
- if (itemId == null) {
- return null;
- }
- return next.get(itemId);
- }
-
- /*
- * Gets the item that is previous from the specified item. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object prevItemId(Object itemId) {
- if (ordered) {
- return ((Container.Ordered) container).prevItemId(itemId);
- }
- if (itemId == null) {
- return null;
- }
- return prev.get(itemId);
- }
-
- /**
- * Registers a new Property to all Items in the Container.
- *
- * @param propertyId
- * the ID of the new Property.
- * @param type
- * the Data type of the new Property.
- * @param defaultValue
- * the value all created Properties are initialized to.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
-
- return container.addContainerProperty(propertyId, type, defaultValue);
- }
-
- /**
- * Creates a new Item into the Container, assigns it an automatic ID, and
- * adds it to the ordering.
- *
- * @return the autogenerated ID of the new Item or <code>null</code> if the
- * operation failed
- * @throws UnsupportedOperationException
- * if the addItem is not supported.
- */
- @Override
- public Object addItem() throws UnsupportedOperationException {
-
- final Object id = container.addItem();
- if (!ordered && id != null) {
- addToOrderWrapper(id);
- }
- return id;
- }
-
- /**
- * Registers a new Item by its ID to the underlying container and to the
- * ordering.
- *
- * @param itemId
- * the ID of the Item to be created.
- * @return the added Item or <code>null</code> if the operation failed
- * @throws UnsupportedOperationException
- * if the addItem is not supported.
- */
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
- final Item item = container.addItem(itemId);
- if (!ordered && item != null) {
- addToOrderWrapper(itemId);
- }
- return item;
- }
-
- /**
- * Removes all items from the underlying container and from the ordering.
- *
- * @return <code>true</code> if the operation succeeded, otherwise
- * <code>false</code>
- * @throws UnsupportedOperationException
- * if the removeAllItems is not supported.
- */
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
- final boolean success = container.removeAllItems();
- if (!ordered && success) {
- first = last = null;
- next.clear();
- prev.clear();
- }
- return success;
- }
-
- /**
- * Removes an Item specified by the itemId from the underlying container and
- * from the ordering.
- *
- * @param itemId
- * the ID of the Item to be removed.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the removeItem is not supported.
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
-
- final boolean success = container.removeItem(itemId);
- if (!ordered && success) {
- removeFromOrderWrapper(itemId);
- }
- return success;
- }
-
- /**
- * Removes the specified Property from the underlying container and from the
- * ordering.
- * <p>
- * Note : The Property will be removed from all the Items in the Container.
- * </p>
- *
- * @param propertyId
- * the ID of the Property to remove.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- * @throws UnsupportedOperationException
- * if the removeContainerProperty is not supported.
- */
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- return container.removeContainerProperty(propertyId);
- }
-
- /*
- * Does the container contain the specified Item? Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean containsId(Object itemId) {
- return container.containsId(itemId);
- }
-
- /*
- * Gets the specified Item from the container. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Item getItem(Object itemId) {
- return container.getItem(itemId);
- }
-
- /*
- * Gets the ID's of all Items stored in the Container Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getItemIds() {
- return container.getItemIds();
- }
-
- /*
- * Gets the Property identified by the given itemId and propertyId from the
- * Container Don't add a JavaDoc comment here, we use the default
- * documentation from implemented interface.
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- return container.getContainerProperty(itemId, propertyId);
- }
-
- /*
- * Gets the ID's of all Properties stored in the Container Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getContainerPropertyIds() {
- return container.getContainerPropertyIds();
- }
-
- /*
- * Gets the data type of all Properties identified by the given Property ID.
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public Class<?> getType(Object propertyId) {
- return container.getType(propertyId);
- }
-
- /*
- * Gets the number of Items in the Container. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public int size() {
- int newSize = container.size();
- if (lastKnownSize != -1 && newSize != lastKnownSize
- && !(container instanceof Container.ItemSetChangeNotifier)) {
- // Update the internal cache when the size of the container changes
- // and the container is incapable of sending ItemSetChangeEvents
- updateOrderWrapper();
- }
- lastKnownSize = newSize;
- return newSize;
- }
-
- /*
- * Registers a new Item set change listener for this Container. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void addListener(Container.ItemSetChangeListener listener) {
- if (container instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) container)
- .addListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Removes a Item set change listener from the object. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Container.ItemSetChangeListener listener) {
- if (container instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) container)
- .removeListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Registers a new Property set change listener for this Container. Don't
- * add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void addListener(Container.PropertySetChangeListener listener) {
- if (container instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) container)
- .addListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * Removes a Property set change listener from the object. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Container.PropertySetChangeListener listener) {
- if (container instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) container)
- .removeListener(new PiggybackListener(listener));
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException {
-
- // If the previous item is not in the container, fail
- if (previousItemId != null && !containsId(previousItemId)) {
- return null;
- }
-
- // Adds the item to container
- final Item item = container.addItem(newItemId);
-
- // Puts the new item to its correct place
- if (!ordered && item != null) {
- addToOrderWrapper(newItemId, previousItemId);
- }
-
- return item;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
- */
- @Override
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException {
-
- // If the previous item is not in the container, fail
- if (previousItemId != null && !containsId(previousItemId)) {
- return null;
- }
-
- // Adds the item to container
- final Object id = container.addItem();
-
- // Puts the new item to its correct place
- if (!ordered && id != null) {
- addToOrderWrapper(id, previousItemId);
- }
-
- return id;
- }
-
- /**
- * This listener 'piggybacks' on the real listener in order to update the
- * wrapper when needed. It proxies equals() and hashCode() to the real
- * listener so that the correct listener gets removed.
- *
- */
- private class PiggybackListener implements
- Container.PropertySetChangeListener,
- Container.ItemSetChangeListener {
-
- Object listener;
-
- public PiggybackListener(Object realListener) {
- listener = realListener;
- }
-
- @Override
- public void containerItemSetChange(ItemSetChangeEvent event) {
- updateOrderWrapper();
- ((Container.ItemSetChangeListener) listener)
- .containerItemSetChange(event);
-
- }
-
- @Override
- public void containerPropertySetChange(PropertySetChangeEvent event) {
- updateOrderWrapper();
- ((Container.PropertySetChangeListener) listener)
- .containerPropertySetChange(event);
-
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj == listener || (obj != null && obj.equals(listener));
- }
-
- @Override
- public int hashCode() {
- return listener.hashCode();
- }
-
- }
-
-}
diff --git a/src/com/vaadin/data/util/DefaultItemSorter.java b/src/com/vaadin/data/util/DefaultItemSorter.java
deleted file mode 100644
index 81b15ebd4f..0000000000
--- a/src/com/vaadin/data/util/DefaultItemSorter.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Container.Sortable;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * Provides a default implementation of an ItemSorter. The
- * <code>DefaultItemSorter</code> adheres to the
- * {@link Sortable#sort(Object[], boolean[])} rules and sorts the container
- * according to the properties given using
- * {@link #setSortProperties(Sortable, Object[], boolean[])}.
- * <p>
- * A Comparator is used for comparing the individual <code>Property</code>
- * values. The comparator can be set using the constructor. If no comparator is
- * provided a default comparator is used.
- *
- */
-public class DefaultItemSorter implements ItemSorter {
-
- private java.lang.Object[] sortPropertyIds;
- private boolean[] sortDirections;
- private Container container;
- private Comparator<Object> propertyValueComparator;
-
- /**
- * Constructs a DefaultItemSorter using the default <code>Comparator</code>
- * for comparing <code>Property</code>values.
- *
- */
- public DefaultItemSorter() {
- this(new DefaultPropertyValueComparator());
- }
-
- /**
- * Constructs a DefaultItemSorter which uses the <code>Comparator</code>
- * indicated by the <code>propertyValueComparator</code> parameter for
- * comparing <code>Property</code>values.
- *
- * @param propertyValueComparator
- * The comparator to use when comparing individual
- * <code>Property</code> values
- */
- public DefaultItemSorter(Comparator<Object> propertyValueComparator) {
- this.propertyValueComparator = propertyValueComparator;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.ItemSorter#compare(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public int compare(Object o1, Object o2) {
- Item item1 = container.getItem(o1);
- Item item2 = container.getItem(o2);
-
- /*
- * Items can be null if the container is filtered. Null is considered
- * "less" than not-null.
- */
- if (item1 == null) {
- if (item2 == null) {
- return 0;
- } else {
- return 1;
- }
- } else if (item2 == null) {
- return -1;
- }
-
- for (int i = 0; i < sortPropertyIds.length; i++) {
-
- int result = compareProperty(sortPropertyIds[i], sortDirections[i],
- item1, item2);
-
- // If order can be decided
- if (result != 0) {
- return result;
- }
-
- }
-
- return 0;
- }
-
- /**
- * Compares the property indicated by <code>propertyId</code> in the items
- * indicated by <code>item1</code> and <code>item2</code> for order. Returns
- * a negative integer, zero, or a positive integer as the property value in
- * the first item is less than, equal to, or greater than the property value
- * in the second item. If the <code>sortDirection</code> is false the
- * returned value is negated.
- * <p>
- * The comparator set for this <code>DefaultItemSorter</code> is used for
- * comparing the two property values.
- *
- * @param propertyId
- * The property id for the property that is used for comparison.
- * @param sortDirection
- * The direction of the sort. A false value negates the result.
- * @param item1
- * The first item to compare.
- * @param item2
- * The second item to compare.
- * @return a negative, zero, or positive integer if the property value in
- * the first item is less than, equal to, or greater than the
- * property value in the second item. Negated if
- * {@code sortDirection} is false.
- */
- protected int compareProperty(Object propertyId, boolean sortDirection,
- Item item1, Item item2) {
-
- // Get the properties to compare
- final Property<?> property1 = item1.getItemProperty(propertyId);
- final Property<?> property2 = item2.getItemProperty(propertyId);
-
- // Get the values to compare
- final Object value1 = (property1 == null) ? null : property1.getValue();
- final Object value2 = (property2 == null) ? null : property2.getValue();
-
- // Result of the comparison
- int r = 0;
- if (sortDirection) {
- r = propertyValueComparator.compare(value1, value2);
- } else {
- r = propertyValueComparator.compare(value2, value1);
- }
-
- return r;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.ItemSorter#setSortProperties(com.vaadin.data.Container
- * .Sortable, java.lang.Object[], boolean[])
- */
- @Override
- public void setSortProperties(Container.Sortable container,
- Object[] propertyId, boolean[] ascending) {
- this.container = container;
-
- // Removes any non-sortable property ids
- final List<Object> ids = new ArrayList<Object>();
- final List<Boolean> orders = new ArrayList<Boolean>();
- final Collection<?> sortable = container
- .getSortableContainerPropertyIds();
- for (int i = 0; i < propertyId.length; i++) {
- if (sortable.contains(propertyId[i])) {
- ids.add(propertyId[i]);
- orders.add(Boolean.valueOf(i < ascending.length ? ascending[i]
- : true));
- }
- }
-
- sortPropertyIds = ids.toArray();
- sortDirections = new boolean[orders.size()];
- for (int i = 0; i < sortDirections.length; i++) {
- sortDirections[i] = (orders.get(i)).booleanValue();
- }
-
- }
-
- /**
- * Provides a default comparator used for comparing {@link Property} values.
- * The <code>DefaultPropertyValueComparator</code> assumes all objects it
- * compares can be cast to Comparable.
- *
- */
- public static class DefaultPropertyValueComparator implements
- Comparator<Object>, Serializable {
-
- @Override
- @SuppressWarnings("unchecked")
- public int compare(Object o1, Object o2) {
- int r = 0;
- // Normal non-null comparison
- if (o1 != null && o2 != null) {
- // Assume the objects can be cast to Comparable, throw
- // ClassCastException otherwise.
- r = ((Comparable<Object>) o1).compareTo(o2);
- } else if (o1 == o2) {
- // Objects are equal if both are null
- r = 0;
- } else {
- if (o1 == null) {
- r = -1; // null is less than non-null
- } else {
- r = 1; // non-null is greater than null
- }
- }
-
- return r;
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/FilesystemContainer.java b/src/com/vaadin/data/util/FilesystemContainer.java
deleted file mode 100644
index cdfeb57e14..0000000000
--- a/src/com/vaadin/data/util/FilesystemContainer.java
+++ /dev/null
@@ -1,918 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.service.FileTypeResolver;
-import com.vaadin.terminal.Resource;
-
-/**
- * A hierarchical container wrapper for a filesystem.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class FilesystemContainer implements Container.Hierarchical {
-
- /**
- * String identifier of a file's "name" property.
- */
- public static String PROPERTY_NAME = "Name";
-
- /**
- * String identifier of a file's "size" property.
- */
- public static String PROPERTY_SIZE = "Size";
-
- /**
- * String identifier of a file's "icon" property.
- */
- public static String PROPERTY_ICON = "Icon";
-
- /**
- * String identifier of a file's "last modified" property.
- */
- public static String PROPERTY_LASTMODIFIED = "Last Modified";
-
- /**
- * List of the string identifiers for the available properties.
- */
- public static Collection<String> FILE_PROPERTIES;
-
- private final static Method FILEITEM_LASTMODIFIED;
-
- private final static Method FILEITEM_NAME;
-
- private final static Method FILEITEM_ICON;
-
- private final static Method FILEITEM_SIZE;
-
- static {
-
- FILE_PROPERTIES = new ArrayList<String>();
- FILE_PROPERTIES.add(PROPERTY_NAME);
- FILE_PROPERTIES.add(PROPERTY_ICON);
- FILE_PROPERTIES.add(PROPERTY_SIZE);
- FILE_PROPERTIES.add(PROPERTY_LASTMODIFIED);
- FILE_PROPERTIES = Collections.unmodifiableCollection(FILE_PROPERTIES);
- try {
- FILEITEM_LASTMODIFIED = FileItem.class.getMethod("lastModified",
- new Class[] {});
- FILEITEM_NAME = FileItem.class.getMethod("getName", new Class[] {});
- FILEITEM_ICON = FileItem.class.getMethod("getIcon", new Class[] {});
- FILEITEM_SIZE = FileItem.class.getMethod("getSize", new Class[] {});
- } catch (final NoSuchMethodException e) {
- throw new RuntimeException(
- "Internal error finding methods in FilesystemContainer");
- }
- }
-
- private File[] roots = new File[] {};
-
- private FilenameFilter filter = null;
-
- private boolean recursive = true;
-
- /**
- * Constructs a new <code>FileSystemContainer</code> with the specified file
- * as the root of the filesystem. The files are included recursively.
- *
- * @param root
- * the root file for the new file-system container. Null values
- * are ignored.
- */
- public FilesystemContainer(File root) {
- if (root != null) {
- roots = new File[] { root };
- }
- }
-
- /**
- * Constructs a new <code>FileSystemContainer</code> with the specified file
- * as the root of the filesystem. The files are included recursively.
- *
- * @param root
- * the root file for the new file-system container.
- * @param recursive
- * should the container recursively contain subdirectories.
- */
- public FilesystemContainer(File root, boolean recursive) {
- this(root);
- setRecursive(recursive);
- }
-
- /**
- * Constructs a new <code>FileSystemContainer</code> with the specified file
- * as the root of the filesystem.
- *
- * @param root
- * the root file for the new file-system container.
- * @param extension
- * the Filename extension (w/o separator) to limit the files in
- * container.
- * @param recursive
- * should the container recursively contain subdirectories.
- */
- public FilesystemContainer(File root, String extension, boolean recursive) {
- this(root);
- this.setFilter(extension);
- setRecursive(recursive);
- }
-
- /**
- * Constructs a new <code>FileSystemContainer</code> with the specified root
- * and recursivity status.
- *
- * @param root
- * the root file for the new file-system container.
- * @param filter
- * the Filename filter to limit the files in container.
- * @param recursive
- * should the container recursively contain subdirectories.
- */
- public FilesystemContainer(File root, FilenameFilter filter,
- boolean recursive) {
- this(root);
- this.setFilter(filter);
- setRecursive(recursive);
- }
-
- /**
- * Adds new root file directory. Adds a file to be included as root file
- * directory in the <code>FilesystemContainer</code>.
- *
- * @param root
- * the File to be added as root directory. Null values are
- * ignored.
- */
- public void addRoot(File root) {
- if (root != null) {
- final File[] newRoots = new File[roots.length + 1];
- for (int i = 0; i < roots.length; i++) {
- newRoots[i] = roots[i];
- }
- newRoots[roots.length] = root;
- roots = newRoots;
- }
- }
-
- /**
- * Tests if the specified Item in the container may have children. Since a
- * <code>FileSystemContainer</code> contains files and directories, this
- * method returns <code>true</code> for directory Items only.
- *
- * @param itemId
- * the id of the item.
- * @return <code>true</code> if the specified Item is a directory,
- * <code>false</code> otherwise.
- */
- @Override
- public boolean areChildrenAllowed(Object itemId) {
- return itemId instanceof File && ((File) itemId).canRead()
- && ((File) itemId).isDirectory();
- }
-
- /*
- * Gets the ID's of all Items who are children of the specified Item. Don't
- * add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public Collection<File> getChildren(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return Collections.unmodifiableCollection(new LinkedList<File>());
- }
- File[] f;
- if (filter != null) {
- f = ((File) itemId).listFiles(filter);
- } else {
- f = ((File) itemId).listFiles();
- }
-
- if (f == null) {
- return Collections.unmodifiableCollection(new LinkedList<File>());
- }
-
- final List<File> l = Arrays.asList(f);
- Collections.sort(l);
-
- return Collections.unmodifiableCollection(l);
- }
-
- /*
- * Gets the parent item of the specified Item. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Object getParent(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return null;
- }
- return ((File) itemId).getParentFile();
- }
-
- /*
- * Tests if the specified Item has any children. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public boolean hasChildren(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return false;
- }
- String[] l;
- if (filter != null) {
- l = ((File) itemId).list(filter);
- } else {
- l = ((File) itemId).list();
- }
- return (l != null) && (l.length > 0);
- }
-
- /*
- * Tests if the specified Item is the root of the filesystem. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean isRoot(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return false;
- }
- for (int i = 0; i < roots.length; i++) {
- if (roots[i].equals(itemId)) {
- return true;
- }
- }
- return false;
- }
-
- /*
- * Gets the ID's of all root Items in the container. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<File> rootItemIds() {
-
- File[] f;
-
- // in single root case we use children
- if (roots.length == 1) {
- if (filter != null) {
- f = roots[0].listFiles(filter);
- } else {
- f = roots[0].listFiles();
- }
- } else {
- f = roots;
- }
-
- if (f == null) {
- return Collections.unmodifiableCollection(new LinkedList<File>());
- }
-
- final List<File> l = Arrays.asList(f);
- Collections.sort(l);
-
- return Collections.unmodifiableCollection(l);
- }
-
- /**
- * Returns <code>false</code> when conversion from files to directories is
- * not supported.
- *
- * @param itemId
- * the ID of the item.
- * @param areChildrenAllowed
- * the boolean value specifying if the Item can have children or
- * not.
- * @return <code>true</code> if the operaton is successful otherwise
- * <code>false</code>.
- * @throws UnsupportedOperationException
- * if the setChildrenAllowed is not supported.
- */
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
- throws UnsupportedOperationException {
-
- throw new UnsupportedOperationException(
- "Conversion file to/from directory is not supported");
- }
-
- /**
- * Returns <code>false</code> when moving files around in the filesystem is
- * not supported.
- *
- * @param itemId
- * the ID of the item.
- * @param newParentId
- * the ID of the Item that's to be the new parent of the Item
- * identified with itemId.
- * @return <code>true</code> if the operation is successful otherwise
- * <code>false</code>.
- * @throws UnsupportedOperationException
- * if the setParent is not supported.
- */
- @Override
- public boolean setParent(Object itemId, Object newParentId)
- throws UnsupportedOperationException {
-
- throw new UnsupportedOperationException("File moving is not supported");
- }
-
- /*
- * Tests if the filesystem contains the specified Item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean containsId(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return false;
- }
- boolean val = false;
-
- // Try to match all roots
- for (int i = 0; i < roots.length; i++) {
- try {
- val |= ((File) itemId).getCanonicalPath().startsWith(
- roots[i].getCanonicalPath());
- } catch (final IOException e) {
- // Exception ignored
- }
-
- }
- if (val && filter != null) {
- val &= filter.accept(((File) itemId).getParentFile(),
- ((File) itemId).getName());
- }
- return val;
- }
-
- /*
- * Gets the specified Item from the filesystem. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Item getItem(Object itemId) {
-
- if (!(itemId instanceof File)) {
- return null;
- }
- return new FileItem((File) itemId);
- }
-
- /**
- * Internal recursive method to add the files under the specified directory
- * to the collection.
- *
- * @param col
- * the collection where the found items are added
- * @param f
- * the root file where to start adding files
- */
- private void addItemIds(Collection<File> col, File f) {
- File[] l;
- if (filter != null) {
- l = f.listFiles(filter);
- } else {
- l = f.listFiles();
- }
- if (l == null) {
- // File.listFiles returns null if File does not exist or if there
- // was an IO error (permission denied)
- return;
- }
- final List<File> ll = Arrays.asList(l);
- Collections.sort(ll);
-
- for (final Iterator<File> i = ll.iterator(); i.hasNext();) {
- final File lf = i.next();
- col.add(lf);
- if (lf.isDirectory()) {
- addItemIds(col, lf);
- }
- }
- }
-
- /*
- * Gets the IDs of Items in the filesystem. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Collection<File> getItemIds() {
-
- if (recursive) {
- final Collection<File> col = new ArrayList<File>();
- for (int i = 0; i < roots.length; i++) {
- addItemIds(col, roots[i]);
- }
- return Collections.unmodifiableCollection(col);
- } else {
- File[] f;
- if (roots.length == 1) {
- if (filter != null) {
- f = roots[0].listFiles(filter);
- } else {
- f = roots[0].listFiles();
- }
- } else {
- f = roots;
- }
-
- if (f == null) {
- return Collections
- .unmodifiableCollection(new LinkedList<File>());
- }
-
- final List<File> l = Arrays.asList(f);
- Collections.sort(l);
- return Collections.unmodifiableCollection(l);
- }
-
- }
-
- /**
- * Gets the specified property of the specified file Item. The available
- * file properties are "Name", "Size" and "Last Modified". If propertyId is
- * not one of those, <code>null</code> is returned.
- *
- * @param itemId
- * the ID of the file whose property is requested.
- * @param propertyId
- * the property's ID.
- * @return the requested property's value, or <code>null</code>
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
-
- if (!(itemId instanceof File)) {
- return null;
- }
-
- if (propertyId.equals(PROPERTY_NAME)) {
- return new MethodProperty<Object>(getType(propertyId),
- new FileItem((File) itemId), FILEITEM_NAME, null);
- }
-
- if (propertyId.equals(PROPERTY_ICON)) {
- return new MethodProperty<Object>(getType(propertyId),
- new FileItem((File) itemId), FILEITEM_ICON, null);
- }
-
- if (propertyId.equals(PROPERTY_SIZE)) {
- return new MethodProperty<Object>(getType(propertyId),
- new FileItem((File) itemId), FILEITEM_SIZE, null);
- }
-
- if (propertyId.equals(PROPERTY_LASTMODIFIED)) {
- return new MethodProperty<Object>(getType(propertyId),
- new FileItem((File) itemId), FILEITEM_LASTMODIFIED, null);
- }
-
- return null;
- }
-
- /**
- * Gets the collection of available file properties.
- *
- * @return Unmodifiable collection containing all available file properties.
- */
- @Override
- public Collection<String> getContainerPropertyIds() {
- return FILE_PROPERTIES;
- }
-
- /**
- * Gets the specified property's data type. "Name" is a <code>String</code>,
- * "Size" is a <code>Long</code>, "Last Modified" is a <code>Date</code>. If
- * propertyId is not one of those, <code>null</code> is returned.
- *
- * @param propertyId
- * the ID of the property whose type is requested.
- * @return data type of the requested property, or <code>null</code>
- */
- @Override
- public Class<?> getType(Object propertyId) {
-
- if (propertyId.equals(PROPERTY_NAME)) {
- return String.class;
- }
- if (propertyId.equals(PROPERTY_ICON)) {
- return Resource.class;
- }
- if (propertyId.equals(PROPERTY_SIZE)) {
- return Long.class;
- }
- if (propertyId.equals(PROPERTY_LASTMODIFIED)) {
- return Date.class;
- }
- return null;
- }
-
- /**
- * Internal method to recursively calculate the number of files under a root
- * directory.
- *
- * @param f
- * the root to start counting from.
- */
- private int getFileCounts(File f) {
- File[] l;
- if (filter != null) {
- l = f.listFiles(filter);
- } else {
- l = f.listFiles();
- }
-
- if (l == null) {
- return 0;
- }
- int ret = l.length;
- for (int i = 0; i < l.length; i++) {
- if (l[i].isDirectory()) {
- ret += getFileCounts(l[i]);
- }
- }
- return ret;
- }
-
- /**
- * Gets the number of Items in the container. In effect, this is the
- * combined amount of files and directories.
- *
- * @return Number of Items in the container.
- */
- @Override
- public int size() {
-
- if (recursive) {
- int counts = 0;
- for (int i = 0; i < roots.length; i++) {
- counts += getFileCounts(roots[i]);
- }
- return counts;
- } else {
- File[] f;
- if (roots.length == 1) {
- if (filter != null) {
- f = roots[0].listFiles(filter);
- } else {
- f = roots[0].listFiles();
- }
- } else {
- f = roots;
- }
-
- if (f == null) {
- return 0;
- }
- return f.length;
- }
- }
-
- /**
- * A Item wrapper for files in a filesystem.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class FileItem implements Item {
-
- /**
- * The wrapped file.
- */
- private final File file;
-
- /**
- * Constructs a FileItem from a existing file.
- */
- private FileItem(File file) {
- this.file = file;
- }
-
- /*
- * Gets the specified property of this file. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Property<?> getItemProperty(Object id) {
- return getContainerProperty(file, id);
- }
-
- /*
- * Gets the IDs of all properties available for this item Don't add a
- * JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public Collection<String> getItemPropertyIds() {
- return getContainerPropertyIds();
- }
-
- /**
- * Calculates a integer hash-code for the Property that's unique inside
- * the Item containing the Property. Two different Properties inside the
- * same Item contained in the same list always have different
- * hash-codes, though Properties in different Items may have identical
- * hash-codes.
- *
- * @return A locally unique hash-code as integer
- */
- @Override
- public int hashCode() {
- return file.hashCode() ^ FilesystemContainer.this.hashCode();
- }
-
- /**
- * Tests if the given object is the same as the this object. Two
- * Properties got from an Item with the same ID are equal.
- *
- * @param obj
- * an object to compare with this object.
- * @return <code>true</code> if the given object is the same as this
- * object, <code>false</code> if not
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FileItem)) {
- return false;
- }
- final FileItem fi = (FileItem) obj;
- return fi.getHost() == getHost() && fi.file.equals(file);
- }
-
- /**
- * Gets the host of this file.
- */
- private FilesystemContainer getHost() {
- return FilesystemContainer.this;
- }
-
- /**
- * Gets the last modified date of this file.
- *
- * @return Date
- */
- public Date lastModified() {
- return new Date(file.lastModified());
- }
-
- /**
- * Gets the name of this file.
- *
- * @return file name of this file.
- */
- public String getName() {
- return file.getName();
- }
-
- /**
- * Gets the icon of this file.
- *
- * @return the icon of this file.
- */
- public Resource getIcon() {
- return FileTypeResolver.getIcon(file);
- }
-
- /**
- * Gets the size of this file.
- *
- * @return size
- */
- public long getSize() {
- if (file.isDirectory()) {
- return 0;
- }
- return file.length();
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- if ("".equals(file.getName())) {
- return file.getAbsolutePath();
- }
- return file.getName();
- }
-
- /**
- * Filesystem container does not support adding new properties.
- *
- * @see com.vaadin.data.Item#addItemProperty(Object, Property)
- */
- @Override
- public boolean addItemProperty(Object id, Property property)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Filesystem container "
- + "does not support adding new properties");
- }
-
- /**
- * Filesystem container does not support removing properties.
- *
- * @see com.vaadin.data.Item#removeItemProperty(Object)
- */
- @Override
- public boolean removeItemProperty(Object id)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Filesystem container does not support property removal");
- }
-
- }
-
- /**
- * Generic file extension filter for displaying only files having certain
- * extension.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class FileExtensionFilter implements FilenameFilter, Serializable {
-
- private final String filter;
-
- /**
- * Constructs a new FileExtensionFilter using given extension.
- *
- * @param fileExtension
- * the File extension without the separator (dot).
- */
- public FileExtensionFilter(String fileExtension) {
- filter = "." + fileExtension;
- }
-
- /**
- * Allows only files with the extension and directories.
- *
- * @see java.io.FilenameFilter#accept(File, String)
- */
- @Override
- public boolean accept(File dir, String name) {
- if (name.endsWith(filter)) {
- return true;
- }
- return new File(dir, name).isDirectory();
- }
-
- }
-
- /**
- * Returns the file filter used to limit the files in this container.
- *
- * @return Used filter instance or null if no filter is assigned.
- */
- public FilenameFilter getFilter() {
- return filter;
- }
-
- /**
- * Sets the file filter used to limit the files in this container.
- *
- * @param filter
- * The filter to set. <code>null</code> disables filtering.
- */
- public void setFilter(FilenameFilter filter) {
- this.filter = filter;
- }
-
- /**
- * Sets the file filter used to limit the files in this container.
- *
- * @param extension
- * the Filename extension (w/o separator) to limit the files in
- * container.
- */
- public void setFilter(String extension) {
- filter = new FileExtensionFilter(extension);
- }
-
- /**
- * Is this container recursive filesystem.
- *
- * @return <code>true</code> if container is recursive, <code>false</code>
- * otherwise.
- */
- public boolean isRecursive() {
- return recursive;
- }
-
- /**
- * Sets the container recursive property. Set this to false to limit the
- * files directly under the root file.
- * <p>
- * Note : This is meaningful only if the root really is a directory.
- * </p>
- *
- * @param recursive
- * the New value for recursive property.
- */
- public void setRecursive(boolean recursive) {
- this.recursive = recursive;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object,
- * java.lang.Class, java.lang.Object)
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addItem()
- */
- @Override
- public Object addItem() throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addItem(java.lang.Object)
- */
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeAllItems()
- */
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeItem(java.lang.Object)
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object )
- */
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "File system container does not support this operation");
- }
-}
diff --git a/src/com/vaadin/data/util/HierarchicalContainer.java b/src/com/vaadin/data/util/HierarchicalContainer.java
deleted file mode 100644
index 06ab77c0e7..0000000000
--- a/src/com/vaadin/data/util/HierarchicalContainer.java
+++ /dev/null
@@ -1,814 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Set;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-
-/**
- * A specialized Container whose contents can be accessed like it was a
- * tree-like structure.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class HierarchicalContainer extends IndexedContainer implements
- Container.Hierarchical {
-
- /**
- * Set of IDs of those contained Items that can't have children.
- */
- private final HashSet<Object> noChildrenAllowed = new HashSet<Object>();
-
- /**
- * Mapping from Item ID to parent Item ID.
- */
- private final HashMap<Object, Object> parent = new HashMap<Object, Object>();
-
- /**
- * Mapping from Item ID to parent Item ID for items included in the filtered
- * container.
- */
- private HashMap<Object, Object> filteredParent = null;
-
- /**
- * Mapping from Item ID to a list of child IDs.
- */
- private final HashMap<Object, LinkedList<Object>> children = new HashMap<Object, LinkedList<Object>>();
-
- /**
- * Mapping from Item ID to a list of child IDs when filtered
- */
- private HashMap<Object, LinkedList<Object>> filteredChildren = null;
-
- /**
- * List that contains all root elements of the container.
- */
- private final LinkedList<Object> roots = new LinkedList<Object>();
-
- /**
- * List that contains all filtered root elements of the container.
- */
- private LinkedList<Object> filteredRoots = null;
-
- /**
- * Determines how filtering of the container is done.
- */
- private boolean includeParentsWhenFiltering = true;
-
- private boolean contentChangedEventsDisabled = false;
-
- private boolean contentsChangedEventPending;
-
- /*
- * Can the specified Item have any children? Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public boolean areChildrenAllowed(Object itemId) {
- if (noChildrenAllowed.contains(itemId)) {
- return false;
- }
- return containsId(itemId);
- }
-
- /*
- * Gets the IDs of the children of the specified Item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> getChildren(Object itemId) {
- LinkedList<Object> c;
-
- if (filteredChildren != null) {
- c = filteredChildren.get(itemId);
- } else {
- c = children.get(itemId);
- }
-
- if (c == null) {
- return null;
- }
- return Collections.unmodifiableCollection(c);
- }
-
- /*
- * Gets the ID of the parent of the specified Item. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Object getParent(Object itemId) {
- if (filteredParent != null) {
- return filteredParent.get(itemId);
- }
- return parent.get(itemId);
- }
-
- /*
- * Is the Item corresponding to the given ID a leaf node? Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean hasChildren(Object itemId) {
- if (filteredChildren != null) {
- return filteredChildren.containsKey(itemId);
- } else {
- return children.containsKey(itemId);
- }
- }
-
- /*
- * Is the Item corresponding to the given ID a root node? Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public boolean isRoot(Object itemId) {
- // If the container is filtered the itemId must be among filteredRoots
- // to be a root.
- if (filteredRoots != null) {
- if (!filteredRoots.contains(itemId)) {
- return false;
- }
- } else {
- // Container is not filtered
- if (parent.containsKey(itemId)) {
- return false;
- }
- }
-
- return containsId(itemId);
- }
-
- /*
- * Gets the IDs of the root elements in the container. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public Collection<?> rootItemIds() {
- if (filteredRoots != null) {
- return Collections.unmodifiableCollection(filteredRoots);
- } else {
- return Collections.unmodifiableCollection(roots);
- }
- }
-
- /**
- * <p>
- * Sets the given Item's capability to have children. If the Item identified
- * with the itemId already has children and the areChildrenAllowed is false
- * this method fails and <code>false</code> is returned; the children must
- * be first explicitly removed with
- * {@link #setParent(Object itemId, Object newParentId)} or
- * {@link com.vaadin.data.Container#removeItem(Object itemId)}.
- * </p>
- *
- * @param itemId
- * the ID of the Item in the container whose child capability is
- * to be set.
- * @param childrenAllowed
- * the boolean value specifying if the Item can have children or
- * not.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean childrenAllowed) {
-
- // Checks that the item is in the container
- if (!containsId(itemId)) {
- return false;
- }
-
- // Updates status
- if (childrenAllowed) {
- noChildrenAllowed.remove(itemId);
- } else {
- noChildrenAllowed.add(itemId);
- }
-
- return true;
- }
-
- /**
- * <p>
- * Sets the parent of an Item. The new parent item must exist and be able to
- * have children. (<code>canHaveChildren(newParentId) == true</code>). It is
- * also possible to detach a node from the hierarchy (and thus make it root)
- * by setting the parent <code>null</code>.
- * </p>
- *
- * @param itemId
- * the ID of the item to be set as the child of the Item
- * identified with newParentId.
- * @param newParentId
- * the ID of the Item that's to be the new parent of the Item
- * identified with itemId.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean setParent(Object itemId, Object newParentId) {
-
- // Checks that the item is in the container
- if (!containsId(itemId)) {
- return false;
- }
-
- // Gets the old parent
- final Object oldParentId = parent.get(itemId);
-
- // Checks if no change is necessary
- if ((newParentId == null && oldParentId == null)
- || ((newParentId != null) && newParentId.equals(oldParentId))) {
- return true;
- }
-
- // Making root?
- if (newParentId == null) {
- // The itemId should become a root so we need to
- // - Remove it from the old parent's children list
- // - Add it as a root
- // - Remove it from the item -> parent list (parent is null for
- // roots)
-
- // Removes from old parents children list
- final LinkedList<Object> l = children.get(oldParentId);
- if (l != null) {
- l.remove(itemId);
- if (l.isEmpty()) {
- children.remove(oldParentId);
- }
-
- }
-
- // Add to be a root
- roots.add(itemId);
-
- // Updates parent
- parent.remove(itemId);
-
- if (hasFilters()) {
- // Refilter the container if setParent is called when filters
- // are applied. Changing parent can change what is included in
- // the filtered version (if includeParentsWhenFiltering==true).
- doFilterContainer(hasFilters());
- }
-
- fireItemSetChange();
-
- return true;
- }
-
- // We get here when the item should not become a root and we need to
- // - Verify the new parent exists and can have children
- // - Check that the new parent is not a child of the selected itemId
- // - Updated the item -> parent mapping to point to the new parent
- // - Remove the item from the roots list if it was a root
- // - Remove the item from the old parent's children list if it was not a
- // root
-
- // Checks that the new parent exists in container and can have
- // children
- if (!containsId(newParentId) || noChildrenAllowed.contains(newParentId)) {
- return false;
- }
-
- // Checks that setting parent doesn't result to a loop
- Object o = newParentId;
- while (o != null && !o.equals(itemId)) {
- o = parent.get(o);
- }
- if (o != null) {
- return false;
- }
-
- // Updates parent
- parent.put(itemId, newParentId);
- LinkedList<Object> pcl = children.get(newParentId);
- if (pcl == null) {
- // Create an empty list for holding children if one were not
- // previously created
- pcl = new LinkedList<Object>();
- children.put(newParentId, pcl);
- }
- pcl.add(itemId);
-
- // Removes from old parent or root
- if (oldParentId == null) {
- roots.remove(itemId);
- } else {
- final LinkedList<Object> l = children.get(oldParentId);
- if (l != null) {
- l.remove(itemId);
- if (l.isEmpty()) {
- children.remove(oldParentId);
- }
- }
- }
-
- if (hasFilters()) {
- // Refilter the container if setParent is called when filters
- // are applied. Changing parent can change what is included in
- // the filtered version (if includeParentsWhenFiltering==true).
- doFilterContainer(hasFilters());
- }
-
- fireItemSetChange();
-
- return true;
- }
-
- private boolean hasFilters() {
- return (filteredRoots != null);
- }
-
- /**
- * Moves a node (an Item) in the container immediately after a sibling node.
- * The two nodes must have the same parent in the container.
- *
- * @param itemId
- * the identifier of the moved node (Item)
- * @param siblingId
- * the identifier of the reference node (Item), after which the
- * other node will be located
- */
- public void moveAfterSibling(Object itemId, Object siblingId) {
- Object parent2 = getParent(itemId);
- LinkedList<Object> childrenList;
- if (parent2 == null) {
- childrenList = roots;
- } else {
- childrenList = children.get(parent2);
- }
- if (siblingId == null) {
- childrenList.remove(itemId);
- childrenList.addFirst(itemId);
-
- } else {
- int oldIndex = childrenList.indexOf(itemId);
- int indexOfSibling = childrenList.indexOf(siblingId);
- if (indexOfSibling != -1 && oldIndex != -1) {
- int newIndex;
- if (oldIndex > indexOfSibling) {
- newIndex = indexOfSibling + 1;
- } else {
- newIndex = indexOfSibling;
- }
- childrenList.remove(oldIndex);
- childrenList.add(newIndex, itemId);
- } else {
- throw new IllegalArgumentException(
- "Given identifiers no not have the same parent.");
- }
- }
- fireItemSetChange();
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#addItem()
- */
- @Override
- public Object addItem() {
- disableContentsChangeEvents();
- final Object itemId = super.addItem();
- if (itemId == null) {
- return null;
- }
-
- if (!roots.contains(itemId)) {
- roots.add(itemId);
- if (filteredRoots != null) {
- if (passesFilters(itemId)) {
- filteredRoots.add(itemId);
- }
- }
- }
- enableAndFireContentsChangeEvents();
- return itemId;
- }
-
- @Override
- protected void fireItemSetChange(
- com.vaadin.data.Container.ItemSetChangeEvent event) {
- if (contentsChangeEventsOn()) {
- super.fireItemSetChange(event);
- } else {
- contentsChangedEventPending = true;
- }
- }
-
- private boolean contentsChangeEventsOn() {
- return !contentChangedEventsDisabled;
- }
-
- private void disableContentsChangeEvents() {
- contentChangedEventsDisabled = true;
- }
-
- private void enableAndFireContentsChangeEvents() {
- contentChangedEventsDisabled = false;
- if (contentsChangedEventPending) {
- fireItemSetChange();
- }
- contentsChangedEventPending = false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#addItem(java.lang.Object)
- */
- @Override
- public Item addItem(Object itemId) {
- disableContentsChangeEvents();
- final Item item = super.addItem(itemId);
- if (item == null) {
- return null;
- }
-
- roots.add(itemId);
-
- if (filteredRoots != null) {
- if (passesFilters(itemId)) {
- filteredRoots.add(itemId);
- }
- }
- enableAndFireContentsChangeEvents();
- return item;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#removeAllItems()
- */
- @Override
- public boolean removeAllItems() {
- disableContentsChangeEvents();
- final boolean success = super.removeAllItems();
-
- if (success) {
- roots.clear();
- parent.clear();
- children.clear();
- noChildrenAllowed.clear();
- if (filteredRoots != null) {
- filteredRoots = null;
- }
- if (filteredChildren != null) {
- filteredChildren = null;
- }
- if (filteredParent != null) {
- filteredParent = null;
- }
- }
- enableAndFireContentsChangeEvents();
- return success;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#removeItem(java.lang.Object )
- */
- @Override
- public boolean removeItem(Object itemId) {
- disableContentsChangeEvents();
- final boolean success = super.removeItem(itemId);
-
- if (success) {
- // Remove from roots if this was a root
- if (roots.remove(itemId)) {
-
- // If filtering is enabled we might need to remove it from the
- // filtered list also
- if (filteredRoots != null) {
- filteredRoots.remove(itemId);
- }
- }
-
- // Clear the children list. Old children will now become root nodes
- LinkedList<Object> childNodeIds = children.remove(itemId);
- if (childNodeIds != null) {
- if (filteredChildren != null) {
- filteredChildren.remove(itemId);
- }
- for (Object childId : childNodeIds) {
- setParent(childId, null);
- }
- }
-
- // Parent of the item that we are removing will contain the item id
- // in its children list
- final Object parentItemId = parent.get(itemId);
- if (parentItemId != null) {
- final LinkedList<Object> c = children.get(parentItemId);
- if (c != null) {
- c.remove(itemId);
-
- if (c.isEmpty()) {
- children.remove(parentItemId);
- }
-
- // Found in the children list so might also be in the
- // filteredChildren list
- if (filteredChildren != null) {
- LinkedList<Object> f = filteredChildren
- .get(parentItemId);
- if (f != null) {
- f.remove(itemId);
- if (f.isEmpty()) {
- filteredChildren.remove(parentItemId);
- }
- }
- }
- }
- }
- parent.remove(itemId);
- if (filteredParent != null) {
- // Item id no longer has a parent as the item id is not in the
- // container.
- filteredParent.remove(itemId);
- }
- noChildrenAllowed.remove(itemId);
- }
-
- enableAndFireContentsChangeEvents();
-
- return success;
- }
-
- /**
- * Removes the Item identified by given itemId and all its children.
- *
- * @see #removeItem(Object)
- * @param itemId
- * the identifier of the Item to be removed
- * @return true if the operation succeeded
- */
- public boolean removeItemRecursively(Object itemId) {
- disableContentsChangeEvents();
- boolean removeItemRecursively = removeItemRecursively(this, itemId);
- enableAndFireContentsChangeEvents();
- return removeItemRecursively;
- }
-
- /**
- * Removes the Item identified by given itemId and all its children from the
- * given Container.
- *
- * @param container
- * the container where the item is to be removed
- * @param itemId
- * the identifier of the Item to be removed
- * @return true if the operation succeeded
- */
- public static boolean removeItemRecursively(
- Container.Hierarchical container, Object itemId) {
- boolean success = true;
- Collection<?> children2 = container.getChildren(itemId);
- if (children2 != null) {
- Object[] array = children2.toArray();
- for (int i = 0; i < array.length; i++) {
- boolean removeItemRecursively = removeItemRecursively(
- container, array[i]);
- if (!removeItemRecursively) {
- success = false;
- }
- }
- }
- // remove the root of subtree if children where succesfully removed
- if (success) {
- success = container.removeItem(itemId);
- }
- return success;
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#doSort()
- */
- @Override
- protected void doSort() {
- super.doSort();
-
- Collections.sort(roots, getItemSorter());
- for (LinkedList<Object> childList : children.values()) {
- Collections.sort(childList, getItemSorter());
- }
- }
-
- /**
- * Used to control how filtering works. @see
- * {@link #setIncludeParentsWhenFiltering(boolean)} for more information.
- *
- * @return true if all parents for items that match the filter are included
- * when filtering, false if only the matching items are included
- */
- public boolean isIncludeParentsWhenFiltering() {
- return includeParentsWhenFiltering;
- }
-
- /**
- * Controls how the filtering of the container works. Set this to true to
- * make filtering include parents for all matched items in addition to the
- * items themselves. Setting this to false causes the filtering to only
- * include the matching items and make items with excluded parents into root
- * items.
- *
- * @param includeParentsWhenFiltering
- * true to include all parents for items that match the filter,
- * false to only include the matching items
- */
- public void setIncludeParentsWhenFiltering(
- boolean includeParentsWhenFiltering) {
- this.includeParentsWhenFiltering = includeParentsWhenFiltering;
- if (filteredRoots != null) {
- // Currently filtered so needs to be re-filtered
- doFilterContainer(true);
- }
- }
-
- /*
- * Overridden to provide filtering for root & children items.
- *
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.IndexedContainer#updateContainerFiltering()
- */
- @Override
- protected boolean doFilterContainer(boolean hasFilters) {
- if (!hasFilters) {
- // All filters removed
- filteredRoots = null;
- filteredChildren = null;
- filteredParent = null;
-
- return super.doFilterContainer(hasFilters);
- }
-
- // Reset data structures
- filteredRoots = new LinkedList<Object>();
- filteredChildren = new HashMap<Object, LinkedList<Object>>();
- filteredParent = new HashMap<Object, Object>();
-
- if (includeParentsWhenFiltering) {
- // Filter so that parents for items that match the filter are also
- // included
- HashSet<Object> includedItems = new HashSet<Object>();
- for (Object rootId : roots) {
- if (filterIncludingParents(rootId, includedItems)) {
- filteredRoots.add(rootId);
- addFilteredChildrenRecursively(rootId, includedItems);
- }
- }
- // includedItemIds now contains all the item ids that should be
- // included. Filter IndexedContainer based on this
- filterOverride = includedItems;
- super.doFilterContainer(hasFilters);
- filterOverride = null;
-
- return true;
- } else {
- // Filter by including all items that pass the filter and make items
- // with no parent new root items
-
- // Filter IndexedContainer first so getItemIds return the items that
- // match
- super.doFilterContainer(hasFilters);
-
- LinkedHashSet<Object> filteredItemIds = new LinkedHashSet<Object>(
- getItemIds());
-
- for (Object itemId : filteredItemIds) {
- Object itemParent = parent.get(itemId);
- if (itemParent == null || !filteredItemIds.contains(itemParent)) {
- // Parent is not included or this was a root, in both cases
- // this should be a filtered root
- filteredRoots.add(itemId);
- } else {
- // Parent is included. Add this to the children list (create
- // it first if necessary)
- addFilteredChild(itemParent, itemId);
- }
- }
-
- return true;
- }
- }
-
- /**
- * Adds the given childItemId as a filteredChildren for the parentItemId and
- * sets it filteredParent.
- *
- * @param parentItemId
- * @param childItemId
- */
- private void addFilteredChild(Object parentItemId, Object childItemId) {
- LinkedList<Object> parentToChildrenList = filteredChildren
- .get(parentItemId);
- if (parentToChildrenList == null) {
- parentToChildrenList = new LinkedList<Object>();
- filteredChildren.put(parentItemId, parentToChildrenList);
- }
- filteredParent.put(childItemId, parentItemId);
- parentToChildrenList.add(childItemId);
-
- }
-
- /**
- * Recursively adds all items in the includedItems list to the
- * filteredChildren map in the same order as they are in the children map.
- * Starts from parentItemId and recurses down as long as child items that
- * should be included are found.
- *
- * @param parentItemId
- * The item id to start recurse from. Not added to a
- * filteredChildren list
- * @param includedItems
- * Set containing the item ids for the items that should be
- * included in the filteredChildren map
- */
- private void addFilteredChildrenRecursively(Object parentItemId,
- HashSet<Object> includedItems) {
- LinkedList<Object> childList = children.get(parentItemId);
- if (childList == null) {
- return;
- }
-
- for (Object childItemId : childList) {
- if (includedItems.contains(childItemId)) {
- addFilteredChild(parentItemId, childItemId);
- addFilteredChildrenRecursively(childItemId, includedItems);
- }
- }
- }
-
- /**
- * Scans the itemId and all its children for which items should be included
- * when filtering. All items which passes the filters are included.
- * Additionally all items that have a child node that should be included are
- * also themselves included.
- *
- * @param itemId
- * @param includedItems
- * @return true if the itemId should be included in the filtered container.
- */
- private boolean filterIncludingParents(Object itemId,
- HashSet<Object> includedItems) {
- boolean toBeIncluded = passesFilters(itemId);
-
- LinkedList<Object> childList = children.get(itemId);
- if (childList != null) {
- for (Object childItemId : children.get(itemId)) {
- toBeIncluded |= filterIncludingParents(childItemId,
- includedItems);
- }
- }
-
- if (toBeIncluded) {
- includedItems.add(itemId);
- }
- return toBeIncluded;
- }
-
- private Set<Object> filterOverride = null;
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.IndexedContainer#passesFilters(java.lang.Object)
- */
- @Override
- protected boolean passesFilters(Object itemId) {
- if (filterOverride != null) {
- return filterOverride.contains(itemId);
- } else {
- return super.passesFilters(itemId);
- }
- }
-}
diff --git a/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java b/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java
deleted file mode 100644
index 172dc0dd4f..0000000000
--- a/src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container.Hierarchical;
-
-/**
- * A wrapper class for adding external ordering to containers not implementing
- * the {@link com.vaadin.data.Container.Ordered} interface while retaining
- * {@link Hierarchical} features.
- *
- * @see ContainerOrderedWrapper
- */
-@SuppressWarnings({ "serial" })
-public class HierarchicalContainerOrderedWrapper extends
- ContainerOrderedWrapper implements Hierarchical {
-
- private Hierarchical hierarchical;
-
- public HierarchicalContainerOrderedWrapper(Hierarchical toBeWrapped) {
- super(toBeWrapped);
- hierarchical = toBeWrapped;
- }
-
- @Override
- public boolean areChildrenAllowed(Object itemId) {
- return hierarchical.areChildrenAllowed(itemId);
- }
-
- @Override
- public Collection<?> getChildren(Object itemId) {
- return hierarchical.getChildren(itemId);
- }
-
- @Override
- public Object getParent(Object itemId) {
- return hierarchical.getParent(itemId);
- }
-
- @Override
- public boolean hasChildren(Object itemId) {
- return hierarchical.hasChildren(itemId);
- }
-
- @Override
- public boolean isRoot(Object itemId) {
- return hierarchical.isRoot(itemId);
- }
-
- @Override
- public Collection<?> rootItemIds() {
- return hierarchical.rootItemIds();
- }
-
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
- throws UnsupportedOperationException {
- return hierarchical.setChildrenAllowed(itemId, areChildrenAllowed);
- }
-
- @Override
- public boolean setParent(Object itemId, Object newParentId)
- throws UnsupportedOperationException {
- return hierarchical.setParent(itemId, newParentId);
- }
-
-}
diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java
deleted file mode 100644
index b95b2c4de8..0000000000
--- a/src/com/vaadin/data/util/IndexedContainer.java
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.data.util.filter.UnsupportedFilterException;
-
-/**
- * An implementation of the <code>{@link Container.Indexed}</code> interface
- * with all important features.</p>
- *
- * Features:
- * <ul>
- * <li> {@link Container.Indexed}
- * <li> {@link Container.Ordered}
- * <li> {@link Container.Sortable}
- * <li> {@link Container.Filterable}
- * <li> {@link Cloneable} (deprecated, might be removed in the future)
- * <li>Sends all needed events on content changes.
- * </ul>
- *
- * @see com.vaadin.data.Container
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-
-@SuppressWarnings("serial")
-// item type is really IndexedContainerItem, but using Item not to show it in
-// public API
-public class IndexedContainer extends
- AbstractInMemoryContainer<Object, Object, Item> implements
- Container.PropertySetChangeNotifier, Property.ValueChangeNotifier,
- Container.Sortable, Cloneable, Container.Filterable,
- Container.SimpleFilterable {
-
- /* Internal structure */
-
- /**
- * Linked list of ordered Property IDs.
- */
- private ArrayList<Object> propertyIds = new ArrayList<Object>();
-
- /**
- * Property ID to type mapping.
- */
- private Hashtable<Object, Class<?>> types = new Hashtable<Object, Class<?>>();
-
- /**
- * Hash of Items, where each Item is implemented as a mapping from Property
- * ID to Property value.
- */
- private Hashtable<Object, Map<Object, Object>> items = new Hashtable<Object, Map<Object, Object>>();
-
- /**
- * Set of properties that are read-only.
- */
- private HashSet<Property<?>> readOnlyProperties = new HashSet<Property<?>>();
-
- /**
- * List of all Property value change event listeners listening all the
- * properties.
- */
- private LinkedList<Property.ValueChangeListener> propertyValueChangeListeners = null;
-
- /**
- * Data structure containing all listeners interested in changes to single
- * Properties. The data structure is a hashtable mapping Property IDs to a
- * hashtable that maps Item IDs to a linked list of listeners listening
- * Property identified by given Property ID and Item ID.
- */
- private Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>> singlePropertyValueChangeListeners = null;
-
- private HashMap<Object, Object> defaultPropertyValues;
-
- private int nextGeneratedItemId = 1;
-
- /* Container constructors */
-
- public IndexedContainer() {
- super();
- }
-
- public IndexedContainer(Collection<?> itemIds) {
- this();
- if (items != null) {
- for (final Iterator<?> i = itemIds.iterator(); i.hasNext();) {
- Object itemId = i.next();
- internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId),
- false);
- }
- filterAll();
- }
- }
-
- /* Container methods */
-
- @Override
- protected Item getUnfilteredItem(Object itemId) {
- if (itemId != null && items.containsKey(itemId)) {
- return new IndexedContainerItem(itemId);
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerPropertyIds()
- */
- @Override
- public Collection<?> getContainerPropertyIds() {
- return Collections.unmodifiableCollection(propertyIds);
- }
-
- /**
- * Gets the type of a Property stored in the list.
- *
- * @param id
- * the ID of the Property.
- * @return Type of the requested Property
- */
- @Override
- public Class<?> getType(Object propertyId) {
- return types.get(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- if (!containsId(itemId)) {
- return null;
- }
-
- return new IndexedContainerProperty(itemId, propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object,
- * java.lang.Class, java.lang.Object)
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) {
-
- // Fails, if nulls are given
- if (propertyId == null || type == null) {
- return false;
- }
-
- // Fails if the Property is already present
- if (propertyIds.contains(propertyId)) {
- return false;
- }
-
- // Adds the Property to Property list and types
- propertyIds.add(propertyId);
- types.put(propertyId, type);
-
- // If default value is given, set it
- if (defaultValue != null) {
- // for existing rows
- for (final Iterator<?> i = getAllItemIds().iterator(); i.hasNext();) {
- getItem(i.next()).getItemProperty(propertyId).setValue(
- defaultValue);
- }
- // store for next rows
- if (defaultPropertyValues == null) {
- defaultPropertyValues = new HashMap<Object, Object>();
- }
- defaultPropertyValues.put(propertyId, defaultValue);
- }
-
- // Sends a change event
- fireContainerPropertySetChange();
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeAllItems()
- */
- @Override
- public boolean removeAllItems() {
- int origSize = size();
-
- internalRemoveAllItems();
-
- items.clear();
-
- // fire event only if the visible view changed, regardless of whether
- // filtered out items were removed or not
- if (origSize != 0) {
- // Sends a change event
- fireItemSetChange();
- }
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addItem()
- */
- @Override
- public Object addItem() {
-
- // Creates a new id
- final Object id = generateId();
-
- // Adds the Item into container
- addItem(id);
-
- return id;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addItem(java.lang.Object)
- */
- @Override
- public Item addItem(Object itemId) {
- Item item = internalAddItemAtEnd(itemId, new IndexedContainerItem(
- itemId), false);
- if (!isFiltered()) {
- // always the last item
- fireItemAdded(size() - 1, itemId, item);
- } else if (passesFilters(itemId) && !containsId(itemId)) {
- getFilteredItemIds().add(itemId);
- // always the last item
- fireItemAdded(size() - 1, itemId, item);
- }
- return item;
- }
-
- /**
- * Helper method to add default values for items if available
- *
- * @param t
- * data table of added item
- */
- private void addDefaultValues(Hashtable<Object, Object> t) {
- if (defaultPropertyValues != null) {
- for (Object key : defaultPropertyValues.keySet()) {
- t.put(key, defaultPropertyValues.get(key));
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeItem(java.lang.Object)
- */
- @Override
- public boolean removeItem(Object itemId) {
- if (itemId == null || items.remove(itemId) == null) {
- return false;
- }
- int origSize = size();
- int position = indexOfId(itemId);
- if (internalRemoveItem(itemId)) {
- // fire event only if the visible view changed, regardless of
- // whether filtered out items were removed or not
- if (size() != origSize) {
- fireItemRemoved(position, itemId);
- }
-
- return true;
- } else {
- return false;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object )
- */
- @Override
- public boolean removeContainerProperty(Object propertyId) {
-
- // Fails if the Property is not present
- if (!propertyIds.contains(propertyId)) {
- return false;
- }
-
- // Removes the Property to Property list and types
- propertyIds.remove(propertyId);
- types.remove(propertyId);
- if (defaultPropertyValues != null) {
- defaultPropertyValues.remove(propertyId);
- }
-
- // If remove the Property from all Items
- for (final Iterator<Object> i = getAllItemIds().iterator(); i.hasNext();) {
- items.get(i.next()).remove(propertyId);
- }
-
- // Sends a change event
- fireContainerPropertySetChange();
-
- return true;
- }
-
- /* Container.Ordered methods */
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId) {
- return internalAddItemAfter(previousItemId, newItemId,
- new IndexedContainerItem(newItemId), true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
- */
- @Override
- public Object addItemAfter(Object previousItemId) {
-
- // Creates a new id
- final Object id = generateId();
-
- if (addItemAfter(previousItemId, id) != null) {
- return id;
- } else {
- return null;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object)
- */
- @Override
- public Item addItemAt(int index, Object newItemId) {
- return internalAddItemAt(index, newItemId, new IndexedContainerItem(
- newItemId), true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#addItemAt(int)
- */
- @Override
- public Object addItemAt(int index) {
-
- // Creates a new id
- final Object id = generateId();
-
- // Adds the Item into container
- addItemAt(index, id);
-
- return id;
- }
-
- /**
- * Generates an unique identifier for use as an item id. Guarantees that the
- * generated id is not currently used as an id.
- *
- * @return
- */
- private Serializable generateId() {
- Serializable id;
- do {
- id = Integer.valueOf(nextGeneratedItemId++);
- } while (items.containsKey(id));
-
- return id;
- }
-
- @Override
- protected void registerNewItem(int index, Object newItemId, Item item) {
- Hashtable<Object, Object> t = new Hashtable<Object, Object>();
- items.put(newItemId, t);
- addDefaultValues(t);
- }
-
- /* Event notifiers */
-
- /**
- * An <code>event</code> object specifying the list whose Item set has
- * changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class ItemSetChangeEvent extends BaseItemSetChangeEvent {
-
- private final int addedItemIndex;
-
- private ItemSetChangeEvent(IndexedContainer source, int addedItemIndex) {
- super(source);
- this.addedItemIndex = addedItemIndex;
- }
-
- /**
- * Iff one item is added, gives its index.
- *
- * @return -1 if either multiple items are changed or some other change
- * than add is done.
- */
- public int getAddedItemIndex() {
- return addedItemIndex;
- }
-
- }
-
- /**
- * An <code>event</code> object specifying the Property in a list whose
- * value has changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- private static class PropertyValueChangeEvent extends EventObject implements
- Property.ValueChangeEvent, Serializable {
-
- private PropertyValueChangeEvent(Property source) {
- super(source);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property.ValueChangeEvent#getProperty()
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
-
- }
-
- @Override
- public void addListener(Container.PropertySetChangeListener listener) {
- super.addListener(listener);
- }
-
- @Override
- public void removeListener(Container.PropertySetChangeListener listener) {
- super.removeListener(listener);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(com.
- * vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void addListener(Property.ValueChangeListener listener) {
- if (propertyValueChangeListeners == null) {
- propertyValueChangeListeners = new LinkedList<Property.ValueChangeListener>();
- }
- propertyValueChangeListeners.add(listener);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener(com
- * .vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void removeListener(Property.ValueChangeListener listener) {
- if (propertyValueChangeListeners != null) {
- propertyValueChangeListeners.remove(listener);
- }
- }
-
- /**
- * Sends a Property value change event to all interested listeners.
- *
- * @param source
- * the IndexedContainerProperty object.
- */
- private void firePropertyValueChange(IndexedContainerProperty source) {
-
- // Sends event to listeners listening all value changes
- if (propertyValueChangeListeners != null) {
- final Object[] l = propertyValueChangeListeners.toArray();
- final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent(
- source);
- for (int i = 0; i < l.length; i++) {
- ((Property.ValueChangeListener) l[i]).valueChange(event);
- }
- }
-
- // Sends event to single property value change listeners
- if (singlePropertyValueChangeListeners != null) {
- final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners
- .get(source.propertyId);
- if (propertySetToListenerListMap != null) {
- final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap
- .get(source.itemId);
- if (listenerList != null) {
- final Property.ValueChangeEvent event = new IndexedContainer.PropertyValueChangeEvent(
- source);
- Object[] listeners = listenerList.toArray();
- for (int i = 0; i < listeners.length; i++) {
- ((Property.ValueChangeListener) listeners[i])
- .valueChange(event);
- }
- }
- }
- }
-
- }
-
- @Override
- public Collection<?> getListeners(Class<?> eventType) {
- if (Property.ValueChangeEvent.class.isAssignableFrom(eventType)) {
- if (propertyValueChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(propertyValueChangeListeners);
- }
- }
- return super.getListeners(eventType);
- }
-
- @Override
- protected void fireItemAdded(int position, Object itemId, Item item) {
- if (position >= 0) {
- fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this,
- position));
- }
- }
-
- @Override
- protected void fireItemSetChange() {
- fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this, -1));
- }
-
- /**
- * Adds new single Property change listener.
- *
- * @param propertyId
- * the ID of the Property to add.
- * @param itemId
- * the ID of the Item .
- * @param listener
- * the listener to be added.
- */
- private void addSinglePropertyChangeListener(Object propertyId,
- Object itemId, Property.ValueChangeListener listener) {
- if (listener != null) {
- if (singlePropertyValueChangeListeners == null) {
- singlePropertyValueChangeListeners = new Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>();
- }
- Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners
- .get(propertyId);
- if (propertySetToListenerListMap == null) {
- propertySetToListenerListMap = new Hashtable<Object, List<Property.ValueChangeListener>>();
- singlePropertyValueChangeListeners.put(propertyId,
- propertySetToListenerListMap);
- }
- List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap
- .get(itemId);
- if (listenerList == null) {
- listenerList = new LinkedList<Property.ValueChangeListener>();
- propertySetToListenerListMap.put(itemId, listenerList);
- }
- listenerList.add(listener);
- }
- }
-
- /**
- * Removes a previously registered single Property change listener.
- *
- * @param propertyId
- * the ID of the Property to remove.
- * @param itemId
- * the ID of the Item.
- * @param listener
- * the listener to be removed.
- */
- private void removeSinglePropertyChangeListener(Object propertyId,
- Object itemId, Property.ValueChangeListener listener) {
- if (listener != null && singlePropertyValueChangeListeners != null) {
- final Map<Object, List<Property.ValueChangeListener>> propertySetToListenerListMap = singlePropertyValueChangeListeners
- .get(propertyId);
- if (propertySetToListenerListMap != null) {
- final List<Property.ValueChangeListener> listenerList = propertySetToListenerListMap
- .get(itemId);
- if (listenerList != null) {
- listenerList.remove(listener);
- if (listenerList.isEmpty()) {
- propertySetToListenerListMap.remove(itemId);
- }
- }
- if (propertySetToListenerListMap.isEmpty()) {
- singlePropertyValueChangeListeners.remove(propertyId);
- }
- }
- if (singlePropertyValueChangeListeners.isEmpty()) {
- singlePropertyValueChangeListeners = null;
- }
- }
- }
-
- /* Internal Item and Property implementations */
-
- /*
- * A class implementing the com.vaadin.data.Item interface to be contained
- * in the list.
- *
- * @author Vaadin Ltd.
- *
- * @version @VERSION@
- *
- * @since 3.0
- */
- class IndexedContainerItem implements Item {
-
- /**
- * Item ID in the host container for this Item.
- */
- private final Object itemId;
-
- /**
- * Constructs a new ListItem instance and connects it to a host
- * container.
- *
- * @param itemId
- * the Item ID of the new Item.
- */
- private IndexedContainerItem(Object itemId) {
-
- // Gets the item contents from the host
- if (itemId == null) {
- throw new NullPointerException();
- }
- this.itemId = itemId;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Item#getItemProperty(java.lang.Object)
- */
- @Override
- public Property<?> getItemProperty(Object id) {
- return new IndexedContainerProperty(itemId, id);
- }
-
- @Override
- public Collection<?> getItemPropertyIds() {
- return Collections.unmodifiableCollection(propertyIds);
- }
-
- /**
- * Gets the <code>String</code> representation of the contents of the
- * Item. The format of the string is a space separated catenation of the
- * <code>String</code> representations of the values of the Properties
- * contained by the Item.
- *
- * @return <code>String</code> representation of the Item contents
- */
- @Override
- public String toString() {
- String retValue = "";
-
- for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) {
- final Object propertyId = i.next();
- retValue += getItemProperty(propertyId).getValue();
- if (i.hasNext()) {
- retValue += " ";
- }
- }
-
- return retValue;
- }
-
- /**
- * Calculates a integer hash-code for the Item that's unique inside the
- * list. Two Items inside the same list have always different
- * hash-codes, though Items in different lists may have identical
- * hash-codes.
- *
- * @return A locally unique hash-code as integer
- */
- @Override
- public int hashCode() {
- return itemId.hashCode();
- }
-
- /**
- * Tests if the given object is the same as the this object. Two Items
- * got from a list container with the same ID are equal.
- *
- * @param obj
- * an object to compare with this object
- * @return <code>true</code> if the given object is the same as this
- * object, <code>false</code> if not
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null
- || !obj.getClass().equals(IndexedContainerItem.class)) {
- return false;
- }
- final IndexedContainerItem li = (IndexedContainerItem) obj;
- return getHost() == li.getHost() && itemId.equals(li.itemId);
- }
-
- private IndexedContainer getHost() {
- return IndexedContainer.this;
- }
-
- /**
- * IndexedContainerItem does not support adding new properties. Add
- * properties at container level. See
- * {@link IndexedContainer#addContainerProperty(Object, Class, Object)}
- *
- * @see com.vaadin.data.Item#addProperty(Object, Property)
- */
- @Override
- public boolean addItemProperty(Object id, Property property)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException("Indexed container item "
- + "does not support adding new properties");
- }
-
- /**
- * Indexed container does not support removing properties. Remove
- * properties at container level. See
- * {@link IndexedContainer#removeContainerProperty(Object)}
- *
- * @see com.vaadin.data.Item#removeProperty(Object)
- */
- @Override
- public boolean removeItemProperty(Object id)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException(
- "Indexed container item does not support property removal");
- }
-
- }
-
- /**
- * A class implementing the {@link Property} interface to be contained in
- * the {@link IndexedContainerItem} contained in the
- * {@link IndexedContainer}.
- *
- * @author Vaadin Ltd.
- *
- * @version
- * @VERSION@
- * @since 3.0
- */
- private class IndexedContainerProperty implements Property<Object>,
- Property.ValueChangeNotifier {
-
- /**
- * ID of the Item, where this property resides.
- */
- private final Object itemId;
-
- /**
- * Id of the Property.
- */
- private final Object propertyId;
-
- /**
- * Constructs a new {@link IndexedContainerProperty} object.
- *
- * @param itemId
- * the ID of the Item to connect the new Property to.
- * @param propertyId
- * the Property ID of the new Property.
- * @param host
- * the list that contains the Item to contain the new
- * Property.
- */
- private IndexedContainerProperty(Object itemId, Object propertyId) {
- if (itemId == null || propertyId == null) {
- // Null ids are not accepted
- throw new NullPointerException(
- "Container item or property ids can not be null");
- }
- this.propertyId = propertyId;
- this.itemId = itemId;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getType()
- */
- @Override
- public Class<?> getType() {
- return types.get(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getValue()
- */
- @Override
- public Object getValue() {
- return items.get(itemId).get(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return readOnlyProperties.contains(this);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setReadOnly(boolean)
- */
- @Override
- public void setReadOnly(boolean newStatus) {
- if (newStatus) {
- readOnlyProperties.add(this);
- } else {
- readOnlyProperties.remove(this);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setValue(java.lang.Object)
- */
- @Override
- public void setValue(Object newValue) throws Property.ReadOnlyException {
- // Gets the Property set
- final Map<Object, Object> propertySet = items.get(itemId);
-
- // Support null values on all types
- if (newValue == null) {
- propertySet.remove(propertyId);
- } else if (getType().isAssignableFrom(newValue.getClass())) {
- propertySet.put(propertyId, newValue);
- } else {
- throw new IllegalArgumentException(
- "Value is of invalid type, got "
- + newValue.getClass().getName() + " but "
- + getType().getName() + " was expected");
- }
-
- // update the container filtering if this property is being filtered
- if (isPropertyFiltered(propertyId)) {
- filterAll();
- }
-
- firePropertyValueChange(this);
- }
-
- /**
- * Returns the value of the Property in human readable textual format.
- * The return value should be assignable to the <code>setValue</code>
- * method if the Property is not in read-only mode.
- *
- * @return <code>String</code> representation of the value stored in the
- * Property
- * @deprecated use {@link #getValue()} instead and possibly toString on
- * that
- */
- @Deprecated
- @Override
- public String toString() {
- throw new UnsupportedOperationException(
- "Use Property.getValue() instead of IndexedContainerProperty.toString()");
- }
-
- /**
- * Calculates a integer hash-code for the Property that's unique inside
- * the Item containing the Property. Two different Properties inside the
- * same Item contained in the same list always have different
- * hash-codes, though Properties in different Items may have identical
- * hash-codes.
- *
- * @return A locally unique hash-code as integer
- */
- @Override
- public int hashCode() {
- return itemId.hashCode() ^ propertyId.hashCode();
- }
-
- /**
- * Tests if the given object is the same as the this object. Two
- * Properties got from an Item with the same ID are equal.
- *
- * @param obj
- * an object to compare with this object
- * @return <code>true</code> if the given object is the same as this
- * object, <code>false</code> if not
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null
- || !obj.getClass().equals(IndexedContainerProperty.class)) {
- return false;
- }
- final IndexedContainerProperty lp = (IndexedContainerProperty) obj;
- return lp.getHost() == getHost()
- && lp.propertyId.equals(propertyId)
- && lp.itemId.equals(itemId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(
- * com.vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void addListener(Property.ValueChangeListener listener) {
- addSinglePropertyChangeListener(propertyId, itemId, listener);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener
- * (com.vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void removeListener(Property.ValueChangeListener listener) {
- removeSinglePropertyChangeListener(propertyId, itemId, listener);
- }
-
- private IndexedContainer getHost() {
- return IndexedContainer.this;
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
- * boolean[])
- */
- @Override
- public void sort(Object[] propertyId, boolean[] ascending) {
- sortContainer(propertyId, ascending);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds
- * ()
- */
- @Override
- public Collection<?> getSortableContainerPropertyIds() {
- return getSortablePropertyIds();
- }
-
- @Override
- public ItemSorter getItemSorter() {
- return super.getItemSorter();
- }
-
- @Override
- public void setItemSorter(ItemSorter itemSorter) {
- super.setItemSorter(itemSorter);
- }
-
- /**
- * Supports cloning of the IndexedContainer cleanly.
- *
- * @throws CloneNotSupportedException
- * if an object cannot be cloned. .
- *
- * @deprecated cloning support might be removed from IndexedContainer in the
- * future
- */
- @Deprecated
- @Override
- public Object clone() throws CloneNotSupportedException {
-
- // Creates the clone
- final IndexedContainer nc = new IndexedContainer();
-
- // Clone the shallow properties
- nc.setAllItemIds(getAllItemIds() != null ? (ListSet<Object>) ((ListSet<Object>) getAllItemIds())
- .clone() : null);
- nc.setItemSetChangeListeners(getItemSetChangeListeners() != null ? new LinkedList<Container.ItemSetChangeListener>(
- getItemSetChangeListeners()) : null);
- nc.propertyIds = propertyIds != null ? (ArrayList<Object>) propertyIds
- .clone() : null;
- nc.setPropertySetChangeListeners(getPropertySetChangeListeners() != null ? new LinkedList<Container.PropertySetChangeListener>(
- getPropertySetChangeListeners()) : null);
- nc.propertyValueChangeListeners = propertyValueChangeListeners != null ? (LinkedList<Property.ValueChangeListener>) propertyValueChangeListeners
- .clone() : null;
- nc.readOnlyProperties = readOnlyProperties != null ? (HashSet<Property<?>>) readOnlyProperties
- .clone() : null;
- nc.singlePropertyValueChangeListeners = singlePropertyValueChangeListeners != null ? (Hashtable<Object, Map<Object, List<Property.ValueChangeListener>>>) singlePropertyValueChangeListeners
- .clone() : null;
-
- nc.types = types != null ? (Hashtable<Object, Class<?>>) types.clone()
- : null;
-
- nc.setFilters((HashSet<Filter>) ((HashSet<Filter>) getFilters())
- .clone());
-
- nc.setFilteredItemIds(getFilteredItemIds() == null ? null
- : (ListSet<Object>) ((ListSet<Object>) getFilteredItemIds())
- .clone());
-
- // Clone property-values
- if (items == null) {
- nc.items = null;
- } else {
- nc.items = new Hashtable<Object, Map<Object, Object>>();
- for (final Iterator<?> i = items.keySet().iterator(); i.hasNext();) {
- final Object id = i.next();
- final Hashtable<Object, Object> it = (Hashtable<Object, Object>) items
- .get(id);
- nc.items.put(id, (Map<Object, Object>) it.clone());
- }
- }
-
- return nc;
- }
-
- @Override
- public void addContainerFilter(Object propertyId, String filterString,
- boolean ignoreCase, boolean onlyMatchPrefix) {
- try {
- addFilter(new SimpleStringFilter(propertyId, filterString,
- ignoreCase, onlyMatchPrefix));
- } catch (UnsupportedFilterException e) {
- // the filter instance created here is always valid for in-memory
- // containers
- }
- }
-
- @Override
- public void removeAllContainerFilters() {
- removeAllFilters();
- }
-
- @Override
- public void removeContainerFilters(Object propertyId) {
- removeFilters(propertyId);
- }
-
- @Override
- public void addContainerFilter(Filter filter)
- throws UnsupportedFilterException {
- addFilter(filter);
- }
-
- @Override
- public void removeContainerFilter(Filter filter) {
- removeFilter(filter);
- }
-
-}
diff --git a/src/com/vaadin/data/util/ItemSorter.java b/src/com/vaadin/data/util/ItemSorter.java
deleted file mode 100644
index 4399dbe292..0000000000
--- a/src/com/vaadin/data/util/ItemSorter.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Container.Sortable;
-
-/**
- * An item comparator which is compatible with the {@link Sortable} interface.
- * The <code>ItemSorter</code> interface can be used in <code>Sortable</code>
- * implementations to provide a custom sorting method.
- */
-public interface ItemSorter extends Comparator<Object>, Cloneable, Serializable {
-
- /**
- * Sets the parameters for an upcoming sort operation. The parameters
- * determine what container to sort and how the <code>ItemSorter</code>
- * sorts the container.
- *
- * @param container
- * The container that will be sorted. The container must contain
- * the propertyIds given in the <code>propertyId</code>
- * parameter.
- * @param propertyId
- * The property ids used for sorting. The property ids must exist
- * in the container and should only be used if they are also
- * sortable, i.e include in the collection returned by
- * <code>container.getSortableContainerPropertyIds()</code>. See
- * {@link Sortable#sort(Object[], boolean[])} for more
- * information.
- * @param ascending
- * Sorting order flags for each property id. See
- * {@link Sortable#sort(Object[], boolean[])} for more
- * information.
- */
- void setSortProperties(Container.Sortable container, Object[] propertyId,
- boolean[] ascending);
-
- /**
- * Compares its two arguments for order. Returns a negative integer, zero,
- * or a positive integer as the first argument is less than, equal to, or
- * greater than the second.
- * <p>
- * The parameters for the <code>ItemSorter</code> <code>compare()</code>
- * method must always be item ids which exist in the container set using
- * {@link #setSortProperties(Sortable, Object[], boolean[])}.
- *
- * @see Comparator#compare(Object, Object)
- */
- @Override
- int compare(Object itemId1, Object itemId2);
-
-}
diff --git a/src/com/vaadin/data/util/ListSet.java b/src/com/vaadin/data/util/ListSet.java
deleted file mode 100644
index b71cc46898..0000000000
--- a/src/com/vaadin/data/util/ListSet.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * ListSet is an internal Vaadin class which implements a combination of a List
- * and a Set. The main purpose of this class is to provide a list with a fast
- * {@link #contains(Object)} method. Each inserted object must by unique (as
- * specified by {@link #equals(Object)}). The {@link #set(int, Object)} method
- * allows duplicates because of the way {@link Collections#sort(java.util.List)}
- * works.
- *
- * This class is subject to change and should not be used outside Vaadin core.
- */
-public class ListSet<E> extends ArrayList<E> {
- private HashSet<E> itemSet = null;
-
- /**
- * Contains a map from an element to the number of duplicates it has. Used
- * to temporarily allow duplicates in the list.
- */
- private HashMap<E, Integer> duplicates = new HashMap<E, Integer>();
-
- public ListSet() {
- super();
- itemSet = new HashSet<E>();
- }
-
- public ListSet(Collection<? extends E> c) {
- super(c);
- itemSet = new HashSet<E>(c.size());
- itemSet.addAll(c);
- }
-
- public ListSet(int initialCapacity) {
- super(initialCapacity);
- itemSet = new HashSet<E>(initialCapacity);
- }
-
- // Delegate contains operations to the set
- @Override
- public boolean contains(Object o) {
- return itemSet.contains(o);
- }
-
- @Override
- public boolean containsAll(Collection<?> c) {
- return itemSet.containsAll(c);
- }
-
- // Methods for updating the set when the list is updated.
- @Override
- public boolean add(E e) {
- if (contains(e)) {
- // Duplicates are not allowed
- return false;
- }
-
- if (super.add(e)) {
- itemSet.add(e);
- return true;
- } else {
- return false;
- }
- };
-
- /**
- * Works as java.util.ArrayList#add(int, java.lang.Object) but returns
- * immediately if the element is already in the ListSet.
- */
- @Override
- public void add(int index, E element) {
- if (contains(element)) {
- // Duplicates are not allowed
- return;
- }
-
- super.add(index, element);
- itemSet.add(element);
- }
-
- @Override
- public boolean addAll(Collection<? extends E> c) {
- boolean modified = false;
- Iterator<? extends E> i = c.iterator();
- while (i.hasNext()) {
- E e = i.next();
- if (contains(e)) {
- continue;
- }
-
- if (add(e)) {
- itemSet.add(e);
- modified = true;
- }
- }
- return modified;
- }
-
- @Override
- public boolean addAll(int index, Collection<? extends E> c) {
- ensureCapacity(size() + c.size());
-
- boolean modified = false;
- Iterator<? extends E> i = c.iterator();
- while (i.hasNext()) {
- E e = i.next();
- if (contains(e)) {
- continue;
- }
-
- add(index++, e);
- itemSet.add(e);
- modified = true;
- }
-
- return modified;
- }
-
- @Override
- public void clear() {
- super.clear();
- itemSet.clear();
- }
-
- @Override
- public int indexOf(Object o) {
- if (!contains(o)) {
- return -1;
- }
-
- return super.indexOf(o);
- }
-
- @Override
- public int lastIndexOf(Object o) {
- if (!contains(o)) {
- return -1;
- }
-
- return super.lastIndexOf(o);
- }
-
- @Override
- public E remove(int index) {
- E e = super.remove(index);
-
- if (e != null) {
- itemSet.remove(e);
- }
-
- return e;
- }
-
- @Override
- public boolean remove(Object o) {
- if (super.remove(o)) {
- itemSet.remove(o);
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- protected void removeRange(int fromIndex, int toIndex) {
- HashSet<E> toRemove = new HashSet<E>();
- for (int idx = fromIndex; idx < toIndex; idx++) {
- toRemove.add(get(idx));
- }
- super.removeRange(fromIndex, toIndex);
- itemSet.removeAll(toRemove);
- }
-
- @Override
- public E set(int index, E element) {
- if (contains(element)) {
- // Element already exist in the list
- if (get(index) == element) {
- // At the same position, nothing to be done
- return element;
- } else {
- // Adding at another position. We assume this is a sort
- // operation and temporarily allow it.
-
- // We could just remove (null) the old element and keep the list
- // unique. This would require finding the index of the old
- // element (indexOf(element)) which is not a fast operation in a
- // list. So we instead allow duplicates temporarily.
- addDuplicate(element);
- }
- }
-
- E old = super.set(index, element);
- removeFromSet(old);
- itemSet.add(element);
-
- return old;
- }
-
- /**
- * Removes "e" from the set if it no longer exists in the list.
- *
- * @param e
- */
- private void removeFromSet(E e) {
- Integer dupl = duplicates.get(e);
- if (dupl != null) {
- // A duplicate was present so we only decrement the duplicate count
- // and continue
- if (dupl == 1) {
- // This is what always should happen. A sort sets the items one
- // by one, temporarily breaking the uniqueness requirement.
- duplicates.remove(e);
- } else {
- duplicates.put(e, dupl - 1);
- }
- } else {
- // The "old" value is no longer in the list.
- itemSet.remove(e);
- }
-
- }
-
- /**
- * Marks the "element" can be found more than once from the list. Allowed in
- * {@link #set(int, Object)} to make sorting work.
- *
- * @param element
- */
- private void addDuplicate(E element) {
- Integer nr = duplicates.get(element);
- if (nr == null) {
- nr = 1;
- } else {
- nr++;
- }
-
- /*
- * Store the number of duplicates of this element so we know later on if
- * we should remove an element from the set or if it was a duplicate (in
- * removeFromSet)
- */
- duplicates.put(element, nr);
-
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Object clone() {
- ListSet<E> v = (ListSet<E>) super.clone();
- v.itemSet = new HashSet<E>(itemSet);
- return v;
- }
-
-}
diff --git a/src/com/vaadin/data/util/MethodProperty.java b/src/com/vaadin/data/util/MethodProperty.java
deleted file mode 100644
index 0c64d90481..0000000000
--- a/src/com/vaadin/data/util/MethodProperty.java
+++ /dev/null
@@ -1,784 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Property;
-import com.vaadin.util.SerializerHelper;
-
-/**
- * <p>
- * Proxy class for creating Properties from pairs of getter and setter methods
- * of a Bean property. An instance of this class can be thought as having been
- * attached to a field of an object. Accessing the object through the Property
- * interface directly manipulates the underlying field.
- * </p>
- *
- * <p>
- * It's assumed that the return value returned by the getter method is
- * assignable to the type of the property, and the setter method parameter is
- * assignable to that value.
- * </p>
- *
- * <p>
- * A valid getter method must always be available, but instance of this class
- * can be constructed with a <code>null</code> setter method in which case the
- * resulting MethodProperty is read-only.
- * </p>
- *
- * <p>
- * MethodProperty implements Property.ValueChangeNotifier, but does not
- * automatically know whether or not the getter method will actually return a
- * new value - value change listeners are always notified when setValue is
- * called, without verifying what the getter returns.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class MethodProperty<T> extends AbstractProperty<T> {
-
- /**
- * The object that includes the property the MethodProperty is bound to.
- */
- private transient Object instance;
-
- /**
- * Argument arrays for the getter and setter methods.
- */
- private transient Object[] setArgs, getArgs;
-
- /**
- * The getter and setter methods.
- */
- private transient Method setMethod, getMethod;
-
- /**
- * Index of the new value in the argument list for the setter method. If the
- * setter method requires several parameters, this index tells which one is
- * the actual value to change.
- */
- private int setArgumentIndex;
-
- /**
- * Type of the property.
- */
- private transient Class<? extends T> type;
-
- /* Special serialization to handle method references */
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- SerializerHelper.writeClass(out, type);
- out.writeObject(instance);
- out.writeObject(setArgs);
- out.writeObject(getArgs);
- if (setMethod != null) {
- out.writeObject(setMethod.getName());
- SerializerHelper
- .writeClassArray(out, setMethod.getParameterTypes());
- } else {
- out.writeObject(null);
- out.writeObject(null);
- }
- if (getMethod != null) {
- out.writeObject(getMethod.getName());
- SerializerHelper
- .writeClassArray(out, getMethod.getParameterTypes());
- } else {
- out.writeObject(null);
- out.writeObject(null);
- }
- };
-
- /* Special serialization to handle method references */
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- try {
- @SuppressWarnings("unchecked")
- // business assumption; type parameters not checked at runtime
- Class<T> class1 = (Class<T>) SerializerHelper.readClass(in);
- type = class1;
- instance = in.readObject();
- setArgs = (Object[]) in.readObject();
- getArgs = (Object[]) in.readObject();
- String name = (String) in.readObject();
- Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
- setMethod = instance.getClass().getMethod(name, paramTypes);
- } else {
- setMethod = null;
- }
-
- name = (String) in.readObject();
- paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
- getMethod = instance.getClass().getMethod(name, paramTypes);
- } else {
- getMethod = null;
- }
- } catch (SecurityException e) {
- getLogger().log(Level.SEVERE, "Internal deserialization error", e);
- } catch (NoSuchMethodException e) {
- getLogger().log(Level.SEVERE, "Internal deserialization error", e);
- }
- };
-
- /**
- * <p>
- * Creates a new instance of <code>MethodProperty</code> from a named bean
- * property. This constructor takes an object and the name of a bean
- * property and initializes itself with the accessor methods for the
- * property.
- * </p>
- * <p>
- * The getter method of a <code>MethodProperty</code> instantiated with this
- * constructor will be called with no arguments, and the setter method with
- * only the new value as the sole argument.
- * </p>
- *
- * <p>
- * If the setter method is unavailable, the resulting
- * <code>MethodProperty</code> will be read-only, otherwise it will be
- * read-write.
- * </p>
- *
- * <p>
- * Method names are constructed from the bean property by adding
- * get/is/are/set prefix and capitalising the first character in the name of
- * the given bean property.
- * </p>
- *
- * @param instance
- * the object that includes the property.
- * @param beanPropertyName
- * the name of the property to bind to.
- */
- @SuppressWarnings("unchecked")
- public MethodProperty(Object instance, String beanPropertyName) {
-
- final Class<?> beanClass = instance.getClass();
-
- // Assure that the first letter is upper cased (it is a common
- // mistake to write firstName, not FirstName).
- if (Character.isLowerCase(beanPropertyName.charAt(0))) {
- final char[] buf = beanPropertyName.toCharArray();
- buf[0] = Character.toUpperCase(buf[0]);
- beanPropertyName = new String(buf);
- }
-
- // Find the get method
- getMethod = null;
- try {
- getMethod = initGetterMethod(beanPropertyName, beanClass);
- } catch (final java.lang.NoSuchMethodException ignored) {
- throw new MethodException(this, "Bean property " + beanPropertyName
- + " can not be found");
- }
-
- // In case the get method is found, resolve the type
- Class<?> returnType = getMethod.getReturnType();
-
- // Finds the set method
- setMethod = null;
- try {
- setMethod = beanClass.getMethod("set" + beanPropertyName,
- new Class[] { returnType });
- } catch (final java.lang.NoSuchMethodException skipped) {
- }
-
- // Gets the return type from get method
- if (returnType.isPrimitive()) {
- type = (Class<T>) convertPrimitiveType(returnType);
- if (type.isPrimitive()) {
- throw new MethodException(this, "Bean property "
- + beanPropertyName
- + " getter return type must not be void");
- }
- } else {
- type = (Class<T>) returnType;
- }
-
- setArguments(new Object[] {}, new Object[] { null }, 0);
- this.instance = instance;
- }
-
- /**
- * <p>
- * Creates a new instance of <code>MethodProperty</code> from named getter
- * and setter methods. The getter method of a <code>MethodProperty</code>
- * instantiated with this constructor will be called with no arguments, and
- * the setter method with only the new value as the sole argument.
- * </p>
- *
- * <p>
- * If the setter method is <code>null</code>, the resulting
- * <code>MethodProperty</code> will be read-only, otherwise it will be
- * read-write.
- * </p>
- *
- * @param type
- * the type of the property.
- * @param instance
- * the object that includes the property.
- * @param getMethodName
- * the name of the getter method.
- * @param setMethodName
- * the name of the setter method.
- *
- */
- public MethodProperty(Class<? extends T> type, Object instance,
- String getMethodName, String setMethodName) {
- this(type, instance, getMethodName, setMethodName, new Object[] {},
- new Object[] { null }, 0);
- }
-
- /**
- * <p>
- * Creates a new instance of <code>MethodProperty</code> with the getter and
- * setter methods. The getter method of a <code>MethodProperty</code>
- * instantiated with this constructor will be called with no arguments, and
- * the setter method with only the new value as the sole argument.
- * </p>
- *
- * <p>
- * If the setter method is <code>null</code>, the resulting
- * <code>MethodProperty</code> will be read-only, otherwise it will be
- * read-write.
- * </p>
- *
- * @param type
- * the type of the property.
- * @param instance
- * the object that includes the property.
- * @param getMethod
- * the getter method.
- * @param setMethod
- * the setter method.
- */
- public MethodProperty(Class<? extends T> type, Object instance,
- Method getMethod, Method setMethod) {
- this(type, instance, getMethod, setMethod, new Object[] {},
- new Object[] { null }, 0);
- }
-
- /**
- * <p>
- * Creates a new instance of <code>MethodProperty</code> from named getter
- * and setter methods and argument lists. The getter method of a
- * <code>MethodProperty</code> instantiated with this constructor will be
- * called with the getArgs as arguments. The setArgs will be used as the
- * arguments for the setter method, though the argument indexed by the
- * setArgumentIndex will be replaced with the argument passed to the
- * {@link #setValue(Object newValue)} method.
- * </p>
- *
- * <p>
- * For example, if the <code>setArgs</code> contains <code>A</code>,
- * <code>B</code> and <code>C</code>, and <code>setArgumentIndex =
- * 1</code>, the call <code>methodProperty.setValue(X)</code> would result
- * in the setter method to be called with the parameter set of
- * <code>{A, X, C}</code>
- * </p>
- *
- * @param type
- * the type of the property.
- * @param instance
- * the object that includes the property.
- * @param getMethodName
- * the name of the getter method.
- * @param setMethodName
- * the name of the setter method.
- * @param getArgs
- * the fixed argument list to be passed to the getter method.
- * @param setArgs
- * the fixed argument list to be passed to the setter method.
- * @param setArgumentIndex
- * the index of the argument in <code>setArgs</code> to be
- * replaced with <code>newValue</code> when
- * {@link #setValue(Object newValue)} is called.
- */
- @SuppressWarnings("unchecked")
- public MethodProperty(Class<? extends T> type, Object instance,
- String getMethodName, String setMethodName, Object[] getArgs,
- Object[] setArgs, int setArgumentIndex) {
-
- // Check the setargs and setargs index
- if (setMethodName != null && setArgs == null) {
- throw new IndexOutOfBoundsException("The setArgs can not be null");
- }
- if (setMethodName != null
- && (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length)) {
- throw new IndexOutOfBoundsException(
- "The setArgumentIndex must be >= 0 and < setArgs.length");
- }
-
- // Set type
- this.type = type;
-
- // Find set and get -methods
- final Method[] m = instance.getClass().getMethods();
-
- // Finds get method
- boolean found = false;
- for (int i = 0; i < m.length; i++) {
-
- // Tests the name of the get Method
- if (!m[i].getName().equals(getMethodName)) {
-
- // name does not match, try next method
- continue;
- }
-
- // Tests return type
- if (!type.equals(m[i].getReturnType())) {
- continue;
- }
-
- // Tests the parameter types
- final Class<?>[] c = m[i].getParameterTypes();
- if (c.length != getArgs.length) {
-
- // not the right amount of parameters, try next method
- continue;
- }
- int j = 0;
- while (j < c.length) {
- if (getArgs[j] != null
- && !c[j].isAssignableFrom(getArgs[j].getClass())) {
-
- // parameter type does not match, try next method
- break;
- }
- j++;
- }
- if (j == c.length) {
-
- // all paramteters matched
- if (found == true) {
- throw new MethodException(this,
- "Could not uniquely identify " + getMethodName
- + "-method");
- } else {
- found = true;
- getMethod = m[i];
- }
- }
- }
- if (found != true) {
- throw new MethodException(this, "Could not find " + getMethodName
- + "-method");
- }
-
- // Finds set method
- if (setMethodName != null) {
-
- // Finds setMethod
- found = false;
- for (int i = 0; i < m.length; i++) {
-
- // Checks name
- if (!m[i].getName().equals(setMethodName)) {
-
- // name does not match, try next method
- continue;
- }
-
- // Checks parameter compatibility
- final Class<?>[] c = m[i].getParameterTypes();
- if (c.length != setArgs.length) {
-
- // not the right amount of parameters, try next method
- continue;
- }
- int j = 0;
- while (j < c.length) {
- if (setArgs[j] != null
- && !c[j].isAssignableFrom(setArgs[j].getClass())) {
-
- // parameter type does not match, try next method
- break;
- } else if (j == setArgumentIndex && !c[j].equals(type)) {
-
- // Property type is not the same as setArg type
- break;
- }
- j++;
- }
- if (j == c.length) {
-
- // all parameters match
- if (found == true) {
- throw new MethodException(this,
- "Could not identify unique " + setMethodName
- + "-method");
- } else {
- found = true;
- setMethod = m[i];
- }
- }
- }
- if (found != true) {
- throw new MethodException(this, "Could not identify "
- + setMethodName + "-method");
- }
- }
-
- // Gets the return type from get method
- this.type = (Class<T>) convertPrimitiveType(type);
-
- setArguments(getArgs, setArgs, setArgumentIndex);
- this.instance = instance;
- }
-
- /**
- * <p>
- * Creates a new instance of <code>MethodProperty</code> from the getter and
- * setter methods, and argument lists.
- * </p>
- * <p>
- * This constructor behaves exactly like
- * {@link #MethodProperty(Class type, Object instance, String getMethodName, String setMethodName, Object [] getArgs, Object [] setArgs, int setArgumentIndex)}
- * except that instead of names of the getter and setter methods this
- * constructor is given the actual methods themselves.
- * </p>
- *
- * @param type
- * the type of the property.
- * @param instance
- * the object that includes the property.
- * @param getMethod
- * the getter method.
- * @param setMethod
- * the setter method.
- * @param getArgs
- * the fixed argument list to be passed to the getter method.
- * @param setArgs
- * the fixed argument list to be passed to the setter method.
- * @param setArgumentIndex
- * the index of the argument in <code>setArgs</code> to be
- * replaced with <code>newValue</code> when
- * {@link #setValue(Object newValue)} is called.
- */
- @SuppressWarnings("unchecked")
- // cannot use "Class<? extends T>" because of automatic primitive type
- // conversions
- public MethodProperty(Class<?> type, Object instance, Method getMethod,
- Method setMethod, Object[] getArgs, Object[] setArgs,
- int setArgumentIndex) {
-
- if (getMethod == null) {
- throw new MethodException(this,
- "Property GET-method cannot not be null: " + type);
- }
-
- if (setMethod != null) {
- if (setArgs == null) {
- throw new IndexOutOfBoundsException(
- "The setArgs can not be null");
- }
- if (setArgumentIndex < 0 || setArgumentIndex >= setArgs.length) {
- throw new IndexOutOfBoundsException(
- "The setArgumentIndex must be >= 0 and < setArgs.length");
- }
- }
-
- // Gets the return type from get method
- Class<? extends T> convertedType = (Class<? extends T>) convertPrimitiveType(type);
-
- this.getMethod = getMethod;
- this.setMethod = setMethod;
- setArguments(getArgs, setArgs, setArgumentIndex);
- this.instance = instance;
- this.type = convertedType;
- }
-
- /**
- * Find a getter method for a property (getXyz(), isXyz() or areXyz()).
- *
- * @param propertyName
- * name of the property
- * @param beanClass
- * class in which to look for the getter methods
- * @return Method
- * @throws NoSuchMethodException
- * if no getter found
- */
- static Method initGetterMethod(String propertyName, final Class<?> beanClass)
- throws NoSuchMethodException {
- propertyName = propertyName.substring(0, 1).toUpperCase()
- + propertyName.substring(1);
-
- Method getMethod = null;
- try {
- getMethod = beanClass.getMethod("get" + propertyName,
- new Class[] {});
- } catch (final java.lang.NoSuchMethodException ignored) {
- try {
- getMethod = beanClass.getMethod("is" + propertyName,
- new Class[] {});
- } catch (final java.lang.NoSuchMethodException ignoredAsWell) {
- getMethod = beanClass.getMethod("are" + propertyName,
- new Class[] {});
- }
- }
- return getMethod;
- }
-
- static Class<?> convertPrimitiveType(Class<?> type) {
- // Gets the return type from get method
- if (type.isPrimitive()) {
- if (type.equals(Boolean.TYPE)) {
- type = Boolean.class;
- } else if (type.equals(Integer.TYPE)) {
- type = Integer.class;
- } else if (type.equals(Float.TYPE)) {
- type = Float.class;
- } else if (type.equals(Double.TYPE)) {
- type = Double.class;
- } else if (type.equals(Byte.TYPE)) {
- type = Byte.class;
- } else if (type.equals(Character.TYPE)) {
- type = Character.class;
- } else if (type.equals(Short.TYPE)) {
- type = Short.class;
- } else if (type.equals(Long.TYPE)) {
- type = Long.class;
- }
- }
- return type;
- }
-
- /**
- * Returns the type of the Property. The methods <code>getValue</code> and
- * <code>setValue</code> must be compatible with this type: one must be able
- * to safely cast the value returned from <code>getValue</code> to the given
- * type and pass any variable assignable to this type as an argument to
- * <code>setValue</code>.
- *
- * @return type of the Property
- */
- @Override
- public final Class<? extends T> getType() {
- return type;
- }
-
- /**
- * Tests if the object is in read-only mode. In read-only mode calls to
- * <code>setValue</code> will throw <code>ReadOnlyException</code> and will
- * not modify the value of the Property.
- *
- * @return <code>true</code> if the object is in read-only mode,
- * <code>false</code> if it's not
- */
- @Override
- public boolean isReadOnly() {
- return super.isReadOnly() || (setMethod == null);
- }
-
- /**
- * Gets the value stored in the Property. The value is resolved by calling
- * the specified getter method with the argument specified at instantiation.
- *
- * @return the value of the Property
- */
- @Override
- public T getValue() {
- try {
- return (T) getMethod.invoke(instance, getArgs);
- } catch (final Throwable e) {
- throw new MethodException(this, e);
- }
- }
-
- /**
- * <p>
- * Sets the setter method and getter method argument lists.
- * </p>
- *
- * @param getArgs
- * the fixed argument list to be passed to the getter method.
- * @param setArgs
- * the fixed argument list to be passed to the setter method.
- * @param setArgumentIndex
- * the index of the argument in <code>setArgs</code> to be
- * replaced with <code>newValue</code> when
- * {@link #setValue(Object newValue)} is called.
- */
- public void setArguments(Object[] getArgs, Object[] setArgs,
- int setArgumentIndex) {
- this.getArgs = new Object[getArgs.length];
- for (int i = 0; i < getArgs.length; i++) {
- this.getArgs[i] = getArgs[i];
- }
- this.setArgs = new Object[setArgs.length];
- for (int i = 0; i < setArgs.length; i++) {
- this.setArgs[i] = setArgs[i];
- }
- this.setArgumentIndex = setArgumentIndex;
- }
-
- /**
- * Sets the value of the property.
- *
- * Note that since Vaadin 7, no conversions are performed and the value must
- * be of the correct type.
- *
- * @param newValue
- * the New value of the property.
- * @throws <code>Property.ReadOnlyException</code> if the object is in
- * read-only mode.
- * @see #invokeSetMethod(Object)
- */
- @Override
- @SuppressWarnings("unchecked")
- public void setValue(Object newValue) throws Property.ReadOnlyException {
-
- // Checks the mode
- if (isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
-
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException(
- "Invalid value type for ObjectProperty.");
- }
-
- invokeSetMethod((T) newValue);
- fireValueChange();
- }
-
- /**
- * Internal method to actually call the setter method of the wrapped
- * property.
- *
- * @param value
- */
- protected void invokeSetMethod(T value) {
-
- try {
- // Construct a temporary argument array only if needed
- if (setArgs.length == 1) {
- setMethod.invoke(instance, new Object[] { value });
- } else {
-
- // Sets the value to argument array
- final Object[] args = new Object[setArgs.length];
- for (int i = 0; i < setArgs.length; i++) {
- args[i] = (i == setArgumentIndex) ? value : setArgs[i];
- }
- setMethod.invoke(instance, args);
- }
- } catch (final InvocationTargetException e) {
- final Throwable targetException = e.getTargetException();
- throw new MethodException(this, targetException);
- } catch (final Exception e) {
- throw new MethodException(this, e);
- }
- }
-
- /**
- * <code>Exception</code> object that signals that there were problems
- * calling or finding the specified getter or setter methods of the
- * property.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("rawtypes")
- // Exceptions cannot be parameterized, ever.
- public static class MethodException extends RuntimeException {
-
- /**
- * The method property from which the exception originates from
- */
- private final Property property;
-
- /**
- * Cause of the method exception
- */
- private Throwable cause;
-
- /**
- * Constructs a new <code>MethodException</code> with the specified
- * detail message.
- *
- * @param property
- * the property.
- * @param msg
- * the detail message.
- */
- public MethodException(Property property, String msg) {
- super(msg);
- this.property = property;
- }
-
- /**
- * Constructs a new <code>MethodException</code> from another exception.
- *
- * @param property
- * the property.
- * @param cause
- * the cause of the exception.
- */
- public MethodException(Property property, Throwable cause) {
- this.property = property;
- this.cause = cause;
- }
-
- /**
- * @see java.lang.Throwable#getCause()
- */
- @Override
- public Throwable getCause() {
- return cause;
- }
-
- /**
- * Gets the method property this exception originates from.
- *
- * @return MethodProperty or null if not a valid MethodProperty
- */
- public MethodProperty getMethodProperty() {
- return (property instanceof MethodProperty) ? (MethodProperty) property
- : null;
- }
-
- /**
- * Gets the method property this exception originates from.
- *
- * @return Property from which the exception originates
- */
- public Property getProperty() {
- return property;
- }
- }
-
- /**
- * Sends a value change event to all registered listeners.
- *
- * Public for backwards compatibility, visibility may be reduced in future
- * versions.
- */
- @Override
- public void fireValueChange() {
- super.fireValueChange();
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(MethodProperty.class.getName());
- }
-}
diff --git a/src/com/vaadin/data/util/MethodPropertyDescriptor.java b/src/com/vaadin/data/util/MethodPropertyDescriptor.java
deleted file mode 100644
index a2a76ec6cf..0000000000
--- a/src/com/vaadin/data/util/MethodPropertyDescriptor.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Property;
-import com.vaadin.util.SerializerHelper;
-
-/**
- * Property descriptor that is able to create simple {@link MethodProperty}
- * instances for a bean, using given accessors.
- *
- * @param <BT>
- * bean type
- *
- * @since 6.6
- */
-public class MethodPropertyDescriptor<BT> implements
- VaadinPropertyDescriptor<BT> {
-
- private final String name;
- private Class<?> propertyType;
- private transient Method readMethod;
- private transient Method writeMethod;
-
- /**
- * Creates a property descriptor that can create MethodProperty instances to
- * access the underlying bean property.
- *
- * @param name
- * of the property
- * @param propertyType
- * type (class) of the property
- * @param readMethod
- * getter {@link Method} for the property
- * @param writeMethod
- * setter {@link Method} for the property or null if read-only
- * property
- */
- public MethodPropertyDescriptor(String name, Class<?> propertyType,
- Method readMethod, Method writeMethod) {
- this.name = name;
- this.propertyType = propertyType;
- this.readMethod = readMethod;
- this.writeMethod = writeMethod;
- }
-
- /* Special serialization to handle method references */
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- SerializerHelper.writeClass(out, propertyType);
-
- if (writeMethod != null) {
- out.writeObject(writeMethod.getName());
- SerializerHelper.writeClass(out, writeMethod.getDeclaringClass());
- SerializerHelper.writeClassArray(out,
- writeMethod.getParameterTypes());
- } else {
- out.writeObject(null);
- out.writeObject(null);
- out.writeObject(null);
- }
-
- if (readMethod != null) {
- out.writeObject(readMethod.getName());
- SerializerHelper.writeClass(out, readMethod.getDeclaringClass());
- SerializerHelper.writeClassArray(out,
- readMethod.getParameterTypes());
- } else {
- out.writeObject(null);
- out.writeObject(null);
- out.writeObject(null);
- }
- }
-
- /* Special serialization to handle method references */
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- try {
- @SuppressWarnings("unchecked")
- // business assumption; type parameters not checked at runtime
- Class<BT> class1 = (Class<BT>) SerializerHelper.readClass(in);
- propertyType = class1;
-
- String name = (String) in.readObject();
- Class<?> writeMethodClass = SerializerHelper.readClass(in);
- Class<?>[] paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
- writeMethod = writeMethodClass.getMethod(name, paramTypes);
- } else {
- writeMethod = null;
- }
-
- name = (String) in.readObject();
- Class<?> readMethodClass = SerializerHelper.readClass(in);
- paramTypes = SerializerHelper.readClassArray(in);
- if (name != null) {
- readMethod = readMethodClass.getMethod(name, paramTypes);
- } else {
- readMethod = null;
- }
- } catch (SecurityException e) {
- getLogger().log(Level.SEVERE, "Internal deserialization error", e);
- } catch (NoSuchMethodException e) {
- getLogger().log(Level.SEVERE, "Internal deserialization error", e);
- }
- };
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public Class<?> getPropertyType() {
- return propertyType;
- }
-
- @Override
- public Property<?> createProperty(Object bean) {
- return new MethodProperty<Object>(propertyType, bean, readMethod,
- writeMethod);
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(MethodPropertyDescriptor.class.getName());
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/NestedMethodProperty.java b/src/com/vaadin/data/util/NestedMethodProperty.java
deleted file mode 100644
index 9bff38456d..0000000000
--- a/src/com/vaadin/data/util/NestedMethodProperty.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.util.MethodProperty.MethodException;
-
-/**
- * Nested accessor based property for a bean.
- *
- * The property is specified in the dotted notation, e.g. "address.street", and
- * can contain multiple levels of nesting.
- *
- * When accessing the property value, all intermediate getters must return
- * non-null values.
- *
- * @see MethodProperty
- *
- * @since 6.6
- */
-public class NestedMethodProperty<T> extends AbstractProperty<T> {
-
- // needed for de-serialization
- private String propertyName;
-
- // chain of getter methods
- private transient List<Method> getMethods;
- /**
- * The setter method.
- */
- private transient Method setMethod;
-
- /**
- * Bean instance used as a starting point for accessing the property value.
- */
- private Object instance;
-
- private Class<? extends T> type;
-
- /* Special serialization to handle method references */
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- // getMethods and setMethod are reconstructed on read based on
- // propertyName
- }
-
- /* Special serialization to handle method references */
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
-
- initialize(instance.getClass(), propertyName);
- }
-
- /**
- * Constructs a nested method property for a given object instance. The
- * property name is a dot separated string pointing to a nested property,
- * e.g. "manager.address.street".
- *
- * @param instance
- * top-level bean to which the property applies
- * @param propertyName
- * dot separated nested property name
- * @throws IllegalArgumentException
- * if the property name is invalid
- */
- public NestedMethodProperty(Object instance, String propertyName) {
- this.instance = instance;
- initialize(instance.getClass(), propertyName);
- }
-
- /**
- * For internal use to deduce property type etc. without a bean instance.
- * Calling {@link #setValue(Object)} or {@link #getValue()} on properties
- * constructed this way is not supported.
- *
- * @param instanceClass
- * class of the top-level bean
- * @param propertyName
- */
- NestedMethodProperty(Class<?> instanceClass, String propertyName) {
- instance = null;
- initialize(instanceClass, propertyName);
- }
-
- /**
- * Initializes most of the internal fields based on the top-level bean
- * instance and property name (dot-separated string).
- *
- * @param beanClass
- * class of the top-level bean to which the property applies
- * @param propertyName
- * dot separated nested property name
- * @throws IllegalArgumentException
- * if the property name is invalid
- */
- private void initialize(Class<?> beanClass, String propertyName)
- throws IllegalArgumentException {
-
- List<Method> getMethods = new ArrayList<Method>();
-
- String lastSimplePropertyName = propertyName;
- Class<?> lastClass = beanClass;
-
- // first top-level property, then go deeper in a loop
- Class<?> propertyClass = beanClass;
- String[] simplePropertyNames = propertyName.split("\\.");
- if (propertyName.endsWith(".") || 0 == simplePropertyNames.length) {
- throw new IllegalArgumentException("Invalid property name '"
- + propertyName + "'");
- }
- for (int i = 0; i < simplePropertyNames.length; i++) {
- String simplePropertyName = simplePropertyNames[i].trim();
- if (simplePropertyName.length() > 0) {
- lastSimplePropertyName = simplePropertyName;
- lastClass = propertyClass;
- try {
- Method getter = MethodProperty.initGetterMethod(
- simplePropertyName, propertyClass);
- propertyClass = getter.getReturnType();
- getMethods.add(getter);
- } catch (final java.lang.NoSuchMethodException e) {
- throw new IllegalArgumentException("Bean property '"
- + simplePropertyName + "' not found", e);
- }
- } else {
- throw new IllegalArgumentException(
- "Empty or invalid bean property identifier in '"
- + propertyName + "'");
- }
- }
-
- // In case the get method is found, resolve the type
- Method lastGetMethod = getMethods.get(getMethods.size() - 1);
- Class<?> type = lastGetMethod.getReturnType();
-
- // Finds the set method
- Method setMethod = null;
- try {
- // Assure that the first letter is upper cased (it is a common
- // mistake to write firstName, not FirstName).
- if (Character.isLowerCase(lastSimplePropertyName.charAt(0))) {
- final char[] buf = lastSimplePropertyName.toCharArray();
- buf[0] = Character.toUpperCase(buf[0]);
- lastSimplePropertyName = new String(buf);
- }
-
- setMethod = lastClass.getMethod("set" + lastSimplePropertyName,
- new Class[] { type });
- } catch (final NoSuchMethodException skipped) {
- }
-
- this.type = (Class<? extends T>) MethodProperty
- .convertPrimitiveType(type);
- this.propertyName = propertyName;
- this.getMethods = getMethods;
- this.setMethod = setMethod;
- }
-
- @Override
- public Class<? extends T> getType() {
- return type;
- }
-
- @Override
- public boolean isReadOnly() {
- return super.isReadOnly() || (null == setMethod);
- }
-
- /**
- * Gets the value stored in the Property. The value is resolved by calling
- * the specified getter method with the argument specified at instantiation.
- *
- * @return the value of the Property
- */
- @Override
- public T getValue() {
- try {
- Object object = instance;
- for (Method m : getMethods) {
- object = m.invoke(object);
- }
- return (T) object;
- } catch (final Throwable e) {
- throw new MethodException(this, e);
- }
- }
-
- /**
- * Sets the value of the property. The new value must be assignable to the
- * type of this property.
- *
- * @param newValue
- * the New value of the property.
- * @throws <code>Property.ReadOnlyException</code> if the object is in
- * read-only mode.
- * @see #invokeSetMethod(Object)
- */
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- // Checks the mode
- if (isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
-
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException(
- "Invalid value type for NestedMethodProperty.");
- }
-
- invokeSetMethod((T) newValue);
- fireValueChange();
- }
-
- /**
- * Internal method to actually call the setter method of the wrapped
- * property.
- *
- * @param value
- */
- protected void invokeSetMethod(T value) {
- try {
- Object object = instance;
- for (int i = 0; i < getMethods.size() - 1; i++) {
- object = getMethods.get(i).invoke(object);
- }
- setMethod.invoke(object, new Object[] { value });
- } catch (final InvocationTargetException e) {
- throw new MethodException(this, e.getTargetException());
- } catch (final Exception e) {
- throw new MethodException(this, e);
- }
- }
-
- /**
- * Returns an unmodifiable list of getter methods to call in sequence to get
- * the property value.
- *
- * This API may change in future versions.
- *
- * @return unmodifiable list of getter methods corresponding to each segment
- * of the property name
- */
- protected List<Method> getGetMethods() {
- return Collections.unmodifiableList(getMethods);
- }
-
-}
diff --git a/src/com/vaadin/data/util/NestedPropertyDescriptor.java b/src/com/vaadin/data/util/NestedPropertyDescriptor.java
deleted file mode 100644
index b67b425d1d..0000000000
--- a/src/com/vaadin/data/util/NestedPropertyDescriptor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-
-/**
- * Property descriptor that is able to create nested property instances for a
- * bean.
- *
- * The property is specified in the dotted notation, e.g. "address.street", and
- * can contain multiple levels of nesting.
- *
- * @param <BT>
- * bean type
- *
- * @since 6.6
- */
-public class NestedPropertyDescriptor<BT> implements
- VaadinPropertyDescriptor<BT> {
-
- private final String name;
- private final Class<?> propertyType;
-
- /**
- * Creates a property descriptor that can create MethodProperty instances to
- * access the underlying bean property.
- *
- * @param name
- * of the property in a dotted path format, e.g. "address.street"
- * @param beanType
- * type (class) of the top-level bean
- * @throws IllegalArgumentException
- * if the property name is invalid
- */
- public NestedPropertyDescriptor(String name, Class<BT> beanType)
- throws IllegalArgumentException {
- this.name = name;
- NestedMethodProperty<?> property = new NestedMethodProperty<Object>(
- beanType, name);
- this.propertyType = property.getType();
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public Class<?> getPropertyType() {
- return propertyType;
- }
-
- @Override
- public Property<?> createProperty(BT bean) {
- return new NestedMethodProperty<Object>(bean, name);
- }
-
-}
diff --git a/src/com/vaadin/data/util/ObjectProperty.java b/src/com/vaadin/data/util/ObjectProperty.java
deleted file mode 100644
index cb85b44c2a..0000000000
--- a/src/com/vaadin/data/util/ObjectProperty.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-
-/**
- * A simple data object containing one typed value. This class is a
- * straightforward implementation of the the {@link com.vaadin.data.Property}
- * interface.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ObjectProperty<T> extends AbstractProperty<T> {
-
- /**
- * The value contained by the Property.
- */
- private T value;
-
- /**
- * Data type of the Property's value.
- */
- private final Class<T> type;
-
- /**
- * Creates a new instance of ObjectProperty with the given value. The type
- * of the property is automatically initialized to be the type of the given
- * value.
- *
- * @param value
- * the Initial value of the Property.
- */
- @SuppressWarnings("unchecked")
- // the cast is safe, because an object of type T has class Class<T>
- public ObjectProperty(T value) {
- this(value, (Class<T>) value.getClass());
- }
-
- /**
- * Creates a new instance of ObjectProperty with the given value and type.
- *
- * Since Vaadin 7, only values of the correct type are accepted, and no
- * automatic conversions are performed.
- *
- * @param value
- * the Initial value of the Property.
- * @param type
- * the type of the value. The value must be assignable to given
- * type.
- */
- public ObjectProperty(T value, Class<T> type) {
-
- // Set the values
- this.type = type;
- setValue(value);
- }
-
- /**
- * Creates a new instance of ObjectProperty with the given value, type and
- * read-only mode status.
- *
- * Since Vaadin 7, only the correct type of values is accepted, see
- * {@link #ObjectProperty(Object, Class)}.
- *
- * @param value
- * the Initial value of the property.
- * @param type
- * the type of the value. <code>value</code> must be assignable
- * to this type.
- * @param readOnly
- * Sets the read-only mode.
- */
- public ObjectProperty(T value, Class<T> type, boolean readOnly) {
- this(value, type);
- setReadOnly(readOnly);
- }
-
- /**
- * Returns the type of the ObjectProperty. The methods <code>getValue</code>
- * and <code>setValue</code> must be compatible with this type: one must be
- * able to safely cast the value returned from <code>getValue</code> to the
- * given type and pass any variable assignable to this type as an argument
- * to <code>setValue</code>.
- *
- * @return type of the Property
- */
- @Override
- public final Class<T> getType() {
- return type;
- }
-
- /**
- * Gets the value stored in the Property.
- *
- * @return the value stored in the Property
- */
- @Override
- public T getValue() {
- return value;
- }
-
- /**
- * Sets the value of the property.
- *
- * Note that since Vaadin 7, no conversions are performed and the value must
- * be of the correct type.
- *
- * @param newValue
- * the New value of the property.
- * @throws <code>Property.ReadOnlyException</code> if the object is in
- * read-only mode
- */
- @Override
- @SuppressWarnings("unchecked")
- public void setValue(Object newValue) throws Property.ReadOnlyException {
-
- // Checks the mode
- if (isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
-
- // Checks the type of the value
- if (newValue != null && !type.isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException("Invalid value type "
- + newValue.getClass().getName()
- + " for ObjectProperty of type " + type.getName() + ".");
- }
-
- // the cast is safe after an isAssignableFrom check
- this.value = (T) newValue;
-
- fireValueChange();
- }
-}
diff --git a/src/com/vaadin/data/util/PropertyFormatter.java b/src/com/vaadin/data/util/PropertyFormatter.java
deleted file mode 100644
index 3d65726309..0000000000
--- a/src/com/vaadin/data/util/PropertyFormatter.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.util.converter.Converter;
-
-/**
- * Formatting proxy for a {@link Property}.
- *
- * <p>
- * This class can be used to implement formatting for any type of Property
- * datasources. The idea is to connect this as proxy between UI component and
- * the original datasource.
- * </p>
- *
- * <p>
- * For example <code>
- * <pre>textfield.setPropertyDataSource(new PropertyFormatter(property) {
- public String format(Object value) {
- return ((Double) value).toString() + "000000000";
- }
-
- public Object parse(String formattedValue) throws Exception {
- return Double.parseDouble(formattedValue);
- }
-
- });</pre></code> adds formatter for Double-typed property that extends
- * standard "1.0" notation with more zeroes.
- * </p>
- *
- * @param T
- * type of the underlying property (a PropertyFormatter is always a
- * Property&lt;String&gt;)
- *
- * @deprecated Since 7.0 replaced by {@link Converter}
- * @author Vaadin Ltd.
- * @since 5.3.0
- */
-@SuppressWarnings("serial")
-@Deprecated
-public abstract class PropertyFormatter<T> extends AbstractProperty<String>
- implements Property.Viewer, Property.ValueChangeListener,
- Property.ReadOnlyStatusChangeListener {
-
- /** Datasource that stores the actual value. */
- Property<T> dataSource;
-
- /**
- * Construct a new {@code PropertyFormatter} that is not connected to any
- * data source. Call {@link #setPropertyDataSource(Property)} later on to
- * attach it to a property.
- *
- */
- protected PropertyFormatter() {
- }
-
- /**
- * Construct a new formatter that is connected to given data source. Calls
- * {@link #format(Object)} which can be a problem if the formatter has not
- * yet been initialized.
- *
- * @param propertyDataSource
- * to connect this property to.
- */
- public PropertyFormatter(Property<T> propertyDataSource) {
-
- setPropertyDataSource(propertyDataSource);
- }
-
- /**
- * Gets the current data source of the formatter, if any.
- *
- * @return the current data source as a Property, or <code>null</code> if
- * none defined.
- */
- @Override
- public Property<T> getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- * Sets the specified Property as the data source for the formatter.
- *
- *
- * <p>
- * Remember that new data sources getValue() must return objects that are
- * compatible with parse() and format() methods.
- * </p>
- *
- * @param newDataSource
- * the new data source Property.
- */
- @Override
- public void setPropertyDataSource(Property newDataSource) {
-
- boolean readOnly = false;
- String prevValue = null;
-
- if (dataSource != null) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource)
- .removeListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeListener) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .removeListener(this);
- }
- readOnly = isReadOnly();
- prevValue = getValue();
- }
-
- dataSource = newDataSource;
-
- if (dataSource != null) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource).addListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeListener) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .addListener(this);
- }
- }
-
- if (isReadOnly() != readOnly) {
- fireReadOnlyStatusChange();
- }
- String newVal = getValue();
- if ((prevValue == null && newVal != null)
- || (prevValue != null && !prevValue.equals(newVal))) {
- fireValueChange();
- }
- }
-
- /* Documented in the interface */
- @Override
- public Class<String> getType() {
- return String.class;
- }
-
- /**
- * Get the formatted value.
- *
- * @return If the datasource returns null, this is null. Otherwise this is
- * String given by format().
- */
- @Override
- public String getValue() {
- T value = dataSource == null ? null : dataSource.getValue();
- if (value == null) {
- return null;
- }
- return format(value);
- }
-
- /** Reflects the read-only status of the datasource. */
- @Override
- public boolean isReadOnly() {
- return dataSource == null ? false : dataSource.isReadOnly();
- }
-
- /**
- * This method must be implemented to format the values received from
- * DataSource.
- *
- * @param value
- * Value object got from the datasource. This is guaranteed to be
- * non-null and of the type compatible with getType() of the
- * datasource.
- * @return
- */
- abstract public String format(T value);
-
- /**
- * Parse string and convert it to format compatible with datasource.
- *
- * The method is required to assure that parse(format(x)) equals x.
- *
- * @param formattedValue
- * This is guaranteed to be non-null string.
- * @return Non-null value compatible with datasource.
- * @throws Exception
- * Any type of exception can be thrown to indicate that the
- * conversion was not succesful.
- */
- abstract public T parse(String formattedValue) throws Exception;
-
- /**
- * Sets the Property's read-only mode to the specified status.
- *
- * @param newStatus
- * the new read-only status of the Property.
- */
- @Override
- public void setReadOnly(boolean newStatus) {
- if (dataSource != null) {
- dataSource.setReadOnly(newStatus);
- }
- }
-
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- if (dataSource == null) {
- return;
- }
- if (newValue == null) {
- if (dataSource.getValue() != null) {
- dataSource.setValue(null);
- fireValueChange();
- }
- } else {
- try {
- dataSource.setValue(parse(newValue.toString()));
- if (!newValue.equals(getValue())) {
- fireValueChange();
- }
- } catch (Exception e) {
- throw new IllegalArgumentException("Could not parse value", e);
- }
- }
- }
-
- /**
- * Listens for changes in the datasource.
- *
- * This should not be called directly.
- */
- @Override
- public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
- fireValueChange();
- }
-
- /**
- * Listens for changes in the datasource.
- *
- * This should not be called directly.
- */
- @Override
- public void readOnlyStatusChange(
- com.vaadin.data.Property.ReadOnlyStatusChangeEvent event) {
- fireReadOnlyStatusChange();
- }
-
-}
diff --git a/src/com/vaadin/data/util/PropertysetItem.java b/src/com/vaadin/data/util/PropertysetItem.java
deleted file mode 100644
index 22f2da75b2..0000000000
--- a/src/com/vaadin/data/util/PropertysetItem.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * Class for handling a set of identified Properties. The elements contained in
- * a </code>MapItem</code> can be referenced using locally unique identifiers.
- * The class supports listeners who are interested in changes to the Property
- * set managed by the class.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
- Cloneable {
-
- /* Private representation of the item */
-
- /**
- * Mapping from property id to property.
- */
- private HashMap<Object, Property<?>> map = new HashMap<Object, Property<?>>();
-
- /**
- * List of all property ids to maintain the order.
- */
- private LinkedList<Object> list = new LinkedList<Object>();
-
- /**
- * List of property set modification listeners.
- */
- private LinkedList<Item.PropertySetChangeListener> propertySetChangeListeners = null;
-
- /* Item methods */
-
- /**
- * Gets the Property corresponding to the given Property ID stored in the
- * Item. If the Item does not contain the Property, <code>null</code> is
- * returned.
- *
- * @param id
- * the identifier of the Property to get.
- * @return the Property with the given ID or <code>null</code>
- */
- @Override
- public Property<?> getItemProperty(Object id) {
- return map.get(id);
- }
-
- /**
- * Gets the collection of IDs of all Properties stored in the Item.
- *
- * @return unmodifiable collection containing IDs of the Properties stored
- * the Item
- */
- @Override
- public Collection<?> getItemPropertyIds() {
- return Collections.unmodifiableCollection(list);
- }
-
- /* Item.Managed methods */
-
- /**
- * Removes the Property identified by ID from the Item. This functionality
- * is optional. If the method is not implemented, the method always returns
- * <code>false</code>.
- *
- * @param id
- * the ID of the Property to be removed.
- * @return <code>true</code> if the operation succeeded <code>false</code>
- * if not
- */
- @Override
- public boolean removeItemProperty(Object id) {
-
- // Cant remove missing properties
- if (map.remove(id) == null) {
- return false;
- }
- list.remove(id);
-
- // Send change events
- fireItemPropertySetChange();
-
- return true;
- }
-
- /**
- * Tries to add a new Property into the Item.
- *
- * @param id
- * the ID of the new Property.
- * @param property
- * the Property to be added and associated with the id.
- * @return <code>true</code> if the operation succeeded, <code>false</code>
- * if not
- */
- @Override
- public boolean addItemProperty(Object id, Property property) {
-
- // Null ids are not accepted
- if (id == null) {
- throw new NullPointerException("Item property id can not be null");
- }
-
- // Cant add a property twice
- if (map.containsKey(id)) {
- return false;
- }
-
- // Put the property to map
- map.put(id, property);
- list.add(id);
-
- // Send event
- fireItemPropertySetChange();
-
- return true;
- }
-
- /**
- * Gets the <code>String</code> representation of the contents of the Item.
- * The format of the string is a space separated catenation of the
- * <code>String</code> representations of the Properties contained by the
- * Item.
- *
- * @return <code>String</code> representation of the Item contents
- */
- @Override
- public String toString() {
- String retValue = "";
-
- for (final Iterator<?> i = getItemPropertyIds().iterator(); i.hasNext();) {
- final Object propertyId = i.next();
- retValue += getItemProperty(propertyId).getValue();
- if (i.hasNext()) {
- retValue += " ";
- }
- }
-
- return retValue;
- }
-
- /* Notifiers */
-
- /**
- * An <code>event</code> object specifying an Item whose Property set has
- * changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- private static class PropertySetChangeEvent extends EventObject implements
- Item.PropertySetChangeEvent {
-
- private PropertySetChangeEvent(Item source) {
- super(source);
- }
-
- /**
- * Gets the Item whose Property set has changed.
- *
- * @return source object of the event as an <code>Item</code>
- */
- @Override
- public Item getItem() {
- return (Item) getSource();
- }
- }
-
- /**
- * Registers a new property set change listener for this Item.
- *
- * @param listener
- * the new Listener to be registered.
- */
- @Override
- public void addListener(Item.PropertySetChangeListener listener) {
- if (propertySetChangeListeners == null) {
- propertySetChangeListeners = new LinkedList<PropertySetChangeListener>();
- }
- propertySetChangeListeners.add(listener);
- }
-
- /**
- * Removes a previously registered property set change listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- @Override
- public void removeListener(Item.PropertySetChangeListener listener) {
- if (propertySetChangeListeners != null) {
- propertySetChangeListeners.remove(listener);
- }
- }
-
- /**
- * Sends a Property set change event to all interested listeners.
- */
- private void fireItemPropertySetChange() {
- if (propertySetChangeListeners != null) {
- final Object[] l = propertySetChangeListeners.toArray();
- final Item.PropertySetChangeEvent event = new PropertysetItem.PropertySetChangeEvent(
- this);
- for (int i = 0; i < l.length; i++) {
- ((Item.PropertySetChangeListener) l[i])
- .itemPropertySetChange(event);
- }
- }
- }
-
- public Collection<?> getListeners(Class<?> eventType) {
- if (Item.PropertySetChangeEvent.class.isAssignableFrom(eventType)) {
- if (propertySetChangeListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(propertySetChangeListeners);
- }
- }
-
- return Collections.EMPTY_LIST;
- }
-
- /**
- * Creates and returns a copy of this object.
- * <p>
- * The method <code>clone</code> performs a shallow copy of the
- * <code>PropertysetItem</code>.
- * </p>
- * <p>
- * Note : All arrays are considered to implement the interface Cloneable.
- * Otherwise, this method creates a new instance of the class of this object
- * and initializes all its fields with exactly the contents of the
- * corresponding fields of this object, as if by assignment, the contents of
- * the fields are not themselves cloned. Thus, this method performs a
- * "shallow copy" of this object, not a "deep copy" operation.
- * </p>
- *
- * @throws CloneNotSupportedException
- * if the object's class does not support the Cloneable
- * interface.
- *
- * @see java.lang.Object#clone()
- */
- @Override
- public Object clone() throws CloneNotSupportedException {
-
- final PropertysetItem npsi = new PropertysetItem();
-
- npsi.list = list != null ? (LinkedList<Object>) list.clone() : null;
- npsi.propertySetChangeListeners = propertySetChangeListeners != null ? (LinkedList<PropertySetChangeListener>) propertySetChangeListeners
- .clone() : null;
- npsi.map = (HashMap<Object, Property<?>>) map.clone();
-
- return npsi;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
-
- if (obj == null || !(obj instanceof PropertysetItem)) {
- return false;
- }
-
- final PropertysetItem other = (PropertysetItem) obj;
-
- if (other.list != list) {
- if (other.list == null) {
- return false;
- }
- if (!other.list.equals(list)) {
- return false;
- }
- }
- if (other.map != map) {
- if (other.map == null) {
- return false;
- }
- if (!other.map.equals(map)) {
- return false;
- }
- }
- if (other.propertySetChangeListeners != propertySetChangeListeners) {
- boolean thisEmpty = (propertySetChangeListeners == null || propertySetChangeListeners
- .isEmpty());
- boolean otherEmpty = (other.propertySetChangeListeners == null || other.propertySetChangeListeners
- .isEmpty());
- if (thisEmpty && otherEmpty) {
- return true;
- }
- if (otherEmpty) {
- return false;
- }
- if (!other.propertySetChangeListeners
- .equals(propertySetChangeListeners)) {
- return false;
- }
- }
-
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
-
- return (list == null ? 0 : list.hashCode())
- ^ (map == null ? 0 : map.hashCode())
- ^ ((propertySetChangeListeners == null || propertySetChangeListeners
- .isEmpty()) ? 0 : propertySetChangeListeners.hashCode());
- }
-}
diff --git a/src/com/vaadin/data/util/QueryContainer.java b/src/com/vaadin/data/util/QueryContainer.java
deleted file mode 100644
index dc7c883a7e..0000000000
--- a/src/com/vaadin/data/util/QueryContainer.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * <p>
- * The <code>QueryContainer</code> is the specialized form of Container which is
- * Ordered and Indexed. This is used to represent the contents of relational
- * database tables accessed through the JDBC Connection in the Vaadin Table.
- * This creates Items based on the queryStatement provided to the container.
- * </p>
- *
- * <p>
- * The <code>QueryContainer</code> can be visualized as a representation of a
- * relational database table.Each Item in the container represents the row
- * fetched by the query.All cells in a column have same data type and the data
- * type information is retrieved from the metadata of the resultset.
- * </p>
- *
- * <p>
- * Note : If data in the tables gets modified, Container will not get reflected
- * with the updates, we have to explicity invoke QueryContainer.refresh method.
- * {@link com.vaadin.data.util.QueryContainer#refresh() refresh()}
- * </p>
- *
- * @see com.vaadin.data.Container
- *
- * @author Vaadin Ltd.
- * @version
- * @since 4.0
- *
- * @deprecated will be removed in the future, use the SQLContainer add-on
- */
-
-@Deprecated
-@SuppressWarnings("serial")
-public class QueryContainer implements Container, Container.Ordered,
- Container.Indexed {
-
- // default ResultSet type
- public static final int DEFAULT_RESULTSET_TYPE = ResultSet.TYPE_SCROLL_INSENSITIVE;
-
- // default ResultSet concurrency
- public static final int DEFAULT_RESULTSET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
-
- private int resultSetType = DEFAULT_RESULTSET_TYPE;
-
- private int resultSetConcurrency = DEFAULT_RESULTSET_CONCURRENCY;
-
- private final String queryStatement;
-
- private final Connection connection;
-
- private ResultSet result;
-
- private Collection<String> propertyIds;
-
- private final HashMap<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>();
-
- private int size = -1;
-
- private Statement statement;
-
- /**
- * Constructs new <code>QueryContainer</code> with the specified
- * <code>queryStatement</code>.
- *
- * @param queryStatement
- * Database query
- * @param connection
- * Connection object
- * @param resultSetType
- * @param resultSetConcurrency
- * @throws SQLException
- * when database operation fails
- */
- public QueryContainer(String queryStatement, Connection connection,
- int resultSetType, int resultSetConcurrency) throws SQLException {
- this.queryStatement = queryStatement;
- this.connection = connection;
- this.resultSetType = resultSetType;
- this.resultSetConcurrency = resultSetConcurrency;
- init();
- }
-
- /**
- * Constructs new <code>QueryContainer</code> with the specified
- * queryStatement using the default resultset type and default resultset
- * concurrency.
- *
- * @param queryStatement
- * Database query
- * @param connection
- * Connection object
- * @see QueryContainer#DEFAULT_RESULTSET_TYPE
- * @see QueryContainer#DEFAULT_RESULTSET_CONCURRENCY
- * @throws SQLException
- * when database operation fails
- */
- public QueryContainer(String queryStatement, Connection connection)
- throws SQLException {
- this(queryStatement, connection, DEFAULT_RESULTSET_TYPE,
- DEFAULT_RESULTSET_CONCURRENCY);
- }
-
- /**
- * Fills the Container with the items and properties. Invoked by the
- * constructor.
- *
- * @throws SQLException
- * when parameter initialization fails.
- * @see QueryContainer#QueryContainer(String, Connection, int, int).
- */
- private void init() throws SQLException {
- refresh();
- ResultSetMetaData metadata;
- metadata = result.getMetaData();
- final int count = metadata.getColumnCount();
- final ArrayList<String> list = new ArrayList<String>(count);
- for (int i = 1; i <= count; i++) {
- final String columnName = metadata.getColumnName(i);
- list.add(columnName);
- final Property<?> p = getContainerProperty(new Integer(1),
- columnName);
- propertyTypes.put(columnName,
- p == null ? Object.class : p.getType());
- }
- propertyIds = Collections.unmodifiableCollection(list);
- }
-
- /**
- * <p>
- * Restores items in the container. This method will update the latest data
- * to the container.
- * </p>
- * Note: This method should be used to update the container with the latest
- * items.
- *
- * @throws SQLException
- * when database operation fails
- *
- */
-
- public void refresh() throws SQLException {
- close();
- statement = connection.createStatement(resultSetType,
- resultSetConcurrency);
- result = statement.executeQuery(queryStatement);
- result.last();
- size = result.getRow();
- }
-
- /**
- * Releases and nullifies the <code>statement</code>.
- *
- * @throws SQLException
- * when database operation fails
- */
-
- public void close() throws SQLException {
- if (statement != null) {
- statement.close();
- }
- statement = null;
- }
-
- /**
- * Gets the Item with the given Item ID from the Container.
- *
- * @param id
- * ID of the Item to retrieve
- * @return Item Id.
- */
-
- @Override
- public Item getItem(Object id) {
- return new Row(id);
- }
-
- /**
- * Gets the collection of propertyId from the Container.
- *
- * @return Collection of Property ID.
- */
-
- @Override
- public Collection<String> getContainerPropertyIds() {
- return propertyIds;
- }
-
- /**
- * Gets an collection of all the item IDs in the container.
- *
- * @return collection of Item IDs
- */
- @Override
- public Collection<?> getItemIds() {
- final Collection<Integer> c = new ArrayList<Integer>(size);
- for (int i = 1; i <= size; i++) {
- c.add(new Integer(i));
- }
- return c;
- }
-
- /**
- * Gets the property identified by the given itemId and propertyId from the
- * container. If the container does not contain the property
- * <code>null</code> is returned.
- *
- * @param itemId
- * ID of the Item which contains the Property
- * @param propertyId
- * ID of the Property to retrieve
- *
- * @return Property with the given ID if exists; <code>null</code>
- * otherwise.
- */
-
- @Override
- public synchronized Property<?> getContainerProperty(Object itemId,
- Object propertyId) {
- if (!(itemId instanceof Integer && propertyId instanceof String)) {
- return null;
- }
- Object value;
- try {
- result.absolute(((Integer) itemId).intValue());
- value = result.getObject((String) propertyId);
- } catch (final Exception e) {
- return null;
- }
-
- // Handle also null values from the database
- return new ObjectProperty<Object>(value != null ? value
- : new String(""));
- }
-
- /**
- * Gets the data type of all properties identified by the given type ID.
- *
- * @param id
- * ID identifying the Properties
- *
- * @return data type of the Properties
- */
-
- @Override
- public Class<?> getType(Object id) {
- return propertyTypes.get(id);
- }
-
- /**
- * Gets the number of items in the container.
- *
- * @return the number of items in the container.
- */
- @Override
- public int size() {
- return size;
- }
-
- /**
- * Tests if the list contains the specified Item.
- *
- * @param id
- * ID the of Item to be tested.
- * @return <code>true</code> if given id is in the container;
- * <code>false</code> otherwise.
- */
- @Override
- public boolean containsId(Object id) {
- if (!(id instanceof Integer)) {
- return false;
- }
- final int i = ((Integer) id).intValue();
- if (i < 1) {
- return false;
- }
- if (i > size) {
- return false;
- }
- return true;
- }
-
- /**
- * Creates new Item with the given ID into the Container.
- *
- * @param itemId
- * ID of the Item to be created.
- *
- * @return Created new Item, or <code>null</code> if it fails.
- *
- * @throws UnsupportedOperationException
- * if the addItem method is not supported.
- */
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Creates a new Item into the Container, and assign it an ID.
- *
- * @return ID of the newly created Item, or <code>null</code> if it fails.
- * @throws UnsupportedOperationException
- * if the addItem method is not supported.
- */
- @Override
- public Object addItem() throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Removes the Item identified by ItemId from the Container.
- *
- * @param itemId
- * ID of the Item to remove.
- * @return <code>true</code> if the operation succeeded; <code>false</code>
- * otherwise.
- * @throws UnsupportedOperationException
- * if the removeItem method is not supported.
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Adds new Property to all Items in the Container.
- *
- * @param propertyId
- * ID of the Property
- * @param type
- * Data type of the new Property
- * @param defaultValue
- * The value all created Properties are initialized to.
- * @return <code>true</code> if the operation succeeded; <code>false</code>
- * otherwise.
- * @throws UnsupportedOperationException
- * if the addContainerProperty method is not supported.
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Removes a Property specified by the given Property ID from the Container.
- *
- * @param propertyId
- * ID of the Property to remove
- * @return <code>true</code> if the operation succeeded; <code>false</code>
- * otherwise.
- * @throws UnsupportedOperationException
- * if the removeContainerProperty method is not supported.
- */
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Removes all Items from the Container.
- *
- * @return <code>true</code> if the operation succeeded; <code>false</code>
- * otherwise.
- * @throws UnsupportedOperationException
- * if the removeAllItems method is not supported.
- */
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Adds new item after the given item.
- *
- * @param previousItemId
- * Id of the previous item in ordered container.
- * @param newItemId
- * Id of the new item to be added.
- * @return Returns new item or <code>null</code> if the operation fails.
- * @throws UnsupportedOperationException
- * if the addItemAfter method is not supported.
- */
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Adds new item after the given item.
- *
- * @param previousItemId
- * Id of the previous item in ordered container.
- * @return Returns item id created new item or <code>null</code> if the
- * operation fails.
- * @throws UnsupportedOperationException
- * if the addItemAfter method is not supported.
- */
- @Override
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns id of first item in the Container.
- *
- * @return ID of the first Item in the list.
- */
- @Override
- public Object firstItemId() {
- if (size < 1) {
- return null;
- }
- return new Integer(1);
- }
-
- /**
- * Returns <code>true</code> if given id is first id at first index.
- *
- * @param id
- * ID of an Item in the Container.
- */
- @Override
- public boolean isFirstId(Object id) {
- return size > 0 && (id instanceof Integer)
- && ((Integer) id).intValue() == 1;
- }
-
- /**
- * Returns <code>true</code> if given id is last id at last index.
- *
- * @param id
- * ID of an Item in the Container
- *
- */
- @Override
- public boolean isLastId(Object id) {
- return size > 0 && (id instanceof Integer)
- && ((Integer) id).intValue() == size;
- }
-
- /**
- * Returns id of last item in the Container.
- *
- * @return ID of the last Item.
- */
- @Override
- public Object lastItemId() {
- if (size < 1) {
- return null;
- }
- return new Integer(size);
- }
-
- /**
- * Returns id of next item in container at next index.
- *
- * @param id
- * ID of an Item in the Container.
- * @return ID of the next Item or null.
- */
- @Override
- public Object nextItemId(Object id) {
- if (size < 1 || !(id instanceof Integer)) {
- return null;
- }
- final int i = ((Integer) id).intValue();
- if (i >= size) {
- return null;
- }
- return new Integer(i + 1);
- }
-
- /**
- * Returns id of previous item in container at previous index.
- *
- * @param id
- * ID of an Item in the Container.
- * @return ID of the previous Item or null.
- */
- @Override
- public Object prevItemId(Object id) {
- if (size < 1 || !(id instanceof Integer)) {
- return null;
- }
- final int i = ((Integer) id).intValue();
- if (i <= 1) {
- return null;
- }
- return new Integer(i - 1);
- }
-
- /**
- * The <code>Row</code> class implements methods of Item.
- *
- * @author Vaadin Ltd.
- * @version
- * @since 4.0
- */
- class Row implements Item {
-
- Object id;
-
- private Row(Object rowId) {
- id = rowId;
- }
-
- /**
- * Adds the item property.
- *
- * @param id
- * ID of the new Property.
- * @param property
- * Property to be added and associated with ID.
- * @return <code>true</code> if the operation succeeded;
- * <code>false</code> otherwise.
- * @throws UnsupportedOperationException
- * if the addItemProperty method is not supported.
- */
- @Override
- public boolean addItemProperty(Object id, Property property)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Gets the property corresponding to the given property ID stored in
- * the Item.
- *
- * @param propertyId
- * identifier of the Property to get
- * @return the Property with the given ID or <code>null</code>
- */
- @Override
- public Property<?> getItemProperty(Object propertyId) {
- return getContainerProperty(id, propertyId);
- }
-
- /**
- * Gets the collection of property IDs stored in the Item.
- *
- * @return unmodifiable collection containing IDs of the Properties
- * stored the Item.
- */
- @Override
- public Collection<String> getItemPropertyIds() {
- return propertyIds;
- }
-
- /**
- * Removes given item property.
- *
- * @param id
- * ID of the Property to be removed.
- * @return <code>true</code> if the item property is removed;
- * <code>false</code> otherwise.
- * @throws UnsupportedOperationException
- * if the removeItemProperty is not supported.
- */
- @Override
- public boolean removeItemProperty(Object id)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- }
-
- /**
- * Closes the statement.
- *
- * @see #close()
- */
- @Override
- public void finalize() {
- try {
- close();
- } catch (final SQLException ignored) {
-
- }
- }
-
- /**
- * Adds the given item at the position of given index.
- *
- * @param index
- * Index to add the new item.
- * @param newItemId
- * Id of the new item to be added.
- * @return new item or <code>null</code> if the operation fails.
- * @throws UnsupportedOperationException
- * if the addItemAt is not supported.
- */
- @Override
- public Item addItemAt(int index, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Adds item at the position of provided index in the container.
- *
- * @param index
- * Index to add the new item.
- * @return item id created new item or <code>null</code> if the operation
- * fails.
- *
- * @throws UnsupportedOperationException
- * if the addItemAt is not supported.
- */
-
- @Override
- public Object addItemAt(int index) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Gets the Index id in the container.
- *
- * @param index
- * Index Id.
- * @return ID in the given index.
- */
- @Override
- public Object getIdByIndex(int index) {
- if (size < 1 || index < 0 || index >= size) {
- return null;
- }
- return new Integer(index + 1);
- }
-
- /**
- * Gets the index of the Item corresponding to id in the container.
- *
- * @param id
- * ID of an Item in the Container
- * @return index of the Item, or -1 if the Container does not include the
- * Item
- */
-
- @Override
- public int indexOfId(Object id) {
- if (size < 1 || !(id instanceof Integer)) {
- return -1;
- }
- final int i = ((Integer) id).intValue();
- if (i >= size || i < 1) {
- return -1;
- }
- return i - 1;
- }
-
-}
diff --git a/src/com/vaadin/data/util/TextFileProperty.java b/src/com/vaadin/data/util/TextFileProperty.java
deleted file mode 100644
index 598b721a9c..0000000000
--- a/src/com/vaadin/data/util/TextFileProperty.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.nio.charset.Charset;
-
-/**
- * Property implementation for wrapping a text file.
- *
- * Supports reading and writing of a File from/to String.
- *
- * {@link ValueChangeListener}s are supported, but only fire when
- * setValue(Object) is explicitly called. {@link ReadOnlyStatusChangeListener}s
- * are supported but only fire when setReadOnly(boolean) is explicitly called.
- *
- */
-@SuppressWarnings("serial")
-public class TextFileProperty extends AbstractProperty<String> {
-
- private File file;
- private Charset charset = null;
-
- /**
- * Wrap given file with property interface.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- */
- public TextFileProperty(File file) {
- this.file = file;
- }
-
- /**
- * Wrap the given file with the property interface and specify character
- * set.
- *
- * Setting the file to null works, but getValue() will return null.
- *
- * @param file
- * File to be wrapped.
- * @param charset
- * Charset to be used for reading and writing the file.
- */
- public TextFileProperty(File file, Charset charset) {
- this.file = file;
- this.charset = charset;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getType()
- */
- @Override
- public Class<String> getType() {
- return String.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#getValue()
- */
- @Override
- public String getValue() {
- if (file == null) {
- return null;
- }
- try {
- FileInputStream fis = new FileInputStream(file);
- InputStreamReader isr = charset == null ? new InputStreamReader(fis)
- : new InputStreamReader(fis, charset);
- BufferedReader r = new BufferedReader(isr);
- StringBuilder b = new StringBuilder();
- char buf[] = new char[8 * 1024];
- int len;
- while ((len = r.read(buf)) != -1) {
- b.append(buf, 0, len);
- }
- r.close();
- isr.close();
- fis.close();
- return b.toString();
- } catch (FileNotFoundException e) {
- return null;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#isReadOnly()
- */
- @Override
- public boolean isReadOnly() {
- return file == null || super.isReadOnly() || !file.canWrite();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Property#setValue(java.lang.Object)
- */
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- if (isReadOnly()) {
- throw new ReadOnlyException();
- }
- if (file == null) {
- return;
- }
-
- try {
- FileOutputStream fos = new FileOutputStream(file);
- OutputStreamWriter osw = charset == null ? new OutputStreamWriter(
- fos) : new OutputStreamWriter(fos, charset);
- BufferedWriter w = new BufferedWriter(osw);
- w.append(newValue.toString());
- w.flush();
- w.close();
- osw.close();
- fos.close();
- fireValueChange();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java b/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
deleted file mode 100644
index d042bfaac2..0000000000
--- a/src/com/vaadin/data/util/TransactionalPropertyWrapper.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.Property.ValueChangeEvent;
-import com.vaadin.data.Property.ValueChangeNotifier;
-
-/**
- * Wrapper class that helps implement two-phase commit for a non-transactional
- * property.
- *
- * When accessing the property through the wrapper, getting and setting the
- * property value take place immediately. However, the wrapper keeps track of
- * the old value of the property so that it can be set for the property in case
- * of a roll-back. This can result in the underlying property value changing
- * multiple times (first based on modifications made by the application, then
- * back upon roll-back).
- *
- * Value change events on the {@link TransactionalPropertyWrapper} are only
- * fired at the end of a successful transaction, whereas listeners attached to
- * the underlying property may receive multiple value change events.
- *
- * @see com.vaadin.data.Property.Transactional
- *
- * @author Vaadin Ltd
- * @version @version@
- * @since 7.0
- *
- * @param <T>
- */
-public class TransactionalPropertyWrapper<T> extends AbstractProperty<T>
- implements ValueChangeNotifier, Property.Transactional<T> {
-
- private Property<T> wrappedProperty;
- private boolean inTransaction = false;
- private boolean valueChangePending;
- private T valueBeforeTransaction;
-
- public TransactionalPropertyWrapper(Property<T> wrappedProperty) {
- this.wrappedProperty = wrappedProperty;
- if (wrappedProperty instanceof ValueChangeNotifier) {
- ((ValueChangeNotifier) wrappedProperty)
- .addListener(new ValueChangeListener() {
-
- @Override
- public void valueChange(ValueChangeEvent event) {
- fireValueChange();
- }
- });
- }
- }
-
- @Override
- public Class getType() {
- return wrappedProperty.getType();
- }
-
- @Override
- public T getValue() {
- return wrappedProperty.getValue();
- }
-
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- // Causes a value change to be sent to this listener which in turn fires
- // a new value change event for this property
- wrappedProperty.setValue(newValue);
- }
-
- @Override
- public void startTransaction() {
- inTransaction = true;
- valueBeforeTransaction = getValue();
- }
-
- @Override
- public void commit() {
- endTransaction();
- }
-
- @Override
- public void rollback() {
- try {
- wrappedProperty.setValue(valueBeforeTransaction);
- } finally {
- valueChangePending = false;
- endTransaction();
- }
- }
-
- protected void endTransaction() {
- inTransaction = false;
- valueBeforeTransaction = null;
- if (valueChangePending) {
- fireValueChange();
- }
- }
-
- @Override
- protected void fireValueChange() {
- if (inTransaction) {
- valueChangePending = true;
- } else {
- super.fireValueChange();
- }
- }
-
- public Property<T> getWrappedProperty() {
- return wrappedProperty;
- }
-
-}
diff --git a/src/com/vaadin/data/util/VaadinPropertyDescriptor.java b/src/com/vaadin/data/util/VaadinPropertyDescriptor.java
deleted file mode 100644
index ee1e525540..0000000000
--- a/src/com/vaadin/data/util/VaadinPropertyDescriptor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util;
-
-import java.io.Serializable;
-
-import com.vaadin.data.Property;
-
-/**
- * Property descriptor that can create a property instance for a bean.
- *
- * Used by {@link BeanItem} and {@link AbstractBeanContainer} to keep track of
- * the set of properties of items.
- *
- * @param <BT>
- * bean type
- *
- * @since 6.6
- */
-public interface VaadinPropertyDescriptor<BT> extends Serializable {
- /**
- * Returns the name of the property.
- *
- * @return
- */
- public String getName();
-
- /**
- * Returns the type of the property.
- *
- * @return Class<?>
- */
- public Class<?> getPropertyType();
-
- /**
- * Creates a new {@link Property} instance for this property for a bean.
- *
- * @param bean
- * @return
- */
- public Property<?> createProperty(BT bean);
-}
diff --git a/src/com/vaadin/data/util/converter/Converter.java b/src/com/vaadin/data/util/converter/Converter.java
deleted file mode 100644
index b8c15e8cdc..0000000000
--- a/src/com/vaadin/data/util/converter/Converter.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-/**
- * Interface that implements conversion between a model and a presentation type.
- * <p>
- * Typically {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should be symmetric so that chaining
- * these together returns the original result for all input but this is not a
- * requirement.
- * </p>
- * <p>
- * Converters must not have any side effects (never update UI from inside a
- * converter).
- * </p>
- * <p>
- * All Converters must be stateless and thread safe.
- * </p>
- * <p>
- * If conversion of a value fails, a {@link ConversionException} is thrown.
- * </p>
- *
- * @param <MODEL>
- * The model type. Must be compatible with what
- * {@link #getModelType()} returns.
- * @param <PRESENTATION>
- * The presentation type. Must be compatible with what
- * {@link #getPresentationType()} returns.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public interface Converter<PRESENTATION, MODEL> extends Serializable {
-
- /**
- * Converts the given value from target type to source type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws ConversionException;
-
- /**
- * Converts the given value from source type to target type.
- * <p>
- * A converter can optionally use locale to do the conversion.
- * </p>
- * A converter should in most cases be symmetric so chaining
- * {@link #convertToPresentation(Object, Locale)} and
- * {@link #convertToModel(Object, Locale)} should return the original value.
- *
- * @param value
- * The value to convert, compatible with the target type. Can be
- * null
- * @param locale
- * The locale to use for conversion. Can be null.
- * @return The converted value compatible with the source type
- * @throws ConversionException
- * If the value could not be converted
- */
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws ConversionException;
-
- /**
- * The source type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToPresentation(Object, Locale)}.
- *
- * @return The source type
- */
- public Class<MODEL> getModelType();
-
- /**
- * The target type of the converter.
- *
- * Values of this type can be passed to
- * {@link #convertToModel(Object, Locale)}.
- *
- * @return The target type
- */
- public Class<PRESENTATION> getPresentationType();
-
- /**
- * An exception that signals that the value passed to
- * {@link Converter#convertToPresentation(Object, Locale)} or
- * {@link Converter#convertToModel(Object, Locale)} could not be converted.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
- public static class ConversionException extends RuntimeException {
-
- /**
- * Constructs a new <code>ConversionException</code> without a detail
- * message.
- */
- public ConversionException() {
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public ConversionException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new {@code ConversionException} with the specified
- * cause.
- *
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructs a new <code>ConversionException</code> with the specified
- * detail message and cause.
- *
- * @param message
- * the detail message
- * @param cause
- * The cause of the the exception
- */
- public ConversionException(String message, Throwable cause) {
- super(message, cause);
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/ConverterFactory.java b/src/com/vaadin/data/util/converter/ConverterFactory.java
deleted file mode 100644
index ed4ab41ac0..0000000000
--- a/src/com/vaadin/data/util/converter/ConverterFactory.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-
-/**
- * Factory interface for providing Converters based on a presentation type and a
- * model type.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- *
- */
-public interface ConverterFactory extends Serializable {
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType);
-
-}
diff --git a/src/com/vaadin/data/util/converter/ConverterUtil.java b/src/com/vaadin/data/util/converter/ConverterUtil.java
deleted file mode 100644
index 7011496ed7..0000000000
--- a/src/com/vaadin/data/util/converter/ConverterUtil.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.converter;
-
-import java.io.Serializable;
-import java.util.Locale;
-
-import com.vaadin.Application;
-
-public class ConverterUtil implements Serializable {
-
- /**
- * Finds a converter that can convert from the given presentation type to
- * the given model type and back. Uses the given application to find a
- * {@link ConverterFactory} or, if application is null, uses the
- * {@link Application#getCurrent()}.
- *
- * @param <PRESENTATIONTYPE>
- * The presentation type
- * @param <MODELTYPE>
- * The model type
- * @param presentationType
- * The presentation type
- * @param modelType
- * The model type
- * @param application
- * The application to use to find a ConverterFactory or null to
- * use the current application
- * @return A Converter capable of converting between the given types or null
- * if no converter was found
- */
- public static <PRESENTATIONTYPE, MODELTYPE> Converter<PRESENTATIONTYPE, MODELTYPE> getConverter(
- Class<PRESENTATIONTYPE> presentationType,
- Class<MODELTYPE> modelType, Application application) {
- Converter<PRESENTATIONTYPE, MODELTYPE> converter = null;
- if (application == null) {
- application = Application.getCurrent();
- }
-
- if (application != null) {
- ConverterFactory factory = application.getConverterFactory();
- converter = factory.createConverter(presentationType, modelType);
- }
- return converter;
-
- }
-
- /**
- * Convert the given value from the data source type to the UI type.
- *
- * @param modelValue
- * The model value to convert
- * @param presentationType
- * The type of the presentation value
- * @param converter
- * The converter to (try to) use
- * @param locale
- * The locale to use for conversion
- * @param <PRESENTATIONTYPE>
- * Presentation type
- *
- * @return The converted value, compatible with the presentation type, or
- * the original value if its type is compatible and no converter is
- * set.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the model type.
- */
- @SuppressWarnings("unchecked")
- public static <PRESENTATIONTYPE, MODELTYPE> PRESENTATIONTYPE convertFromModel(
- MODELTYPE modelValue,
- Class<? extends PRESENTATIONTYPE> presentationType,
- Converter<PRESENTATIONTYPE, MODELTYPE> converter, Locale locale)
- throws Converter.ConversionException {
- if (converter != null) {
- return converter.convertToPresentation(modelValue, locale);
- }
- if (modelValue == null) {
- return null;
- }
-
- if (presentationType.isAssignableFrom(modelValue.getClass())) {
- return (PRESENTATIONTYPE) modelValue;
- } else {
- throw new Converter.ConversionException(
- "Unable to convert value of type "
- + modelValue.getClass().getName()
- + " to presentation type "
- + presentationType
- + ". No converter is set and the types are not compatible.");
- }
- }
-
- /**
- * @param <MODELTYPE>
- * @param <PRESENTATIONTYPE>
- * @param presentationValue
- * @param modelType
- * @param converter
- * @param locale
- * @return
- * @throws Converter.ConversionException
- */
- public static <MODELTYPE, PRESENTATIONTYPE> MODELTYPE convertToModel(
- PRESENTATIONTYPE presentationValue, Class<MODELTYPE> modelType,
- Converter<PRESENTATIONTYPE, MODELTYPE> converter, Locale locale)
- throws Converter.ConversionException {
- if (converter != null) {
- /*
- * If there is a converter, always use it. It must convert or throw
- * an exception.
- */
- return converter.convertToModel(presentationValue, locale);
- }
-
- if (presentationValue == null) {
- // Null should always be passed through the converter but if there
- // is no converter we can safely return null
- return null;
- }
-
- if (modelType == null) {
- // No model type, return original value
- return (MODELTYPE) presentationValue;
- } else if (modelType.isAssignableFrom(presentationValue.getClass())) {
- // presentation type directly compatible with model type
- return modelType.cast(presentationValue);
- } else {
- throw new Converter.ConversionException(
- "Unable to convert value of type "
- + presentationValue.getClass().getName()
- + " to model type "
- + modelType
- + ". No converter is set and the types are not compatible.");
- }
-
- }
-
- /**
- * Checks if the given converter can handle conversion between the given
- * presentation and model type
- *
- * @param converter
- * The converter to check
- * @param presentationType
- * The presentation type
- * @param modelType
- * The model type
- * @return true if the converter supports conversion between the given
- * presentation and model type, false otherwise
- */
- public static boolean canConverterHandle(Converter<?, ?> converter,
- Class<?> presentationType, Class<?> modelType) {
- if (converter == null) {
- return false;
- }
-
- if (!modelType.isAssignableFrom(converter.getModelType())) {
- return false;
- }
- if (!presentationType.isAssignableFrom(converter.getPresentationType())) {
- return false;
- }
-
- return true;
- }
-}
diff --git a/src/com/vaadin/data/util/converter/DateToLongConverter.java b/src/com/vaadin/data/util/converter/DateToLongConverter.java
deleted file mode 100644
index aeba38aa1f..0000000000
--- a/src/com/vaadin/data/util/converter/DateToLongConverter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Long} to {@link Date} and back.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateToLongConverter implements Converter<Date, Long> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- @Override
- public Long convertToModel(Date value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return value.getTime();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public Date convertToPresentation(Long value, Locale locale) {
- if (value == null) {
- return null;
- }
-
- return new Date(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- @Override
- public Class<Long> getModelType() {
- return Long.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<Date> getPresentationType() {
- return Date.class;
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
deleted file mode 100644
index afb95d81ed..0000000000
--- a/src/com/vaadin/data/util/converter/DefaultConverterFactory.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Date;
-import java.util.logging.Logger;
-
-import com.vaadin.Application;
-
-/**
- * Default implementation of {@link ConverterFactory}. Provides converters for
- * standard types like {@link String}, {@link Double} and {@link Date}. </p>
- * <p>
- * Custom converters can be provided by extending this class and using
- * {@link Application#setConverterFactory(ConverterFactory)}.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DefaultConverterFactory implements ConverterFactory {
-
- private final static Logger log = Logger
- .getLogger(DefaultConverterFactory.class.getName());
-
- @Override
- public <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> createConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- Converter<PRESENTATION, MODEL> converter = findConverter(
- presentationType, modelType);
- if (converter != null) {
- log.finest(getClass().getName() + " created a "
- + converter.getClass());
- return converter;
- }
-
- // Try to find a reverse converter
- Converter<MODEL, PRESENTATION> reverseConverter = findConverter(
- modelType, presentationType);
- if (reverseConverter != null) {
- log.finest(getClass().getName() + " created a reverse "
- + reverseConverter.getClass());
- return new ReverseConverter<PRESENTATION, MODEL>(reverseConverter);
- }
-
- log.finest(getClass().getName() + " could not find a converter for "
- + presentationType.getName() + " to " + modelType.getName()
- + " conversion");
- return null;
-
- }
-
- protected <PRESENTATION, MODEL> Converter<PRESENTATION, MODEL> findConverter(
- Class<PRESENTATION> presentationType, Class<MODEL> modelType) {
- if (presentationType == String.class) {
- // TextField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createStringConverter(modelType);
- if (converter != null) {
- return converter;
- }
- } else if (presentationType == Date.class) {
- // DateField converters and more
- Converter<PRESENTATION, MODEL> converter = (Converter<PRESENTATION, MODEL>) createDateConverter(modelType);
- if (converter != null) {
- return converter;
- }
- }
-
- return null;
-
- }
-
- protected Converter<Date, ?> createDateConverter(Class<?> sourceType) {
- if (Long.class.isAssignableFrom(sourceType)) {
- return new DateToLongConverter();
- } else {
- return null;
- }
- }
-
- protected Converter<String, ?> createStringConverter(Class<?> sourceType) {
- if (Double.class.isAssignableFrom(sourceType)) {
- return new StringToDoubleConverter();
- } else if (Integer.class.isAssignableFrom(sourceType)) {
- return new StringToIntegerConverter();
- } else if (Boolean.class.isAssignableFrom(sourceType)) {
- return new StringToBooleanConverter();
- } else if (Number.class.isAssignableFrom(sourceType)) {
- return new StringToNumberConverter();
- } else if (Date.class.isAssignableFrom(sourceType)) {
- return new StringToDateConverter();
- } else {
- return null;
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/ReverseConverter.java b/src/com/vaadin/data/util/converter/ReverseConverter.java
deleted file mode 100644
index fa1bb5daf1..0000000000
--- a/src/com/vaadin/data/util/converter/ReverseConverter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that wraps another {@link Converter} and reverses source and
- * target types.
- *
- * @param <MODEL>
- * The source type
- * @param <PRESENTATION>
- * The target type
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class ReverseConverter<PRESENTATION, MODEL> implements
- Converter<PRESENTATION, MODEL> {
-
- private Converter<MODEL, PRESENTATION> realConverter;
-
- /**
- * Creates a converter from source to target based on a converter that
- * converts from target to source.
- *
- * @param converter
- * The converter to use in a reverse fashion
- */
- public ReverseConverter(Converter<MODEL, PRESENTATION> converter) {
- this.realConverter = converter;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#convertToModel(java
- * .lang.Object, java.util.Locale)
- */
- @Override
- public MODEL convertToModel(PRESENTATION value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToPresentation(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public PRESENTATION convertToPresentation(MODEL value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- return realConverter.convertToModel(value, locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getSourceType()
- */
- @Override
- public Class<MODEL> getModelType() {
- return realConverter.getPresentationType();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getTargetType()
- */
- @Override
- public Class<PRESENTATION> getPresentationType() {
- return realConverter.getModelType();
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java b/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
deleted file mode 100644
index 999f575dc4..0000000000
--- a/src/com/vaadin/data/util/converter/StringToBooleanConverter.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Boolean} and back.
- * The String representation is given by Boolean.toString().
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToBooleanConverter implements Converter<String, Boolean> {
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- @Override
- public Boolean convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- if (getTrueString().equals(value)) {
- return true;
- } else if (getFalseString().equals(value)) {
- return false;
- } else {
- throw new ConversionException("Cannot convert " + value + " to "
- + getModelType().getName());
- }
- }
-
- /**
- * Gets the string representation for true. Default is "true".
- *
- * @return the string representation for true
- */
- protected String getTrueString() {
- return Boolean.TRUE.toString();
- }
-
- /**
- * Gets the string representation for false. Default is "false".
- *
- * @return the string representation for false
- */
- protected String getFalseString() {
- return Boolean.FALSE.toString();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Boolean value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
- if (value) {
- return getTrueString();
- } else {
- return getFalseString();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- @Override
- public Class<Boolean> getModelType() {
- return Boolean.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/StringToDateConverter.java b/src/com/vaadin/data/util/converter/StringToDateConverter.java
deleted file mode 100644
index 487b02b2aa..0000000000
--- a/src/com/vaadin/data/util/converter/StringToDateConverter.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.DateFormat;
-import java.text.ParsePosition;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Date} to {@link String} and back. Uses
- * the given locale and {@link DateFormat} for formatting and parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDateConverter implements Converter<String, Date> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Date, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A DateFormat instance
- */
- protected DateFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- DateFormat f = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
- DateFormat.MEDIUM, locale);
- f.setLenient(false);
- return f;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- @Override
- public Date convertToModel(String value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Date parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Date value, Locale locale)
- throws com.vaadin.data.util.converter.Converter.ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- @Override
- public Class<Date> getModelType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java b/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
deleted file mode 100644
index 251f91855b..0000000000
--- a/src/com/vaadin/data/util/converter/StringToDoubleConverter.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Double} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Leading and trailing white spaces are ignored when converting from a String.
- * </p>
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToDoubleConverter implements Converter<String, Double> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Double, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- @Override
- public Double convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
- return parsedValue.doubleValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Double value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- @Override
- public Class<Double> getModelType() {
- return Double.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-}
diff --git a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java b/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
deleted file mode 100644
index 950f01c6ab..0000000000
--- a/src/com/vaadin/data/util/converter/StringToIntegerConverter.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link String} to {@link Integer} and back.
- * Uses the given locale and a {@link NumberFormat} instance for formatting and
- * parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToIntegerConverter implements Converter<String, Integer> {
-
- /**
- * Returns the format used by
- * {@link #convertToPresentation(Integer, Locale)} and
- * {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
- return NumberFormat.getIntegerInstance(locale);
- }
-
- @Override
- public Integer convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue.intValue();
- }
-
- @Override
- public String convertToPresentation(Integer value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- @Override
- public Class<Integer> getModelType() {
- return Integer.class;
- }
-
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
diff --git a/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/src/com/vaadin/data/util/converter/StringToNumberConverter.java
deleted file mode 100644
index 42699a326a..0000000000
--- a/src/com/vaadin/data/util/converter/StringToNumberConverter.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.util.converter;
-
-import java.text.NumberFormat;
-import java.text.ParsePosition;
-import java.util.Locale;
-
-/**
- * A converter that converts from {@link Number} to {@link String} and back.
- * Uses the given locale and {@link NumberFormat} for formatting and parsing.
- * <p>
- * Override and overwrite {@link #getFormat(Locale)} to use a different format.
- * </p>
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class StringToNumberConverter implements Converter<String, Number> {
-
- /**
- * Returns the format used by {@link #convertToPresentation(Number, Locale)}
- * and {@link #convertToModel(String, Locale)}.
- *
- * @param locale
- * The locale to use
- * @return A NumberFormat instance
- */
- protected NumberFormat getFormat(Locale locale) {
- if (locale == null) {
- locale = Locale.getDefault();
- }
-
- return NumberFormat.getNumberInstance(locale);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object,
- * java.util.Locale)
- */
- @Override
- public Number convertToModel(String value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- // Remove leading and trailing white space
- value = value.trim();
-
- // Parse and detect errors. If the full string was not used, it is
- // an error.
- ParsePosition parsePosition = new ParsePosition(0);
- Number parsedValue = getFormat(locale).parse(value, parsePosition);
- if (parsePosition.getIndex() != value.length()) {
- throw new ConversionException("Could not convert '" + value
- + "' to " + getModelType().getName());
- }
-
- if (parsedValue == null) {
- // Convert "" to null
- return null;
- }
- return parsedValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.converter.Converter#convertToPresentation(java.lang
- * .Object, java.util.Locale)
- */
- @Override
- public String convertToPresentation(Number value, Locale locale)
- throws ConversionException {
- if (value == null) {
- return null;
- }
-
- return getFormat(locale).format(value);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getModelType()
- */
- @Override
- public Class<Number> getModelType() {
- return Number.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.converter.Converter#getPresentationType()
- */
- @Override
- public Class<String> getPresentationType() {
- return String.class;
- }
-
-}
diff --git a/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java b/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java
deleted file mode 100644
index 482b10120c..0000000000
--- a/src/com/vaadin/data/util/filter/AbstractJunctionFilter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
-import com.vaadin.data.Container.Filter;
-
-/**
- * Abstract base class for filters that are composed of multiple sub-filters.
- *
- * The method {@link #appliesToProperty(Object)} is provided to help
- * implementing {@link Filter} for in-memory filters.
- *
- * @since 6.6
- */
-public abstract class AbstractJunctionFilter implements Filter {
-
- protected final Collection<Filter> filters;
-
- public AbstractJunctionFilter(Filter... filters) {
- this.filters = Collections.unmodifiableCollection(Arrays
- .asList(filters));
- }
-
- /**
- * Returns an unmodifiable collection of the sub-filters of this composite
- * filter.
- *
- * @return
- */
- public Collection<Filter> getFilters() {
- return filters;
- }
-
- /**
- * Returns true if a change in the named property may affect the filtering
- * result. If some of the sub-filters are not in-memory filters, true is
- * returned.
- *
- * By default, all sub-filters are iterated to check if any of them applies.
- * If there are no sub-filters, false is returned - override in subclasses
- * to change this behavior.
- */
- @Override
- public boolean appliesToProperty(Object propertyId) {
- for (Filter filter : getFilters()) {
- if (filter.appliesToProperty(propertyId)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !getClass().equals(obj.getClass())) {
- return false;
- }
- AbstractJunctionFilter other = (AbstractJunctionFilter) obj;
- // contents comparison with equals()
- return Arrays.equals(filters.toArray(), other.filters.toArray());
- }
-
- @Override
- public int hashCode() {
- int hash = getFilters().size();
- for (Filter filter : filters) {
- hash = (hash << 1) ^ filter.hashCode();
- }
- return hash;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/filter/And.java b/src/com/vaadin/data/util/filter/And.java
deleted file mode 100644
index ca6c35aba7..0000000000
--- a/src/com/vaadin/data/util/filter/And.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-
-/**
- * A compound {@link Filter} that accepts an item if all of its filters accept
- * the item.
- *
- * If no filters are given, the filter should accept all items.
- *
- * This filter also directly supports in-memory filtering when all sub-filters
- * do so.
- *
- * @see Or
- *
- * @since 6.6
- */
-public final class And extends AbstractJunctionFilter {
-
- /**
- *
- * @param filters
- * filters of which the And filter will be composed
- */
- public And(Filter... filters) {
- super(filters);
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedFilterException {
- for (Filter filter : getFilters()) {
- if (!filter.passesFilter(itemId, item)) {
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/src/com/vaadin/data/util/filter/Between.java b/src/com/vaadin/data/util/filter/Between.java
deleted file mode 100644
index b00a74d13d..0000000000
--- a/src/com/vaadin/data/util/filter/Between.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-
-public class Between implements Filter {
-
- private final Object propertyId;
- private final Comparable startValue;
- private final Comparable endValue;
-
- public Between(Object propertyId, Comparable startValue, Comparable endValue) {
- this.propertyId = propertyId;
- this.startValue = startValue;
- this.endValue = endValue;
- }
-
- public Object getPropertyId() {
- return propertyId;
- }
-
- public Comparable<?> getStartValue() {
- return startValue;
- }
-
- public Comparable<?> getEndValue() {
- return endValue;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException {
- Object value = item.getItemProperty(getPropertyId()).getValue();
- if (value instanceof Comparable) {
- Comparable cval = (Comparable) value;
- return cval.compareTo(getStartValue()) >= 0
- && cval.compareTo(getEndValue()) <= 0;
- }
- return false;
- }
-
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return getPropertyId() != null && getPropertyId().equals(propertyId);
- }
-
- @Override
- public int hashCode() {
- return getPropertyId().hashCode() + getStartValue().hashCode()
- + getEndValue().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- // Only objects of the same class can be equal
- if (!getClass().equals(obj.getClass())) {
- return false;
- }
- final Between o = (Between) obj;
-
- // Checks the properties one by one
- boolean propertyIdEqual = (null != getPropertyId()) ? getPropertyId()
- .equals(o.getPropertyId()) : null == o.getPropertyId();
- boolean startValueEqual = (null != getStartValue()) ? getStartValue()
- .equals(o.getStartValue()) : null == o.getStartValue();
- boolean endValueEqual = (null != getEndValue()) ? getEndValue().equals(
- o.getEndValue()) : null == o.getEndValue();
- return propertyIdEqual && startValueEqual && endValueEqual;
-
- }
-}
diff --git a/src/com/vaadin/data/util/filter/Compare.java b/src/com/vaadin/data/util/filter/Compare.java
deleted file mode 100644
index 4091f5b922..0000000000
--- a/src/com/vaadin/data/util/filter/Compare.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * Simple container filter comparing an item property value against a given
- * constant value. Use the nested classes {@link Equal}, {@link Greater},
- * {@link Less}, {@link GreaterOrEqual} and {@link LessOrEqual} instead of this
- * class directly.
- *
- * This filter also directly supports in-memory filtering.
- *
- * The reference and actual values must implement {@link Comparable} and the
- * class of the actual property value must be assignable from the class of the
- * reference value.
- *
- * @since 6.6
- */
-public abstract class Compare implements Filter {
-
- public enum Operation {
- EQUAL, GREATER, LESS, GREATER_OR_EQUAL, LESS_OR_EQUAL
- };
-
- private final Object propertyId;
- private final Operation operation;
- private final Object value;
-
- /**
- * A {@link Compare} filter that accepts items for which the identified
- * property value is equal to <code>value</code>.
- *
- * For in-memory filters, equals() is used for the comparison. For other
- * containers, the comparison implementation is container dependent and may
- * use e.g. database comparison operations.
- *
- * @since 6.6
- */
- public static final class Equal extends Compare {
- /**
- * Construct a filter that accepts items for which the identified
- * property value is equal to <code>value</code>.
- *
- * For in-memory filters, equals() is used for the comparison. For other
- * containers, the comparison implementation is container dependent and
- * may use e.g. database comparison operations.
- *
- * @param propertyId
- * the identifier of the property whose value to compare
- * against value, not null
- * @param value
- * the value to compare against - null values may or may not
- * be supported depending on the container
- */
- public Equal(Object propertyId, Object value) {
- super(propertyId, value, Operation.EQUAL);
- }
- }
-
- /**
- * A {@link Compare} filter that accepts items for which the identified
- * property value is greater than <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable} and
- * {@link Comparable#compareTo(Object)} is used for the comparison. For
- * other containers, the comparison implementation is container dependent
- * and may use e.g. database comparison operations.
- *
- * @since 6.6
- */
- public static final class Greater extends Compare {
- /**
- * Construct a filter that accepts items for which the identified
- * property value is greater than <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable}
- * and {@link Comparable#compareTo(Object)} is used for the comparison.
- * For other containers, the comparison implementation is container
- * dependent and may use e.g. database comparison operations.
- *
- * @param propertyId
- * the identifier of the property whose value to compare
- * against value, not null
- * @param value
- * the value to compare against - null values may or may not
- * be supported depending on the container
- */
- public Greater(Object propertyId, Object value) {
- super(propertyId, value, Operation.GREATER);
- }
- }
-
- /**
- * A {@link Compare} filter that accepts items for which the identified
- * property value is less than <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable} and
- * {@link Comparable#compareTo(Object)} is used for the comparison. For
- * other containers, the comparison implementation is container dependent
- * and may use e.g. database comparison operations.
- *
- * @since 6.6
- */
- public static final class Less extends Compare {
- /**
- * Construct a filter that accepts items for which the identified
- * property value is less than <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable}
- * and {@link Comparable#compareTo(Object)} is used for the comparison.
- * For other containers, the comparison implementation is container
- * dependent and may use e.g. database comparison operations.
- *
- * @param propertyId
- * the identifier of the property whose value to compare
- * against value, not null
- * @param value
- * the value to compare against - null values may or may not
- * be supported depending on the container
- */
- public Less(Object propertyId, Object value) {
- super(propertyId, value, Operation.LESS);
- }
- }
-
- /**
- * A {@link Compare} filter that accepts items for which the identified
- * property value is greater than or equal to <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable} and
- * {@link Comparable#compareTo(Object)} is used for the comparison. For
- * other containers, the comparison implementation is container dependent
- * and may use e.g. database comparison operations.
- *
- * @since 6.6
- */
- public static final class GreaterOrEqual extends Compare {
- /**
- * Construct a filter that accepts items for which the identified
- * property value is greater than or equal to <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable}
- * and {@link Comparable#compareTo(Object)} is used for the comparison.
- * For other containers, the comparison implementation is container
- * dependent and may use e.g. database comparison operations.
- *
- * @param propertyId
- * the identifier of the property whose value to compare
- * against value, not null
- * @param value
- * the value to compare against - null values may or may not
- * be supported depending on the container
- */
- public GreaterOrEqual(Object propertyId, Object value) {
- super(propertyId, value, Operation.GREATER_OR_EQUAL);
- }
- }
-
- /**
- * A {@link Compare} filter that accepts items for which the identified
- * property value is less than or equal to <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable} and
- * {@link Comparable#compareTo(Object)} is used for the comparison. For
- * other containers, the comparison implementation is container dependent
- * and may use e.g. database comparison operations.
- *
- * @since 6.6
- */
- public static final class LessOrEqual extends Compare {
- /**
- * Construct a filter that accepts items for which the identified
- * property value is less than or equal to <code>value</code>.
- *
- * For in-memory filters, the values must implement {@link Comparable}
- * and {@link Comparable#compareTo(Object)} is used for the comparison.
- * For other containers, the comparison implementation is container
- * dependent and may use e.g. database comparison operations.
- *
- * @param propertyId
- * the identifier of the property whose value to compare
- * against value, not null
- * @param value
- * the value to compare against - null values may or may not
- * be supported depending on the container
- */
- public LessOrEqual(Object propertyId, Object value) {
- super(propertyId, value, Operation.LESS_OR_EQUAL);
- }
- }
-
- /**
- * Constructor for a {@link Compare} filter that compares the value of an
- * item property with the given constant <code>value</code>.
- *
- * This constructor is intended to be used by the nested static classes only
- * ({@link Equal}, {@link Greater}, {@link Less}, {@link GreaterOrEqual},
- * {@link LessOrEqual}).
- *
- * For in-memory filtering, comparisons except EQUAL require that the values
- * implement {@link Comparable} and {@link Comparable#compareTo(Object)} is
- * used for the comparison. The equality comparison is performed using
- * {@link Object#equals(Object)}.
- *
- * For other containers, the comparison implementation is container
- * dependent and may use e.g. database comparison operations. Therefore, the
- * behavior of comparisons might differ in some cases between in-memory and
- * other containers.
- *
- * @param propertyId
- * the identifier of the property whose value to compare against
- * value, not null
- * @param value
- * the value to compare against - null values may or may not be
- * supported depending on the container
- * @param operation
- * the comparison {@link Operation} to use
- */
- Compare(Object propertyId, Object value, Operation operation) {
- this.propertyId = propertyId;
- this.value = value;
- this.operation = operation;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item) {
- final Property<?> p = item.getItemProperty(getPropertyId());
- if (null == p) {
- return false;
- }
- Object value = p.getValue();
- switch (getOperation()) {
- case EQUAL:
- return (null == this.value) ? (null == value) : this.value
- .equals(value);
- case GREATER:
- return compareValue(value) > 0;
- case LESS:
- return compareValue(value) < 0;
- case GREATER_OR_EQUAL:
- return compareValue(value) >= 0;
- case LESS_OR_EQUAL:
- return compareValue(value) <= 0;
- }
- // all cases should have been processed above
- return false;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected int compareValue(Object value1) {
- if (null == value) {
- return null == value1 ? 0 : -1;
- } else if (null == value1) {
- return 1;
- } else if (getValue() instanceof Comparable
- && value1.getClass().isAssignableFrom(getValue().getClass())) {
- return -((Comparable) getValue()).compareTo(value1);
- }
- throw new IllegalArgumentException("Could not compare the arguments: "
- + value1 + ", " + getValue());
- }
-
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return getPropertyId().equals(propertyId);
- }
-
- @Override
- public boolean equals(Object obj) {
-
- // Only objects of the same class can be equal
- if (!getClass().equals(obj.getClass())) {
- return false;
- }
- final Compare o = (Compare) obj;
-
- // Checks the properties one by one
- if (getPropertyId() != o.getPropertyId() && null != o.getPropertyId()
- && !o.getPropertyId().equals(getPropertyId())) {
- return false;
- }
- if (getOperation() != o.getOperation()) {
- return false;
- }
- return (null == getValue()) ? null == o.getValue() : getValue().equals(
- o.getValue());
- }
-
- @Override
- public int hashCode() {
- return (null != getPropertyId() ? getPropertyId().hashCode() : 0)
- ^ (null != getValue() ? getValue().hashCode() : 0);
- }
-
- /**
- * Returns the property id of the property to compare against the fixed
- * value.
- *
- * @return property id (not null)
- */
- public Object getPropertyId() {
- return propertyId;
- }
-
- /**
- * Returns the comparison operation.
- *
- * @return {@link Operation}
- */
- public Operation getOperation() {
- return operation;
- }
-
- /**
- * Returns the value to compare the property against.
- *
- * @return comparison reference value
- */
- public Object getValue() {
- return value;
- }
-}
diff --git a/src/com/vaadin/data/util/filter/IsNull.java b/src/com/vaadin/data/util/filter/IsNull.java
deleted file mode 100644
index 3faf4153ee..0000000000
--- a/src/com/vaadin/data/util/filter/IsNull.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * Simple container filter checking whether an item property value is null.
- *
- * This filter also directly supports in-memory filtering.
- *
- * @since 6.6
- */
-public final class IsNull implements Filter {
-
- private final Object propertyId;
-
- /**
- * Constructor for a filter that compares the value of an item property with
- * null.
- *
- * For in-memory filtering, a simple == check is performed. For other
- * containers, the comparison implementation is container dependent but
- * should correspond to the in-memory null check.
- *
- * @param propertyId
- * the identifier (not null) of the property whose value to check
- */
- public IsNull(Object propertyId) {
- this.propertyId = propertyId;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException {
- final Property<?> p = item.getItemProperty(getPropertyId());
- if (null == p) {
- return false;
- }
- return null == p.getValue();
- }
-
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return getPropertyId().equals(propertyId);
- }
-
- @Override
- public boolean equals(Object obj) {
- // Only objects of the same class can be equal
- if (!getClass().equals(obj.getClass())) {
- return false;
- }
- final IsNull o = (IsNull) obj;
-
- // Checks the properties one by one
- return (null != getPropertyId()) ? getPropertyId().equals(
- o.getPropertyId()) : null == o.getPropertyId();
- }
-
- @Override
- public int hashCode() {
- return (null != getPropertyId() ? getPropertyId().hashCode() : 0);
- }
-
- /**
- * Returns the property id of the property tested by the filter, not null
- * for valid filters.
- *
- * @return property id (not null)
- */
- public Object getPropertyId() {
- return propertyId;
- }
-
-}
diff --git a/src/com/vaadin/data/util/filter/Like.java b/src/com/vaadin/data/util/filter/Like.java
deleted file mode 100644
index 3dcc48e809..0000000000
--- a/src/com/vaadin/data/util/filter/Like.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-
-public class Like implements Filter {
- private final Object propertyId;
- private final String value;
- private boolean caseSensitive;
-
- public Like(String propertyId, String value) {
- this(propertyId, value, true);
- }
-
- public Like(String propertyId, String value, boolean caseSensitive) {
- this.propertyId = propertyId;
- this.value = value;
- setCaseSensitive(caseSensitive);
- }
-
- public Object getPropertyId() {
- return propertyId;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setCaseSensitive(boolean caseSensitive) {
- this.caseSensitive = caseSensitive;
- }
-
- public boolean isCaseSensitive() {
- return caseSensitive;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException {
- if (!item.getItemProperty(getPropertyId()).getType()
- .isAssignableFrom(String.class)) {
- // We can only handle strings
- return false;
- }
- String colValue = (String) item.getItemProperty(getPropertyId())
- .getValue();
-
- String pattern = getValue().replace("%", ".*");
- if (isCaseSensitive()) {
- return colValue.matches(pattern);
- }
- return colValue.toUpperCase().matches(pattern.toUpperCase());
- }
-
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return getPropertyId() != null && getPropertyId().equals(propertyId);
- }
-
- @Override
- public int hashCode() {
- return getPropertyId().hashCode() + getValue().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- // Only objects of the same class can be equal
- if (!getClass().equals(obj.getClass())) {
- return false;
- }
- final Like o = (Like) obj;
-
- // Checks the properties one by one
- boolean propertyIdEqual = (null != getPropertyId()) ? getPropertyId()
- .equals(o.getPropertyId()) : null == o.getPropertyId();
- boolean valueEqual = (null != getValue()) ? getValue().equals(
- o.getValue()) : null == o.getValue();
- return propertyIdEqual && valueEqual;
- }
-}
diff --git a/src/com/vaadin/data/util/filter/Not.java b/src/com/vaadin/data/util/filter/Not.java
deleted file mode 100644
index bbfc9ca86a..0000000000
--- a/src/com/vaadin/data/util/filter/Not.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-
-/**
- * Negating filter that accepts the items rejected by another filter.
- *
- * This filter directly supports in-memory filtering when the negated filter
- * does so.
- *
- * @since 6.6
- */
-public final class Not implements Filter {
- private final Filter filter;
-
- /**
- * Constructs a filter that negates a filter.
- *
- * @param filter
- * {@link Filter} to negate, not-null
- */
- public Not(Filter filter) {
- this.filter = filter;
- }
-
- /**
- * Returns the negated filter.
- *
- * @return Filter
- */
- public Filter getFilter() {
- return filter;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedOperationException {
- return !filter.passesFilter(itemId, item);
- }
-
- /**
- * Returns true if a change in the named property may affect the filtering
- * result. Return value is the same as {@link #appliesToProperty(Object)}
- * for the negated filter.
- *
- * @return boolean
- */
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return filter.appliesToProperty(propertyId);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !getClass().equals(obj.getClass())) {
- return false;
- }
- return filter.equals(((Not) obj).getFilter());
- }
-
- @Override
- public int hashCode() {
- return filter.hashCode();
- }
-
-}
diff --git a/src/com/vaadin/data/util/filter/Or.java b/src/com/vaadin/data/util/filter/Or.java
deleted file mode 100644
index b60074f7e3..0000000000
--- a/src/com/vaadin/data/util/filter/Or.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-
-/**
- * A compound {@link Filter} that accepts an item if any of its filters accept
- * the item.
- *
- * If no filters are given, the filter should reject all items.
- *
- * This filter also directly supports in-memory filtering when all sub-filters
- * do so.
- *
- * @see And
- *
- * @since 6.6
- */
-public final class Or extends AbstractJunctionFilter {
-
- /**
- *
- * @param filters
- * filters of which the Or filter will be composed
- */
- public Or(Filter... filters) {
- super(filters);
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item)
- throws UnsupportedFilterException {
- for (Filter filter : getFilters()) {
- if (filter.passesFilter(itemId, item)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if a change in the named property may affect the filtering
- * result. If some of the sub-filters are not in-memory filters, true is
- * returned.
- *
- * By default, all sub-filters are iterated to check if any of them applies.
- * If there are no sub-filters, true is returned as an empty Or rejects all
- * items.
- */
- @Override
- public boolean appliesToProperty(Object propertyId) {
- if (getFilters().isEmpty()) {
- // empty Or filters out everything
- return true;
- } else {
- return super.appliesToProperty(propertyId);
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/filter/SimpleStringFilter.java b/src/com/vaadin/data/util/filter/SimpleStringFilter.java
deleted file mode 100644
index f98b2c02b4..0000000000
--- a/src/com/vaadin/data/util/filter/SimpleStringFilter.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * Simple string filter for matching items that start with or contain a
- * specified string. The matching can be case-sensitive or case-insensitive.
- *
- * This filter also directly supports in-memory filtering. When performing
- * in-memory filtering, values of other types are converted using toString(),
- * but other (lazy container) implementations do not need to perform such
- * conversions and might not support values of different types.
- *
- * Note that this filter is modeled after the pre-6.6 filtering mechanisms, and
- * might not be very efficient e.g. for database filtering.
- *
- * TODO this might still change
- *
- * @since 6.6
- */
-public final class SimpleStringFilter implements Filter {
-
- final Object propertyId;
- final String filterString;
- final boolean ignoreCase;
- final boolean onlyMatchPrefix;
-
- public SimpleStringFilter(Object propertyId, String filterString,
- boolean ignoreCase, boolean onlyMatchPrefix) {
- this.propertyId = propertyId;
- this.filterString = ignoreCase ? filterString.toLowerCase()
- : filterString;
- this.ignoreCase = ignoreCase;
- this.onlyMatchPrefix = onlyMatchPrefix;
- }
-
- @Override
- public boolean passesFilter(Object itemId, Item item) {
- final Property<?> p = item.getItemProperty(propertyId);
- if (p == null) {
- return false;
- }
- Object propertyValue = p.getValue();
- if (propertyValue == null) {
- return false;
- }
- final String value = ignoreCase ? propertyValue.toString()
- .toLowerCase() : propertyValue.toString();
- if (onlyMatchPrefix) {
- if (!value.startsWith(filterString)) {
- return false;
- }
- } else {
- if (!value.contains(filterString)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public boolean appliesToProperty(Object propertyId) {
- return this.propertyId.equals(propertyId);
- }
-
- @Override
- public boolean equals(Object obj) {
-
- // Only ones of the objects of the same class can be equal
- if (!(obj instanceof SimpleStringFilter)) {
- return false;
- }
- final SimpleStringFilter o = (SimpleStringFilter) obj;
-
- // Checks the properties one by one
- if (propertyId != o.propertyId && o.propertyId != null
- && !o.propertyId.equals(propertyId)) {
- return false;
- }
- if (filterString != o.filterString && o.filterString != null
- && !o.filterString.equals(filterString)) {
- return false;
- }
- if (ignoreCase != o.ignoreCase) {
- return false;
- }
- if (onlyMatchPrefix != o.onlyMatchPrefix) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return (propertyId != null ? propertyId.hashCode() : 0)
- ^ (filterString != null ? filterString.hashCode() : 0);
- }
-
- /**
- * Returns the property identifier to which this filter applies.
- *
- * @return property id
- */
- public Object getPropertyId() {
- return propertyId;
- }
-
- /**
- * Returns the filter string.
- *
- * Note: this method is intended only for implementations of lazy string
- * filters and may change in the future.
- *
- * @return filter string given to the constructor
- */
- public String getFilterString() {
- return filterString;
- }
-
- /**
- * Returns whether the filter is case-insensitive or case-sensitive.
- *
- * Note: this method is intended only for implementations of lazy string
- * filters and may change in the future.
- *
- * @return true if performing case-insensitive filtering, false for
- * case-sensitive
- */
- public boolean isIgnoreCase() {
- return ignoreCase;
- }
-
- /**
- * Returns true if the filter only applies to the beginning of the value
- * string, false for any location in the value.
- *
- * Note: this method is intended only for implementations of lazy string
- * filters and may change in the future.
- *
- * @return true if checking for matches at the beginning of the value only,
- * false if matching any part of value
- */
- public boolean isOnlyMatchPrefix() {
- return onlyMatchPrefix;
- }
-}
diff --git a/src/com/vaadin/data/util/filter/UnsupportedFilterException.java b/src/com/vaadin/data/util/filter/UnsupportedFilterException.java
deleted file mode 100644
index c09cc474e9..0000000000
--- a/src/com/vaadin/data/util/filter/UnsupportedFilterException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.filter;
-
-import java.io.Serializable;
-
-/**
- * Exception for cases where a container does not support a specific type of
- * filters.
- *
- * If possible, this should be thrown already when adding a filter to a
- * container. If a problem is not detected at that point, an
- * {@link UnsupportedOperationException} can be throws when attempting to
- * perform filtering.
- *
- * @since 6.6
- */
-public class UnsupportedFilterException extends RuntimeException implements
- Serializable {
- public UnsupportedFilterException() {
- }
-
- public UnsupportedFilterException(String message) {
- super(message);
- }
-
- public UnsupportedFilterException(Exception cause) {
- super(cause);
- }
-
- public UnsupportedFilterException(String message, Exception cause) {
- super(message, cause);
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/package.html b/src/com/vaadin/data/util/package.html
deleted file mode 100644
index 07e3acde9e..0000000000
--- a/src/com/vaadin/data/util/package.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-
-</head>
-
-<body bgcolor="white">
-
-<p>Provides implementations of Property, Item and Container
-interfaces, and utilities for the data layer.</p>
-
-<p>Various Property, Item and Container implementations are provided
-in this package. Each implementation can have its own sets of
-constraints on the data it encapsulates and on how the implementation
-can be used. See the class javadocs for more information.</p>
-
-</body>
-</html>
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java b/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
deleted file mode 100644
index 788966048d..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.data.util.sqlcontainer.query.FreeformQuery;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-
-/**
- * CacheFlushNotifier is a simple static notification mechanism to inform other
- * SQLContainers that the contents of their caches may have become stale.
- */
-class CacheFlushNotifier implements Serializable {
- /*
- * SQLContainer instance reference list and dead reference queue. Used for
- * the cache flush notification feature.
- */
- private static List<WeakReference<SQLContainer>> allInstances = new ArrayList<WeakReference<SQLContainer>>();
- private static ReferenceQueue<SQLContainer> deadInstances = new ReferenceQueue<SQLContainer>();
-
- /**
- * Adds the given SQLContainer to the cache flush notification receiver list
- *
- * @param c
- * Container to add
- */
- public static void addInstance(SQLContainer c) {
- removeDeadReferences();
- if (c != null) {
- allInstances.add(new WeakReference<SQLContainer>(c, deadInstances));
- }
- }
-
- /**
- * Removes dead references from instance list
- */
- private static void removeDeadReferences() {
- java.lang.ref.Reference<? extends SQLContainer> dead = deadInstances
- .poll();
- while (dead != null) {
- allInstances.remove(dead);
- dead = deadInstances.poll();
- }
- }
-
- /**
- * Iterates through the instances and notifies containers which are
- * connected to the same table or are using the same query string.
- *
- * @param c
- * SQLContainer that issued the cache flush notification
- */
- public static void notifyOfCacheFlush(SQLContainer c) {
- removeDeadReferences();
- for (WeakReference<SQLContainer> wr : allInstances) {
- if (wr.get() != null) {
- SQLContainer wrc = wr.get();
- if (wrc == null) {
- continue;
- }
- /*
- * If the reference points to the container sending the
- * notification, do nothing.
- */
- if (wrc.equals(c)) {
- continue;
- }
- /* Compare QueryDelegate types and tableName/queryString */
- QueryDelegate wrQd = wrc.getQueryDelegate();
- QueryDelegate qd = c.getQueryDelegate();
- if (wrQd instanceof TableQuery
- && qd instanceof TableQuery
- && ((TableQuery) wrQd).getTableName().equals(
- ((TableQuery) qd).getTableName())) {
- wrc.refresh();
- } else if (wrQd instanceof FreeformQuery
- && qd instanceof FreeformQuery
- && ((FreeformQuery) wrQd).getQueryString().equals(
- ((FreeformQuery) qd).getQueryString())) {
- wrc.refresh();
- }
- }
- }
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java b/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
deleted file mode 100644
index 839fceb3c2..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/CacheMap.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * CacheMap extends LinkedHashMap, adding the possibility to adjust maximum
- * number of items. In SQLContainer this is used for RowItem -cache. Cache size
- * will be two times the page length parameter of the container.
- */
-class CacheMap<K, V> extends LinkedHashMap<K, V> {
- private static final long serialVersionUID = 679999766473555231L;
- private int cacheLimit = SQLContainer.CACHE_RATIO
- * SQLContainer.DEFAULT_PAGE_LENGTH;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
- return size() > cacheLimit;
- }
-
- void setCacheLimit(int limit) {
- cacheLimit = limit > 0 ? limit : SQLContainer.DEFAULT_PAGE_LENGTH;
- }
-
- int getCacheLimit() {
- return cacheLimit;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java b/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
deleted file mode 100644
index 168bce1880..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.sql.Date;
-import java.sql.Time;
-import java.sql.Timestamp;
-
-import com.vaadin.data.Property;
-
-/**
- * ColumnProperty represents the value of one column in a RowItem. In addition
- * to the value, ColumnProperty also contains some basic column attributes such
- * as nullability status, read-only status and data type.
- *
- * Note that depending on the QueryDelegate in use this does not necessarily map
- * into an actual column in a database table.
- */
-final public class ColumnProperty implements Property {
- private static final long serialVersionUID = -3694463129581802457L;
-
- private RowItem owner;
-
- private String propertyId;
-
- private boolean readOnly;
- private boolean allowReadOnlyChange = true;
- private boolean nullable = true;
-
- private Object value;
- private Object changedValue;
- private Class<?> type;
-
- private boolean modified;
-
- private boolean versionColumn;
-
- /**
- * Prevent instantiation without required parameters.
- */
- @SuppressWarnings("unused")
- private ColumnProperty() {
- }
-
- public ColumnProperty(String propertyId, boolean readOnly,
- boolean allowReadOnlyChange, boolean nullable, Object value,
- Class<?> type) {
- if (propertyId == null) {
- throw new IllegalArgumentException("Properties must be named.");
- }
- if (type == null) {
- throw new IllegalArgumentException("Property type must be set.");
- }
- this.propertyId = propertyId;
- this.type = type;
- this.value = value;
-
- this.allowReadOnlyChange = allowReadOnlyChange;
- this.nullable = nullable;
- this.readOnly = readOnly;
- }
-
- @Override
- public Object getValue() {
- if (isModified()) {
- return changedValue;
- }
- return value;
- }
-
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- if (newValue == null && !nullable) {
- throw new NotNullableException(
- "Null values are not allowed for this property.");
- }
- if (readOnly) {
- throw new ReadOnlyException(
- "Cannot set value for read-only property.");
- }
-
- /* Check if this property is a date property. */
- boolean isDateProperty = Time.class.equals(getType())
- || Date.class.equals(getType())
- || Timestamp.class.equals(getType());
-
- if (newValue != null) {
- /* Handle SQL dates, times and Timestamps given as java.util.Date */
- if (isDateProperty) {
- /*
- * Try to get the millisecond value from the new value of this
- * property. Possible type to convert from is java.util.Date.
- */
- long millis = 0;
- if (newValue instanceof java.util.Date) {
- millis = ((java.util.Date) newValue).getTime();
- /*
- * Create the new object based on the millisecond value,
- * according to the type of this property.
- */
- if (Time.class.equals(getType())) {
- newValue = new Time(millis);
- } else if (Date.class.equals(getType())) {
- newValue = new Date(millis);
- } else if (Timestamp.class.equals(getType())) {
- newValue = new Timestamp(millis);
- }
- }
- }
-
- if (!getType().isAssignableFrom(newValue.getClass())) {
- throw new IllegalArgumentException(
- "Illegal value type for ColumnProperty");
- }
-
- /*
- * If the value to be set is the same that has already been set, do
- * not set it again.
- */
- if (isValueAlreadySet(newValue)) {
- return;
- }
- }
-
- /* Set the new value and notify container of the change. */
- changedValue = newValue;
- modified = true;
- owner.getContainer().itemChangeNotification(owner);
- }
-
- private boolean isValueAlreadySet(Object newValue) {
- Object referenceValue = isModified() ? changedValue : value;
-
- return (isNullable() && newValue == null && referenceValue == null)
- || newValue.equals(referenceValue);
- }
-
- @Override
- public Class<?> getType() {
- return type;
- }
-
- @Override
- public boolean isReadOnly() {
- return readOnly;
- }
-
- public boolean isReadOnlyChangeAllowed() {
- return allowReadOnlyChange;
- }
-
- @Override
- public void setReadOnly(boolean newStatus) {
- if (allowReadOnlyChange) {
- readOnly = newStatus;
- }
- }
-
- public String getPropertyId() {
- return propertyId;
- }
-
- /**
- * Returns the value of the Property in human readable textual format.
- *
- * @see java.lang.Object#toString()
- * @deprecated get the string representation from the value
- */
- @Deprecated
- @Override
- public String toString() {
- throw new UnsupportedOperationException(
- "Use ColumnProperty.getValue() instead of ColumnProperty.toString()");
- }
-
- public void setOwner(RowItem owner) {
- if (owner == null) {
- throw new IllegalArgumentException("Owner can not be set to null.");
- }
- if (this.owner != null) {
- throw new IllegalStateException(
- "ColumnProperties can only be bound once.");
- }
- this.owner = owner;
- }
-
- public boolean isModified() {
- return modified;
- }
-
- public boolean isVersionColumn() {
- return versionColumn;
- }
-
- public void setVersionColumn(boolean versionColumn) {
- this.versionColumn = versionColumn;
- }
-
- public boolean isNullable() {
- return nullable;
- }
-
- /**
- * An exception that signals that a <code>null</code> value was passed to
- * the <code>setValue</code> method, but the value of this property can not
- * be set to <code>null</code>.
- */
- @SuppressWarnings("serial")
- public class NotNullableException extends RuntimeException {
-
- /**
- * Constructs a new <code>NotNullableException</code> without a detail
- * message.
- */
- public NotNullableException() {
- }
-
- /**
- * Constructs a new <code>NotNullableException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message
- */
- public NotNullableException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new <code>NotNullableException</code> from another
- * exception.
- *
- * @param cause
- * The cause of the failure
- */
- public NotNullableException(Throwable cause) {
- super(cause);
- }
- }
-
- public void commit() {
- if (isModified()) {
- modified = false;
- value = changedValue;
- }
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java b/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java
deleted file mode 100644
index adfd439ac8..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-
-/**
- * An OptimisticLockException is thrown when trying to update or delete a row
- * that has been changed since last read from the database.
- *
- * OptimisticLockException is a runtime exception because optimistic locking is
- * turned off by default, and as such will never be thrown in a default
- * configuration. In order to turn on optimistic locking, you need to specify
- * the version column in your TableQuery instance.
- *
- * @see TableQuery#setVersionColumn(String)
- *
- * @author Jonatan Kronqvist / Vaadin Ltd
- */
-public class OptimisticLockException extends RuntimeException {
-
- private final RowId rowId;
-
- public OptimisticLockException(RowId rowId) {
- super();
- this.rowId = rowId;
- }
-
- public OptimisticLockException(String msg, RowId rowId) {
- super(msg);
- this.rowId = rowId;
- }
-
- public RowId getRowId() {
- return rowId;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java b/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java
deleted file mode 100644
index c73ffce63a..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-public class ReadOnlyRowId extends RowId {
- private static final long serialVersionUID = -2626764781642012467L;
- private final Integer rowNum;
-
- public ReadOnlyRowId(int rowNum) {
- super();
- this.rowNum = rowNum;
- }
-
- @Override
- public int hashCode() {
- return rowNum.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ReadOnlyRowId)) {
- return false;
- }
- return rowNum.equals(((ReadOnlyRowId) obj).rowNum);
- }
-
- public int getRowNum() {
- return rowNum;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/Reference.java b/src/com/vaadin/data/util/sqlcontainer/Reference.java
deleted file mode 100644
index dea1aa87c0..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/Reference.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * The reference class represents a simple [usually foreign key] reference to
- * another SQLContainer. Actual foreign key reference in the database is not
- * required, but it is recommended to make sure that certain constraints are
- * followed.
- */
-@SuppressWarnings("serial")
-class Reference implements Serializable {
-
- /**
- * The SQLContainer that this reference points to.
- */
- private SQLContainer referencedContainer;
-
- /**
- * The column ID/name in the referencing SQLContainer that contains the key
- * used for the reference.
- */
- private String referencingColumn;
-
- /**
- * The column ID/name in the referenced SQLContainer that contains the key
- * used for the reference.
- */
- private String referencedColumn;
-
- /**
- * Constructs a new reference to be used within the SQLContainer to
- * reference another SQLContainer.
- */
- Reference(SQLContainer referencedContainer, String referencingColumn,
- String referencedColumn) {
- this.referencedContainer = referencedContainer;
- this.referencingColumn = referencingColumn;
- this.referencedColumn = referencedColumn;
- }
-
- SQLContainer getReferencedContainer() {
- return referencedContainer;
- }
-
- String getReferencingColumn() {
- return referencingColumn;
- }
-
- String getReferencedColumn() {
- return referencedColumn;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/RowId.java b/src/com/vaadin/data/util/sqlcontainer/RowId.java
deleted file mode 100644
index 925325134a..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/RowId.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-/**
- * RowId represents identifiers of a single database result set row.
- *
- * The data structure of a RowId is an Object array which contains the values of
- * the primary key columns of the identified row. This allows easy equals()
- * -comparison of RowItems.
- */
-public class RowId implements Serializable {
- private static final long serialVersionUID = -3161778404698901258L;
- protected Object[] id;
-
- /**
- * Prevent instantiation without required parameters.
- */
- protected RowId() {
- }
-
- public RowId(Object[] id) {
- if (id == null) {
- throw new IllegalArgumentException("id parameter must not be null!");
- }
- this.id = id;
- }
-
- public Object[] getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- int result = 31;
- if (id != null) {
- for (Object o : id) {
- if (o != null) {
- result += o.hashCode();
- }
- }
- }
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RowId)) {
- return false;
- }
- Object[] compId = ((RowId) obj).getId();
- if (id == null && compId == null) {
- return true;
- }
- if (id.length != compId.length) {
- return false;
- }
- for (int i = 0; i < id.length; i++) {
- if ((id[i] == null && compId[i] != null)
- || (id[i] != null && !id[i].equals(compId[i]))) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public String toString() {
- StringBuffer s = new StringBuffer();
- for (int i = 0; i < id.length; i++) {
- s.append(id[i]);
- if (i < id.length - 1) {
- s.append("/");
- }
- }
- return s.toString();
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/RowItem.java b/src/com/vaadin/data/util/sqlcontainer/RowItem.java
deleted file mode 100644
index d613a06b63..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/RowItem.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * RowItem represents one row of a result set obtained from a QueryDelegate.
- *
- * Note that depending on the QueryDelegate in use this does not necessarily map
- * into an actual row in a database table.
- */
-public final class RowItem implements Item {
- private static final long serialVersionUID = -6228966439127951408L;
- private SQLContainer container;
- private RowId id;
- private Collection<ColumnProperty> properties;
-
- /**
- * Prevent instantiation without required parameters.
- */
- @SuppressWarnings("unused")
- private RowItem() {
- }
-
- public RowItem(SQLContainer container, RowId id,
- Collection<ColumnProperty> properties) {
- if (container == null) {
- throw new IllegalArgumentException("Container cannot be null.");
- }
- if (id == null) {
- throw new IllegalArgumentException("Row ID cannot be null.");
- }
- this.container = container;
- this.properties = properties;
- /* Set this RowItem as owner to the properties */
- if (properties != null) {
- for (ColumnProperty p : properties) {
- p.setOwner(this);
- }
- }
- this.id = id;
- }
-
- @Override
- public Property<?> getItemProperty(Object id) {
- if (id instanceof String && id != null) {
- for (ColumnProperty cp : properties) {
- if (id.equals(cp.getPropertyId())) {
- return cp;
- }
- }
- }
- return null;
- }
-
- @Override
- public Collection<?> getItemPropertyIds() {
- Collection<String> ids = new ArrayList<String>(properties.size());
- for (ColumnProperty cp : properties) {
- ids.add(cp.getPropertyId());
- }
- return Collections.unmodifiableCollection(ids);
- }
-
- /**
- * Adding properties is not supported. Properties are generated by
- * SQLContainer.
- */
- @Override
- public boolean addItemProperty(Object id, Property property)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Removing properties is not supported. Properties are generated by
- * SQLContainer.
- */
- @Override
- public boolean removeItemProperty(Object id)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- public RowId getId() {
- return id;
- }
-
- public SQLContainer getContainer() {
- return container;
- }
-
- public boolean isModified() {
- if (properties != null) {
- for (ColumnProperty p : properties) {
- if (p.isModified()) {
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- StringBuffer s = new StringBuffer();
- s.append("ID:");
- s.append(getId().toString());
- for (Object propId : getItemPropertyIds()) {
- s.append("|");
- s.append(propId.toString());
- s.append(":");
- Object value = getItemProperty(propId).getValue();
- s.append((null != value) ? value.toString() : null);
- }
- return s.toString();
- }
-
- public void commit() {
- if (properties != null) {
- for (ColumnProperty p : properties) {
- p.commit();
- }
- }
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
deleted file mode 100644
index 5827390723..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
+++ /dev/null
@@ -1,1716 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.IOException;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.ConcurrentModificationException;
-import java.util.Date;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.util.filter.Compare.Equal;
-import com.vaadin.data.util.filter.Like;
-import com.vaadin.data.util.filter.UnsupportedFilterException;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate;
-import com.vaadin.data.util.sqlcontainer.query.QueryDelegate.RowIdChangeListener;
-import com.vaadin.data.util.sqlcontainer.query.TableQuery;
-import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator;
-import com.vaadin.data.util.sqlcontainer.query.generator.OracleGenerator;
-
-public class SQLContainer implements Container, Container.Filterable,
- Container.Indexed, Container.Sortable, Container.ItemSetChangeNotifier {
-
- /** Query delegate */
- private QueryDelegate delegate;
- /** Auto commit mode, default = false */
- private boolean autoCommit = false;
-
- /** Page length = number of items contained in one page */
- private int pageLength = DEFAULT_PAGE_LENGTH;
- public static final int DEFAULT_PAGE_LENGTH = 100;
-
- /** Number of items to cache = CACHE_RATIO x pageLength */
- public static final int CACHE_RATIO = 2;
-
- /** Item and index caches */
- private final Map<Integer, RowId> itemIndexes = new HashMap<Integer, RowId>();
- private final CacheMap<RowId, RowItem> cachedItems = new CacheMap<RowId, RowItem>();
-
- /** Container properties = column names, data types and statuses */
- private final List<String> propertyIds = new ArrayList<String>();
- private final Map<String, Class<?>> propertyTypes = new HashMap<String, Class<?>>();
- private final Map<String, Boolean> propertyReadOnly = new HashMap<String, Boolean>();
- private final Map<String, Boolean> propertyNullable = new HashMap<String, Boolean>();
-
- /** Filters (WHERE) and sorters (ORDER BY) */
- private final List<Filter> filters = new ArrayList<Filter>();
- private final List<OrderBy> sorters = new ArrayList<OrderBy>();
-
- /**
- * Total number of items available in the data source using the current
- * query, filters and sorters.
- */
- private int size;
-
- /**
- * Size updating logic. Do not update size from data source if it has been
- * updated in the last sizeValidMilliSeconds milliseconds.
- */
- private final int sizeValidMilliSeconds = 10000;
- private boolean sizeDirty = true;
- private Date sizeUpdated = new Date();
-
- /** Starting row number of the currently fetched page */
- private int currentOffset;
-
- /** ItemSetChangeListeners */
- private LinkedList<Container.ItemSetChangeListener> itemSetChangeListeners;
-
- /** Temporary storage for modified items and items to be removed and added */
- private final Map<RowId, RowItem> removedItems = new HashMap<RowId, RowItem>();
- private final List<RowItem> addedItems = new ArrayList<RowItem>();
- private final List<RowItem> modifiedItems = new ArrayList<RowItem>();
-
- /** List of references to other SQLContainers */
- private final Map<SQLContainer, Reference> references = new HashMap<SQLContainer, Reference>();
-
- /** Cache flush notification system enabled. Disabled by default. */
- private boolean notificationsEnabled;
-
- /**
- * Prevent instantiation without a QueryDelegate.
- */
- @SuppressWarnings("unused")
- private SQLContainer() {
- }
-
- /**
- * Creates and initializes SQLContainer using the given QueryDelegate
- *
- * @param delegate
- * QueryDelegate implementation
- * @throws SQLException
- */
- public SQLContainer(QueryDelegate delegate) throws SQLException {
- if (delegate == null) {
- throw new IllegalArgumentException(
- "QueryDelegate must not be null.");
- }
- this.delegate = delegate;
- getPropertyIds();
- cachedItems.setCacheLimit(CACHE_RATIO * getPageLength());
- }
-
- /**************************************/
- /** Methods from interface Container **/
- /**************************************/
-
- /**
- * Note! If auto commit mode is enabled, this method will still return the
- * temporary row ID assigned for the item. Implement
- * QueryDelegate.RowIdChangeListener to receive the actual Row ID value
- * after the addition has been committed.
- *
- * {@inheritDoc}
- */
-
- @Override
- public Object addItem() throws UnsupportedOperationException {
- Object emptyKey[] = new Object[delegate.getPrimaryKeyColumns().size()];
- RowId itemId = new TemporaryRowId(emptyKey);
- // Create new empty column properties for the row item.
- List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>();
- for (String propertyId : propertyIds) {
- /* Default settings for new item properties. */
- itemProperties
- .add(new ColumnProperty(propertyId, propertyReadOnly
- .get(propertyId),
- !propertyReadOnly.get(propertyId), propertyNullable
- .get(propertyId), null, getType(propertyId)));
- }
- RowItem newRowItem = new RowItem(this, itemId, itemProperties);
-
- if (autoCommit) {
- /* Add and commit instantly */
- try {
- if (delegate instanceof TableQuery) {
- itemId = ((TableQuery) delegate)
- .storeRowImmediately(newRowItem);
- } else {
- delegate.beginTransaction();
- delegate.storeRow(newRowItem);
- delegate.commit();
- }
- refresh();
- if (notificationsEnabled) {
- CacheFlushNotifier.notifyOfCacheFlush(this);
- }
- getLogger().log(Level.FINER, "Row added to DB...");
- return itemId;
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "Failed to add row to DB. Rolling back.", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- getLogger().log(Level.SEVERE,
- "Failed to roll back row addition", e);
- }
- return null;
- }
- } else {
- addedItems.add(newRowItem);
- fireContentsChange();
- return itemId;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#containsId(java.lang.Object)
- */
-
- @Override
- public boolean containsId(Object itemId) {
- if (itemId == null) {
- return false;
- }
-
- if (cachedItems.containsKey(itemId)) {
- return true;
- } else {
- for (RowItem item : addedItems) {
- if (item.getId().equals(itemId)) {
- return itemPassesFilters(item);
- }
- }
- }
- if (removedItems.containsKey(itemId)) {
- return false;
- }
-
- if (itemId instanceof ReadOnlyRowId) {
- int rowNum = ((ReadOnlyRowId) itemId).getRowNum();
- return rowNum >= 0 && rowNum < size;
- }
-
- if (itemId instanceof RowId && !(itemId instanceof TemporaryRowId)) {
- try {
- return delegate.containsRowWithKey(((RowId) itemId).getId());
- } catch (Exception e) {
- /* Query failed, just return false. */
- getLogger().log(Level.WARNING, "containsId query failed", e);
- }
- }
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerProperty(java.lang.Object,
- * java.lang.Object)
- */
-
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- Item item = getItem(itemId);
- if (item == null) {
- return null;
- }
- return item.getItemProperty(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getContainerPropertyIds()
- */
-
- @Override
- public Collection<?> getContainerPropertyIds() {
- return Collections.unmodifiableCollection(propertyIds);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getItem(java.lang.Object)
- */
-
- @Override
- public Item getItem(Object itemId) {
- if (!cachedItems.containsKey(itemId)) {
- int index = indexOfId(itemId);
- if (index >= size) {
- // The index is in the added items
- int offset = index - size;
- RowItem item = addedItems.get(offset);
- if (itemPassesFilters(item)) {
- return item;
- } else {
- return null;
- }
- } else {
- // load the item into cache
- updateOffsetAndCache(index);
- }
- }
- return cachedItems.get(itemId);
- }
-
- /**
- * Bypasses in-memory filtering to return items that are cached in memory.
- * <em>NOTE</em>: This does not bypass database-level filtering.
- *
- * @param itemId
- * the id of the item to retrieve.
- * @return the item represented by itemId.
- */
- public Item getItemUnfiltered(Object itemId) {
- if (!cachedItems.containsKey(itemId)) {
- for (RowItem item : addedItems) {
- if (item.getId().equals(itemId)) {
- return item;
- }
- }
- }
- return cachedItems.get(itemId);
- }
-
- /**
- * NOTE! Do not use this method if in any way avoidable. This method doesn't
- * (and cannot) use lazy loading, which means that all rows in the database
- * will be loaded into memory.
- *
- * {@inheritDoc}
- */
-
- @Override
- public Collection<?> getItemIds() {
- updateCount();
- ArrayList<RowId> ids = new ArrayList<RowId>();
- ResultSet rs = null;
- try {
- // Load ALL rows :(
- delegate.beginTransaction();
- rs = delegate.getResults(0, 0);
- List<String> pKeys = delegate.getPrimaryKeyColumns();
- while (rs.next()) {
- RowId id = null;
- if (pKeys.isEmpty()) {
- /* Create a read only itemId */
- id = new ReadOnlyRowId(rs.getRow());
- } else {
- /* Generate itemId for the row based on primary key(s) */
- Object[] itemId = new Object[pKeys.size()];
- for (int i = 0; i < pKeys.size(); i++) {
- itemId[i] = rs.getObject(pKeys.get(i));
- }
- id = new RowId(itemId);
- }
- if (id != null && !removedItems.containsKey(id)) {
- ids.add(id);
- }
- }
- rs.getStatement().close();
- rs.close();
- delegate.commit();
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "getItemIds() failed, rolling back.", e);
- try {
- delegate.rollback();
- } catch (SQLException e1) {
- getLogger().log(Level.SEVERE, "Failed to roll back state", e1);
- }
- try {
- rs.getStatement().close();
- rs.close();
- } catch (SQLException e1) {
- getLogger().log(Level.WARNING, "Closing session failed", e1);
- }
- throw new RuntimeException("Failed to fetch item indexes.", e);
- }
- for (RowItem item : getFilteredAddedItems()) {
- ids.add(item.getId());
- }
- return Collections.unmodifiableCollection(ids);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#getType(java.lang.Object)
- */
-
- @Override
- public Class<?> getType(Object propertyId) {
- if (!propertyIds.contains(propertyId)) {
- return null;
- }
- return propertyTypes.get(propertyId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#size()
- */
-
- @Override
- public int size() {
- updateCount();
- return size + sizeOfAddedItems() - removedItems.size();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeItem(java.lang.Object)
- */
-
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
- if (!containsId(itemId)) {
- return false;
- }
- for (RowItem item : addedItems) {
- if (item.getId().equals(itemId)) {
- addedItems.remove(item);
- fireContentsChange();
- return true;
- }
- }
-
- if (autoCommit) {
- /* Remove and commit instantly. */
- Item i = getItem(itemId);
- if (i == null) {
- return false;
- }
- try {
- delegate.beginTransaction();
- boolean success = delegate.removeRow((RowItem) i);
- delegate.commit();
- refresh();
- if (notificationsEnabled) {
- CacheFlushNotifier.notifyOfCacheFlush(this);
- }
- if (success) {
- getLogger().log(Level.FINER, "Row removed from DB...");
- }
- return success;
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "Failed to remove row, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- /* Nothing can be done here */
- getLogger().log(Level.SEVERE,
- "Failed to rollback row removal", ee);
- }
- return false;
- } catch (OptimisticLockException e) {
- getLogger().log(Level.WARNING,
- "Failed to remove row, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- /* Nothing can be done here */
- getLogger().log(Level.SEVERE,
- "Failed to rollback row removal", ee);
- }
- throw e;
- }
- } else {
- removedItems.put((RowId) itemId, (RowItem) getItem(itemId));
- cachedItems.remove(itemId);
- refresh();
- return true;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeAllItems()
- */
-
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
- if (autoCommit) {
- /* Remove and commit instantly. */
- try {
- delegate.beginTransaction();
- boolean success = true;
- for (Object id : getItemIds()) {
- if (!delegate.removeRow((RowItem) getItem(id))) {
- success = false;
- }
- }
- if (success) {
- delegate.commit();
- getLogger().log(Level.FINER, "All rows removed from DB...");
- refresh();
- if (notificationsEnabled) {
- CacheFlushNotifier.notifyOfCacheFlush(this);
- }
- } else {
- delegate.rollback();
- }
- return success;
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "removeAllItems() failed, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- /* Nothing can be done here */
- getLogger().log(Level.SEVERE, "Failed to roll back", ee);
- }
- return false;
- } catch (OptimisticLockException e) {
- getLogger().log(Level.WARNING,
- "removeAllItems() failed, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- /* Nothing can be done here */
- getLogger().log(Level.SEVERE, "Failed to roll back", ee);
- }
- throw e;
- }
- } else {
- for (Object id : getItemIds()) {
- removedItems.put((RowId) id, (RowItem) getItem(id));
- cachedItems.remove(id);
- }
- refresh();
- return true;
- }
- }
-
- /*************************************************/
- /** Methods from interface Container.Filterable **/
- /*************************************************/
-
- /**
- * {@inheritDoc}
- */
-
- @Override
- public void addContainerFilter(Filter filter)
- throws UnsupportedFilterException {
- // filter.setCaseSensitive(!ignoreCase);
-
- filters.add(filter);
- refresh();
- }
-
- /**
- * {@inheritDoc}
- */
-
- @Override
- public void removeContainerFilter(Filter filter) {
- filters.remove(filter);
- refresh();
- }
-
- /**
- * {@inheritDoc}
- */
- public void addContainerFilter(Object propertyId, String filterString,
- boolean ignoreCase, boolean onlyMatchPrefix) {
- if (propertyId == null || !propertyIds.contains(propertyId)) {
- return;
- }
-
- /* Generate Filter -object */
- String likeStr = onlyMatchPrefix ? filterString + "%" : "%"
- + filterString + "%";
- Like like = new Like(propertyId.toString(), likeStr);
- like.setCaseSensitive(!ignoreCase);
- filters.add(like);
- refresh();
- }
-
- /**
- * {@inheritDoc}
- */
- public void removeContainerFilters(Object propertyId) {
- ArrayList<Filter> toRemove = new ArrayList<Filter>();
- for (Filter f : filters) {
- if (f.appliesToProperty(propertyId)) {
- toRemove.add(f);
- }
- }
- filters.removeAll(toRemove);
- refresh();
- }
-
- /**
- * {@inheritDoc}
- */
-
- @Override
- public void removeAllContainerFilters() {
- filters.clear();
- refresh();
- }
-
- /**********************************************/
- /** Methods from interface Container.Indexed **/
- /**********************************************/
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#indexOfId(java.lang.Object)
- */
-
- @Override
- public int indexOfId(Object itemId) {
- // First check if the id is in the added items
- for (int ix = 0; ix < addedItems.size(); ix++) {
- RowItem item = addedItems.get(ix);
- if (item.getId().equals(itemId)) {
- if (itemPassesFilters(item)) {
- updateCount();
- return size + ix;
- } else {
- return -1;
- }
- }
- }
-
- if (!containsId(itemId)) {
- return -1;
- }
- if (cachedItems.isEmpty()) {
- getPage();
- }
- int size = size();
- boolean wrappedAround = false;
- while (!wrappedAround) {
- for (Integer i : itemIndexes.keySet()) {
- if (itemIndexes.get(i).equals(itemId)) {
- return i;
- }
- }
- // load in the next page.
- int nextIndex = (currentOffset / (pageLength * CACHE_RATIO) + 1)
- * (pageLength * CACHE_RATIO);
- if (nextIndex >= size) {
- // Container wrapped around, start from index 0.
- wrappedAround = true;
- nextIndex = 0;
- }
- updateOffsetAndCache(nextIndex);
- }
- return -1;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#getIdByIndex(int)
- */
-
- @Override
- public Object getIdByIndex(int index) {
- if (index < 0 || index > size() - 1) {
- return null;
- }
- if (index < size) {
- if (itemIndexes.keySet().contains(index)) {
- return itemIndexes.get(index);
- }
- updateOffsetAndCache(index);
- return itemIndexes.get(index);
- } else {
- // The index is in the added items
- int offset = index - size;
- return addedItems.get(offset).getId();
- }
- }
-
- /**********************************************/
- /** Methods from interface Container.Ordered **/
- /**********************************************/
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object)
- */
-
- @Override
- public Object nextItemId(Object itemId) {
- return getIdByIndex(indexOfId(itemId) + 1);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object)
- */
-
- @Override
- public Object prevItemId(Object itemId) {
- return getIdByIndex(indexOfId(itemId) - 1);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#firstItemId()
- */
-
- @Override
- public Object firstItemId() {
- updateCount();
- if (size == 0) {
- if (addedItems.isEmpty()) {
- return null;
- } else {
- int ix = -1;
- do {
- ix++;
- } while (!itemPassesFilters(addedItems.get(ix))
- && ix < addedItems.size());
- if (ix < addedItems.size()) {
- return addedItems.get(ix).getId();
- }
- }
- }
- if (!itemIndexes.containsKey(0)) {
- updateOffsetAndCache(0);
- }
- return itemIndexes.get(0);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#lastItemId()
- */
-
- @Override
- public Object lastItemId() {
- if (addedItems.isEmpty()) {
- int lastIx = size() - 1;
- if (!itemIndexes.containsKey(lastIx)) {
- updateOffsetAndCache(size - 1);
- }
- return itemIndexes.get(lastIx);
- } else {
- int ix = addedItems.size();
- do {
- ix--;
- } while (!itemPassesFilters(addedItems.get(ix)) && ix >= 0);
- if (ix >= 0) {
- return addedItems.get(ix).getId();
- } else {
- return null;
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object)
- */
-
- @Override
- public boolean isFirstId(Object itemId) {
- return firstItemId().equals(itemId);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object)
- */
-
- @Override
- public boolean isLastId(Object itemId) {
- return lastItemId().equals(itemId);
- }
-
- /***********************************************/
- /** Methods from interface Container.Sortable **/
- /***********************************************/
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
- * boolean[])
- */
-
- @Override
- public void sort(Object[] propertyId, boolean[] ascending) {
- sorters.clear();
- if (propertyId == null || propertyId.length == 0) {
- refresh();
- return;
- }
- /* Generate OrderBy -objects */
- boolean asc = true;
- for (int i = 0; i < propertyId.length; i++) {
- /* Check that the property id is valid */
- if (propertyId[i] instanceof String
- && propertyIds.contains(propertyId[i])) {
- try {
- asc = ascending[i];
- } catch (Exception e) {
- getLogger().log(Level.WARNING, "", e);
- }
- sorters.add(new OrderBy((String) propertyId[i], asc));
- }
- }
- refresh();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds()
- */
-
- @Override
- public Collection<?> getSortableContainerPropertyIds() {
- return getContainerPropertyIds();
- }
-
- /**************************************/
- /** Methods specific to SQLContainer **/
- /**************************************/
-
- /**
- * Refreshes the container - clears all caches and resets size and offset.
- * Does NOT remove sorting or filtering rules!
- */
- public void refresh() {
- sizeDirty = true;
- currentOffset = 0;
- cachedItems.clear();
- itemIndexes.clear();
- fireContentsChange();
- }
-
- /**
- * Returns modify state of the container.
- *
- * @return true if contents of this container have been modified
- */
- public boolean isModified() {
- return !removedItems.isEmpty() || !addedItems.isEmpty()
- || !modifiedItems.isEmpty();
- }
-
- /**
- * Set auto commit mode enabled or disabled. Auto commit mode means that all
- * changes made to items of this container will be immediately written to
- * the underlying data source.
- *
- * @param autoCommitEnabled
- * true to enable auto commit mode
- */
- public void setAutoCommit(boolean autoCommitEnabled) {
- autoCommit = autoCommitEnabled;
- }
-
- /**
- * Returns status of the auto commit mode.
- *
- * @return true if auto commit mode is enabled
- */
- public boolean isAutoCommit() {
- return autoCommit;
- }
-
- /**
- * Returns the currently set page length.
- *
- * @return current page length
- */
- public int getPageLength() {
- return pageLength;
- }
-
- /**
- * Sets the page length used in lazy fetching of items from the data source.
- * Also resets the cache size to match the new page length.
- *
- * As a side effect the container will be refreshed.
- *
- * @param pageLength
- * new page length
- */
- public void setPageLength(int pageLength) {
- setPageLengthInternal(pageLength);
- refresh();
- }
-
- /**
- * Sets the page length internally, without refreshing the container.
- *
- * @param pageLength
- * the new page length
- */
- private void setPageLengthInternal(int pageLength) {
- this.pageLength = pageLength > 0 ? pageLength : DEFAULT_PAGE_LENGTH;
- cachedItems.setCacheLimit(CACHE_RATIO * getPageLength());
- }
-
- /**
- * Adds the given OrderBy to this container and refreshes the container
- * contents with the new sorting rules.
- *
- * Note that orderBy.getColumn() must return a column name that exists in
- * this container.
- *
- * @param orderBy
- * OrderBy to be added to the container sorting rules
- */
- public void addOrderBy(OrderBy orderBy) {
- if (orderBy == null) {
- return;
- }
- if (!propertyIds.contains(orderBy.getColumn())) {
- throw new IllegalArgumentException(
- "The column given for sorting does not exist in this container.");
- }
- sorters.add(orderBy);
- refresh();
- }
-
- /**
- * Commits all the changes, additions and removals made to the items of this
- * container.
- *
- * @throws UnsupportedOperationException
- * @throws SQLException
- */
- public void commit() throws UnsupportedOperationException, SQLException {
- try {
- getLogger().log(Level.FINER,
- "Commiting changes through delegate...");
- delegate.beginTransaction();
- /* Perform buffered deletions */
- for (RowItem item : removedItems.values()) {
- if (!delegate.removeRow(item)) {
- throw new SQLException("Removal failed for row with ID: "
- + item.getId());
- }
- }
- /* Perform buffered modifications */
- for (RowItem item : modifiedItems) {
- if (delegate.storeRow(item) > 0) {
- /*
- * Also reset the modified state in the item in case it is
- * reused e.g. in a form.
- */
- item.commit();
- } else {
- delegate.rollback();
- refresh();
- throw new ConcurrentModificationException(
- "Item with the ID '" + item.getId()
- + "' has been externally modified.");
- }
- }
- /* Perform buffered additions */
- for (RowItem item : addedItems) {
- delegate.storeRow(item);
- }
- delegate.commit();
- removedItems.clear();
- addedItems.clear();
- modifiedItems.clear();
- refresh();
- if (notificationsEnabled) {
- CacheFlushNotifier.notifyOfCacheFlush(this);
- }
- } catch (SQLException e) {
- delegate.rollback();
- throw e;
- } catch (OptimisticLockException e) {
- delegate.rollback();
- throw e;
- }
- }
-
- /**
- * Rolls back all the changes, additions and removals made to the items of
- * this container.
- *
- * @throws UnsupportedOperationException
- * @throws SQLException
- */
- public void rollback() throws UnsupportedOperationException, SQLException {
- getLogger().log(Level.FINE, "Rolling back changes...");
- removedItems.clear();
- addedItems.clear();
- modifiedItems.clear();
- refresh();
- }
-
- /**
- * Notifies this container that a property in the given item has been
- * modified. The change will be buffered or made instantaneously depending
- * on auto commit mode.
- *
- * @param changedItem
- * item that has a modified property
- */
- void itemChangeNotification(RowItem changedItem) {
- if (autoCommit) {
- try {
- delegate.beginTransaction();
- if (delegate.storeRow(changedItem) == 0) {
- delegate.rollback();
- refresh();
- throw new ConcurrentModificationException(
- "Item with the ID '" + changedItem.getId()
- + "' has been externally modified.");
- }
- delegate.commit();
- if (notificationsEnabled) {
- CacheFlushNotifier.notifyOfCacheFlush(this);
- }
- getLogger().log(Level.FINER, "Row updated to DB...");
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "itemChangeNotification failed, rolling back...", e);
- try {
- delegate.rollback();
- } catch (SQLException ee) {
- /* Nothing can be done here */
- getLogger().log(Level.SEVERE, "Rollback failed", e);
- }
- throw new RuntimeException(e);
- }
- } else {
- if (!(changedItem.getId() instanceof TemporaryRowId)
- && !modifiedItems.contains(changedItem)) {
- modifiedItems.add(changedItem);
- }
- }
- }
-
- /**
- * Determines a new offset for updating the row cache. The offset is
- * calculated from the given index, and will be fixed to match the start of
- * a page, based on the value of pageLength.
- *
- * @param index
- * Index of the item that was requested, but not found in cache
- */
- private void updateOffsetAndCache(int index) {
- if (itemIndexes.containsKey(index)) {
- return;
- }
- currentOffset = (index / (pageLength * CACHE_RATIO))
- * (pageLength * CACHE_RATIO);
- if (currentOffset < 0) {
- currentOffset = 0;
- }
- getPage();
- }
-
- /**
- * Fetches new count of rows from the data source, if needed.
- */
- private void updateCount() {
- if (!sizeDirty
- && new Date().getTime() < sizeUpdated.getTime()
- + sizeValidMilliSeconds) {
- return;
- }
- try {
- try {
- delegate.setFilters(filters);
- } catch (UnsupportedOperationException e) {
- getLogger().log(Level.FINE,
- "The query delegate doesn't support filtering", e);
- }
- try {
- delegate.setOrderBy(sorters);
- } catch (UnsupportedOperationException e) {
- getLogger().log(Level.FINE,
- "The query delegate doesn't support filtering", e);
- }
- int newSize = delegate.getCount();
- if (newSize != size) {
- size = newSize;
- refresh();
- }
- sizeUpdated = new Date();
- sizeDirty = false;
- getLogger().log(Level.FINER,
- "Updated row count. New count is: " + size);
- } catch (SQLException e) {
- throw new RuntimeException("Failed to update item set size.", e);
- }
- }
-
- /**
- * Fetches property id's (column names and their types) from the data
- * source.
- *
- * @throws SQLException
- */
- private void getPropertyIds() throws SQLException {
- propertyIds.clear();
- propertyTypes.clear();
- delegate.setFilters(null);
- delegate.setOrderBy(null);
- ResultSet rs = null;
- ResultSetMetaData rsmd = null;
- try {
- delegate.beginTransaction();
- rs = delegate.getResults(0, 1);
- boolean resultExists = rs.next();
- rsmd = rs.getMetaData();
- Class<?> type = null;
- for (int i = 1; i <= rsmd.getColumnCount(); i++) {
- if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) {
- continue;
- }
- String colName = rsmd.getColumnLabel(i);
- /*
- * Make sure not to add the same colName twice. This can easily
- * happen if the SQL query joins many tables with an ID column.
- */
- if (!propertyIds.contains(colName)) {
- propertyIds.add(colName);
- }
- /* Try to determine the column's JDBC class by all means. */
- if (resultExists && rs.getObject(i) != null) {
- type = rs.getObject(i).getClass();
- } else {
- try {
- type = Class.forName(rsmd.getColumnClassName(i));
- } catch (Exception e) {
- getLogger().log(Level.WARNING, "Class not found", e);
- /* On failure revert to Object and hope for the best. */
- type = Object.class;
- }
- }
- /*
- * Determine read only and nullability status of the column. A
- * column is read only if it is reported as either read only or
- * auto increment by the database, and also it is set as the
- * version column in a TableQuery delegate.
- */
- boolean readOnly = rsmd.isAutoIncrement(i)
- || rsmd.isReadOnly(i);
- if (delegate instanceof TableQuery
- && rsmd.getColumnLabel(i).equals(
- ((TableQuery) delegate).getVersionColumn())) {
- readOnly = true;
- }
- propertyReadOnly.put(colName, readOnly);
- propertyNullable.put(colName,
- rsmd.isNullable(i) == ResultSetMetaData.columnNullable);
- propertyTypes.put(colName, type);
- }
- rs.getStatement().close();
- rs.close();
- delegate.commit();
- getLogger().log(Level.FINER, "Property IDs fetched.");
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "Failed to fetch property ids, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException e1) {
- getLogger().log(Level.SEVERE, "Failed to roll back", e1);
- }
- try {
- if (rs != null) {
- if (rs.getStatement() != null) {
- rs.getStatement().close();
- }
- rs.close();
- }
- } catch (SQLException e1) {
- getLogger().log(Level.WARNING, "Failed to close session", e1);
- }
- throw e;
- }
- }
-
- /**
- * Fetches a page from the data source based on the values of pageLenght and
- * currentOffset. Also updates the set of primary keys, used in
- * identification of RowItems.
- */
- private void getPage() {
- updateCount();
- ResultSet rs = null;
- ResultSetMetaData rsmd = null;
- cachedItems.clear();
- itemIndexes.clear();
- try {
- try {
- delegate.setOrderBy(sorters);
- } catch (UnsupportedOperationException e) {
- /* The query delegate doesn't support sorting. */
- /* No need to do anything. */
- getLogger().log(Level.FINE,
- "The query delegate doesn't support sorting", e);
- }
- delegate.beginTransaction();
- rs = delegate.getResults(currentOffset, pageLength * CACHE_RATIO);
- rsmd = rs.getMetaData();
- List<String> pKeys = delegate.getPrimaryKeyColumns();
- // }
- /* Create new items and column properties */
- ColumnProperty cp = null;
- int rowCount = currentOffset;
- if (!delegate.implementationRespectsPagingLimits()) {
- rowCount = currentOffset = 0;
- setPageLengthInternal(size);
- }
- while (rs.next()) {
- List<ColumnProperty> itemProperties = new ArrayList<ColumnProperty>();
- /* Generate row itemId based on primary key(s) */
- Object[] itemId = new Object[pKeys.size()];
- for (int i = 0; i < pKeys.size(); i++) {
- itemId[i] = rs.getObject(pKeys.get(i));
- }
- RowId id = null;
- if (pKeys.isEmpty()) {
- id = new ReadOnlyRowId(rs.getRow());
- } else {
- id = new RowId(itemId);
- }
- List<String> propertiesToAdd = new ArrayList<String>(
- propertyIds);
- if (!removedItems.containsKey(id)) {
- for (int i = 1; i <= rsmd.getColumnCount(); i++) {
- if (!isColumnIdentifierValid(rsmd.getColumnLabel(i))) {
- continue;
- }
- String colName = rsmd.getColumnLabel(i);
- Object value = rs.getObject(i);
- Class<?> type = value != null ? value.getClass()
- : Object.class;
- if (value == null) {
- for (String propName : propertyTypes.keySet()) {
- if (propName.equals(rsmd.getColumnLabel(i))) {
- type = propertyTypes.get(propName);
- break;
- }
- }
- }
- /*
- * In case there are more than one column with the same
- * name, add only the first one. This can easily happen
- * if you join many tables where each table has an ID
- * column.
- */
- if (propertiesToAdd.contains(colName)) {
- cp = new ColumnProperty(colName,
- propertyReadOnly.get(colName),
- !propertyReadOnly.get(colName),
- propertyNullable.get(colName), value, type);
- itemProperties.add(cp);
- propertiesToAdd.remove(colName);
- }
- }
- /* Cache item */
- itemIndexes.put(rowCount, id);
-
- // if an item with the id is contained in the modified
- // cache, then use this record and add it to the cached
- // items. Otherwise create a new item
- int modifiedIndex = indexInModifiedCache(id);
- if (modifiedIndex != -1) {
- cachedItems.put(id, modifiedItems.get(modifiedIndex));
- } else {
- cachedItems.put(id, new RowItem(this, id,
- itemProperties));
- }
-
- rowCount++;
- }
- }
- rs.getStatement().close();
- rs.close();
- delegate.commit();
- getLogger().log(
- Level.FINER,
- "Fetched " + pageLength * CACHE_RATIO
- + " rows starting from " + currentOffset);
- } catch (SQLException e) {
- getLogger().log(Level.WARNING,
- "Failed to fetch rows, rolling back", e);
- try {
- delegate.rollback();
- } catch (SQLException e1) {
- getLogger().log(Level.SEVERE, "Failed to roll back", e1);
- }
- try {
- if (rs != null) {
- if (rs.getStatement() != null) {
- rs.getStatement().close();
- rs.close();
- }
- }
- } catch (SQLException e1) {
- getLogger().log(Level.WARNING, "Failed to close session", e1);
- }
- throw new RuntimeException("Failed to fetch page.", e);
- }
- }
-
- /**
- * Returns the index of the item with the given itemId for the modified
- * cache.
- *
- * @param itemId
- * @return the index of the item with the itemId in the modified cache. Or
- * -1 if not found.
- */
- private int indexInModifiedCache(Object itemId) {
- for (int ix = 0; ix < modifiedItems.size(); ix++) {
- RowItem item = modifiedItems.get(ix);
- if (item.getId().equals(itemId)) {
- return ix;
- }
- }
- return -1;
- }
-
- private int sizeOfAddedItems() {
- return getFilteredAddedItems().size();
- }
-
- private List<RowItem> getFilteredAddedItems() {
- ArrayList<RowItem> filtered = new ArrayList<RowItem>(addedItems);
- if (filters != null && !filters.isEmpty()) {
- for (RowItem item : addedItems) {
- if (!itemPassesFilters(item)) {
- filtered.remove(item);
- }
- }
- }
- return filtered;
- }
-
- private boolean itemPassesFilters(RowItem item) {
- for (Filter filter : filters) {
- if (!filter.passesFilter(item.getId(), item)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks is the given column identifier valid to be used with SQLContainer.
- * Currently the only non-valid identifier is "rownum" when MSSQL or Oracle
- * is used. This is due to the way the SELECT queries are constructed in
- * order to implement paging in these databases.
- *
- * @param identifier
- * Column identifier
- * @return true if the identifier is valid
- */
- private boolean isColumnIdentifierValid(String identifier) {
- if (identifier.equalsIgnoreCase("rownum")
- && delegate instanceof TableQuery) {
- TableQuery tq = (TableQuery) delegate;
- if (tq.getSqlGenerator() instanceof MSSQLGenerator
- || tq.getSqlGenerator() instanceof OracleGenerator) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns the QueryDelegate set for this SQLContainer.
- *
- * @return current querydelegate
- */
- protected QueryDelegate getQueryDelegate() {
- return delegate;
- }
-
- /************************************/
- /** UNSUPPORTED CONTAINER FEATURES **/
- /************************************/
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object,
- * java.lang.Class, java.lang.Object)
- */
-
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object)
- */
-
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#addItem(java.lang.Object)
- */
-
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object,
- * java.lang.Object)
- */
-
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#addItemAt(int, java.lang.Object)
- */
-
- @Override
- public Item addItemAt(int index, Object newItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Indexed#addItemAt(int)
- */
-
- @Override
- public Object addItemAt(int index) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
- */
-
- @Override
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /******************************************/
- /** ITEMSETCHANGENOTIFIER IMPLEMENTATION **/
- /******************************************/
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin
- * .data.Container.ItemSetChangeListener)
- */
-
- @Override
- public void addListener(Container.ItemSetChangeListener listener) {
- if (itemSetChangeListeners == null) {
- itemSetChangeListeners = new LinkedList<Container.ItemSetChangeListener>();
- }
- itemSetChangeListeners.add(listener);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin
- * .data.Container.ItemSetChangeListener)
- */
-
- @Override
- public void removeListener(Container.ItemSetChangeListener listener) {
- if (itemSetChangeListeners != null) {
- itemSetChangeListeners.remove(listener);
- }
- }
-
- protected void fireContentsChange() {
- if (itemSetChangeListeners != null) {
- final Object[] l = itemSetChangeListeners.toArray();
- final Container.ItemSetChangeEvent event = new SQLContainer.ItemSetChangeEvent(
- this);
- for (int i = 0; i < l.length; i++) {
- ((Container.ItemSetChangeListener) l[i])
- .containerItemSetChange(event);
- }
- }
- }
-
- /**
- * Simple ItemSetChangeEvent implementation.
- */
- @SuppressWarnings("serial")
- public static class ItemSetChangeEvent extends EventObject implements
- Container.ItemSetChangeEvent {
-
- private ItemSetChangeEvent(SQLContainer source) {
- super(source);
- }
-
- @Override
- public Container getContainer() {
- return (Container) getSource();
- }
- }
-
- /**************************************************/
- /** ROWIDCHANGELISTENER PASSING TO QUERYDELEGATE **/
- /**************************************************/
-
- /**
- * Adds a RowIdChangeListener to the QueryDelegate
- *
- * @param listener
- */
- public void addListener(RowIdChangeListener listener) {
- if (delegate instanceof QueryDelegate.RowIdChangeNotifier) {
- ((QueryDelegate.RowIdChangeNotifier) delegate)
- .addListener(listener);
- }
- }
-
- /**
- * Removes a RowIdChangeListener from the QueryDelegate
- *
- * @param listener
- */
- public void removeListener(RowIdChangeListener listener) {
- if (delegate instanceof QueryDelegate.RowIdChangeNotifier) {
- ((QueryDelegate.RowIdChangeNotifier) delegate)
- .removeListener(listener);
- }
- }
-
- /**
- * Calling this will enable this SQLContainer to send and receive cache
- * flush notifications for its lifetime.
- */
- public void enableCacheFlushNotifications() {
- if (!notificationsEnabled) {
- notificationsEnabled = true;
- CacheFlushNotifier.addInstance(this);
- }
- }
-
- /******************************************/
- /** Referencing mechanism implementation **/
- /******************************************/
-
- /**
- * Adds a new reference to the given SQLContainer. In addition to the
- * container you must provide the column (property) names used for the
- * reference in both this and the referenced SQLContainer.
- *
- * Note that multiple references pointing to the same SQLContainer are not
- * supported.
- *
- * @param refdCont
- * Target SQLContainer of the new reference
- * @param refingCol
- * Column (property) name in this container storing the (foreign
- * key) reference
- * @param refdCol
- * Column (property) name in the referenced container storing the
- * referenced key
- */
- public void addReference(SQLContainer refdCont, String refingCol,
- String refdCol) {
- if (refdCont == null) {
- throw new IllegalArgumentException(
- "Referenced SQLContainer can not be null.");
- }
- if (!getContainerPropertyIds().contains(refingCol)) {
- throw new IllegalArgumentException(
- "Given referencing column name is invalid."
- + " Please ensure that this container"
- + " contains a property ID named: " + refingCol);
- }
- if (!refdCont.getContainerPropertyIds().contains(refdCol)) {
- throw new IllegalArgumentException(
- "Given referenced column name is invalid."
- + " Please ensure that the referenced container"
- + " contains a property ID named: " + refdCol);
- }
- if (references.keySet().contains(refdCont)) {
- throw new IllegalArgumentException(
- "An SQLContainer instance can only be referenced once.");
- }
- references.put(refdCont, new Reference(refdCont, refingCol, refdCol));
- }
-
- /**
- * Removes the reference pointing to the given SQLContainer.
- *
- * @param refdCont
- * Target SQLContainer of the reference
- * @return true if successful, false if the reference did not exist
- */
- public boolean removeReference(SQLContainer refdCont) {
- if (refdCont == null) {
- throw new IllegalArgumentException(
- "Referenced SQLContainer can not be null.");
- }
- return references.remove(refdCont) == null ? false : true;
- }
-
- /**
- * Sets the referenced item. The referencing column of the item in this
- * container is updated accordingly.
- *
- * @param itemId
- * Item Id of the reference source (from this container)
- * @param refdItemId
- * Item Id of the reference target (from referenced container)
- * @param refdCont
- * Target SQLContainer of the reference
- * @return true if the referenced item was successfully set, false on
- * failure
- */
- public boolean setReferencedItem(Object itemId, Object refdItemId,
- SQLContainer refdCont) {
- if (refdCont == null) {
- throw new IllegalArgumentException(
- "Referenced SQLContainer can not be null.");
- }
- Reference r = references.get(refdCont);
- if (r == null) {
- throw new IllegalArgumentException(
- "Reference to the given SQLContainer not defined.");
- }
- try {
- getContainerProperty(itemId, r.getReferencingColumn()).setValue(
- refdCont.getContainerProperty(refdItemId,
- r.getReferencedColumn()));
- return true;
- } catch (Exception e) {
- getLogger()
- .log(Level.WARNING, "Setting referenced item failed.", e);
- return false;
- }
- }
-
- /**
- * Fetches the Item Id of the referenced item from the target SQLContainer.
- *
- * @param itemId
- * Item Id of the reference source (from this container)
- * @param refdCont
- * Target SQLContainer of the reference
- * @return Item Id of the referenced item, or null if not found
- */
- public Object getReferencedItemId(Object itemId, SQLContainer refdCont) {
- if (refdCont == null) {
- throw new IllegalArgumentException(
- "Referenced SQLContainer can not be null.");
- }
- Reference r = references.get(refdCont);
- if (r == null) {
- throw new IllegalArgumentException(
- "Reference to the given SQLContainer not defined.");
- }
- Object refKey = getContainerProperty(itemId, r.getReferencingColumn())
- .getValue();
-
- refdCont.removeAllContainerFilters();
- refdCont.addContainerFilter(new Equal(r.getReferencedColumn(), refKey));
- Object toReturn = refdCont.firstItemId();
- refdCont.removeAllContainerFilters();
- return toReturn;
- }
-
- /**
- * Fetches the referenced item from the target SQLContainer.
- *
- * @param itemId
- * Item Id of the reference source (from this container)
- * @param refdCont
- * Target SQLContainer of the reference
- * @return The referenced item, or null if not found
- */
- public Item getReferencedItem(Object itemId, SQLContainer refdCont) {
- return refdCont.getItem(getReferencedItemId(itemId, refdCont));
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- }
-
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- if (notificationsEnabled) {
- /*
- * Register instance with CacheFlushNotifier after de-serialization
- * if notifications are enabled
- */
- CacheFlushNotifier.addInstance(this);
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(SQLContainer.class.getName());
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java b/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java
deleted file mode 100644
index 4a48dbf499..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/SQLUtil.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-import java.io.Serializable;
-
-public class SQLUtil implements Serializable {
- /**
- * Escapes different special characters in strings that are passed to SQL.
- * Replaces the following:
- *
- * <list> <li>' is replaced with ''</li> <li>\x00 is removed</li> <li>\ is
- * replaced with \\</li> <li>" is replaced with \"</li> <li>
- * \x1a is removed</li> </list>
- *
- * Also note! The escaping done here may or may not be enough to prevent any
- * and all SQL injections so it is recommended to check user input before
- * giving it to the SQLContainer/TableQuery.
- *
- * @param constant
- * @return \\\'\'
- */
- public static String escapeSQL(String constant) {
- if (constant == null) {
- return null;
- }
- String fixedConstant = constant;
- fixedConstant = fixedConstant.replaceAll("\\\\x00", "");
- fixedConstant = fixedConstant.replaceAll("\\\\x1a", "");
- fixedConstant = fixedConstant.replaceAll("'", "''");
- fixedConstant = fixedConstant.replaceAll("\\\\", "\\\\\\\\");
- fixedConstant = fixedConstant.replaceAll("\\\"", "\\\\\"");
- return fixedConstant;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java b/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java
deleted file mode 100644
index b4bca75a2a..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer;
-
-public class TemporaryRowId extends RowId {
- private static final long serialVersionUID = -641983830469018329L;
-
- public TemporaryRowId(Object[] id) {
- super(id);
- }
-
- @Override
- public int hashCode() {
- return id.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof TemporaryRowId)) {
- return false;
- }
- Object[] compId = ((TemporaryRowId) obj).getId();
- return id.equals(compId);
- }
-
- @Override
- public String toString() {
- return "Temporary row id";
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java
deleted file mode 100644
index 9aa4f7c4be..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-
-public class J2EEConnectionPool implements JDBCConnectionPool {
-
- private String dataSourceJndiName;
-
- private DataSource dataSource = null;
-
- public J2EEConnectionPool(DataSource dataSource) {
- this.dataSource = dataSource;
- }
-
- public J2EEConnectionPool(String dataSourceJndiName) {
- this.dataSourceJndiName = dataSourceJndiName;
- }
-
- @Override
- public Connection reserveConnection() throws SQLException {
- Connection conn = getDataSource().getConnection();
- conn.setAutoCommit(false);
-
- return conn;
- }
-
- private DataSource getDataSource() throws SQLException {
- if (dataSource == null) {
- dataSource = lookupDataSource();
- }
- return dataSource;
- }
-
- private DataSource lookupDataSource() throws SQLException {
- try {
- InitialContext ic = new InitialContext();
- return (DataSource) ic.lookup(dataSourceJndiName);
- } catch (NamingException e) {
- throw new SQLException(
- "NamingException - Cannot connect to the database. Cause: "
- + e.getMessage());
- }
- }
-
- @Override
- public void releaseConnection(Connection conn) {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- Logger.getLogger(J2EEConnectionPool.class.getName()).log(
- Level.FINE, "Could not release SQL connection", e);
- }
- }
- }
-
- @Override
- public void destroy() {
- dataSource = null;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java
deleted file mode 100644
index cf12461588..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Interface for implementing connection pools to be used with SQLContainer.
- */
-public interface JDBCConnectionPool extends Serializable {
- /**
- * Retrieves a connection.
- *
- * @return a usable connection to the database
- * @throws SQLException
- */
- public Connection reserveConnection() throws SQLException;
-
- /**
- * Releases a connection that was retrieved earlier.
- *
- * Note that depending on implementation, the transaction possibly open in
- * the connection may or may not be rolled back.
- *
- * @param conn
- * Connection to be released
- */
- public void releaseConnection(Connection conn);
-
- /**
- * Destroys the connection pool: close() is called an all the connections in
- * the pool, whether available or reserved.
- *
- * This method was added to fix PostgreSQL -related issues with connections
- * that were left hanging 'idle'.
- */
- public void destroy();
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java b/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
deleted file mode 100644
index 21760014b9..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.connection;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Simple implementation of the JDBCConnectionPool interface. Handles loading
- * the JDBC driver, setting up the connections and ensuring they are still
- * usable upon release.
- */
-@SuppressWarnings("serial")
-public class SimpleJDBCConnectionPool implements JDBCConnectionPool {
-
- private int initialConnections = 5;
- private int maxConnections = 20;
-
- private String driverName;
- private String connectionUri;
- private String userName;
- private String password;
-
- private transient Set<Connection> availableConnections;
- private transient Set<Connection> reservedConnections;
-
- private boolean initialized;
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password) throws SQLException {
- if (driverName == null) {
- throw new IllegalArgumentException(
- "JDBC driver class name must be given.");
- }
- if (connectionUri == null) {
- throw new IllegalArgumentException(
- "Database connection URI must be given.");
- }
- if (userName == null) {
- throw new IllegalArgumentException(
- "Database username must be given.");
- }
- if (password == null) {
- throw new IllegalArgumentException(
- "Database password must be given.");
- }
- this.driverName = driverName;
- this.connectionUri = connectionUri;
- this.userName = userName;
- this.password = password;
-
- /* Initialize JDBC driver */
- try {
- Class.forName(driverName).newInstance();
- } catch (Exception ex) {
- throw new RuntimeException("Specified JDBC Driver: " + driverName
- + " - initialization failed.", ex);
- }
- }
-
- public SimpleJDBCConnectionPool(String driverName, String connectionUri,
- String userName, String password, int initialConnections,
- int maxConnections) throws SQLException {
- this(driverName, connectionUri, userName, password);
- this.initialConnections = initialConnections;
- this.maxConnections = maxConnections;
- }
-
- private void initializeConnections() throws SQLException {
- availableConnections = new HashSet<Connection>(initialConnections);
- reservedConnections = new HashSet<Connection>(initialConnections);
- for (int i = 0; i < initialConnections; i++) {
- availableConnections.add(createConnection());
- }
- initialized = true;
- }
-
- @Override
- public synchronized Connection reserveConnection() throws SQLException {
- if (!initialized) {
- initializeConnections();
- }
- if (availableConnections.isEmpty()) {
- if (reservedConnections.size() < maxConnections) {
- availableConnections.add(createConnection());
- } else {
- throw new SQLException("Connection limit has been reached.");
- }
- }
-
- Connection c = availableConnections.iterator().next();
- availableConnections.remove(c);
- reservedConnections.add(c);
-
- return c;
- }
-
- @Override
- public synchronized void releaseConnection(Connection conn) {
- if (conn == null || !initialized) {
- return;
- }
- /* Try to roll back if necessary */
- try {
- if (!conn.getAutoCommit()) {
- conn.rollback();
- }
- } catch (SQLException e) {
- /* Roll back failed, close and discard connection */
- try {
- conn.close();
- } catch (SQLException e1) {
- /* Nothing needs to be done */
- }
- reservedConnections.remove(conn);
- return;
- }
- reservedConnections.remove(conn);
- availableConnections.add(conn);
- }
-
- private Connection createConnection() throws SQLException {
- Connection c = DriverManager.getConnection(connectionUri, userName,
- password);
- c.setAutoCommit(false);
- if (driverName.toLowerCase().contains("mysql")) {
- try {
- Statement s = c.createStatement();
- s.execute("SET SESSION sql_mode = 'ANSI'");
- s.close();
- } catch (Exception e) {
- // Failed to set ansi mode; continue
- }
- }
- return c;
- }
-
- @Override
- public void destroy() {
- for (Connection c : availableConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
- for (Connection c : reservedConnections) {
- try {
- c.close();
- } catch (SQLException e) {
- // No need to do anything
- }
- }
-
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- initialized = false;
- out.defaultWriteObject();
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
deleted file mode 100644
index ec986fab95..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-import com.vaadin.data.util.sqlcontainer.SQLContainer;
-import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
-
-@SuppressWarnings("serial")
-public class FreeformQuery implements QueryDelegate {
-
- FreeformQueryDelegate delegate = null;
- private String queryString;
- private List<String> primaryKeyColumns;
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection = null;
-
- /**
- * Prevent no-parameters instantiation of FreeformQuery
- */
- @SuppressWarnings("unused")
- private FreeformQuery() {
- }
-
- /**
- * Creates a new freeform query delegate to be used with the
- * {@link SQLContainer}.
- *
- * @param queryString
- * The actual query to perform.
- * @param primaryKeyColumns
- * The primary key columns. Read-only mode is forced if this
- * parameter is null or empty.
- * @param connectionPool
- * the JDBCConnectionPool to use to open connections to the SQL
- * database.
- * @deprecated @see
- * {@link FreeformQuery#FreeformQuery(String, JDBCConnectionPool, String...)}
- */
- @Deprecated
- public FreeformQuery(String queryString, List<String> primaryKeyColumns,
- JDBCConnectionPool connectionPool) {
- if (primaryKeyColumns == null) {
- primaryKeyColumns = new ArrayList<String>();
- }
- if (primaryKeyColumns.contains("")) {
- throw new IllegalArgumentException(
- "The primary key columns contain an empty string!");
- } else if (queryString == null || "".equals(queryString)) {
- throw new IllegalArgumentException(
- "The query string may not be empty or null!");
- } else if (connectionPool == null) {
- throw new IllegalArgumentException(
- "The connectionPool may not be null!");
- }
- this.queryString = queryString;
- this.primaryKeyColumns = Collections
- .unmodifiableList(primaryKeyColumns);
- this.connectionPool = connectionPool;
- }
-
- /**
- * Creates a new freeform query delegate to be used with the
- * {@link SQLContainer}.
- *
- * @param queryString
- * The actual query to perform.
- * @param connectionPool
- * the JDBCConnectionPool to use to open connections to the SQL
- * database.
- * @param primaryKeyColumns
- * The primary key columns. Read-only mode is forced if none are
- * provided. (optional)
- */
- public FreeformQuery(String queryString, JDBCConnectionPool connectionPool,
- String... primaryKeyColumns) {
- this(queryString, Arrays.asList(primaryKeyColumns), connectionPool);
- }
-
- /**
- * This implementation of getCount() actually fetches all records from the
- * database, which might be a performance issue. Override this method with a
- * SELECT COUNT(*) ... query if this is too slow for your needs.
- *
- * {@inheritDoc}
- */
- @Override
- public int getCount() throws SQLException {
- // First try the delegate
- int count = countByDelegate();
- if (count < 0) {
- // Couldn't use the delegate, use the bad way.
- Connection conn = getConnection();
- Statement statement = conn.createStatement(
- ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
-
- ResultSet rs = statement.executeQuery(queryString);
- if (rs.last()) {
- count = rs.getRow();
- } else {
- count = 0;
- }
- rs.close();
- statement.close();
- releaseConnection(conn);
- }
- return count;
- }
-
- @SuppressWarnings("deprecation")
- private int countByDelegate() throws SQLException {
- int count = -1;
- if (delegate == null) {
- return count;
- }
- /* First try using prepared statement */
- if (delegate instanceof FreeformStatementDelegate) {
- try {
- StatementHelper sh = ((FreeformStatementDelegate) delegate)
- .getCountStatement();
- Connection c = getConnection();
- PreparedStatement pstmt = c.prepareStatement(sh
- .getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- ResultSet rs = pstmt.executeQuery();
- rs.next();
- count = rs.getInt(1);
- rs.close();
- pstmt.clearParameters();
- pstmt.close();
- releaseConnection(c);
- return count;
- } catch (UnsupportedOperationException e) {
- // Count statement generation not supported
- }
- }
- /* Try using regular statement */
- try {
- String countQuery = delegate.getCountQuery();
- if (countQuery != null) {
- Connection conn = getConnection();
- Statement statement = conn.createStatement();
- ResultSet rs = statement.executeQuery(countQuery);
- rs.next();
- count = rs.getInt(1);
- rs.close();
- statement.close();
- releaseConnection(conn);
- return count;
- }
- } catch (UnsupportedOperationException e) {
- // Count query generation not supported
- }
- return count;
- }
-
- private Connection getConnection() throws SQLException {
- if (activeConnection != null) {
- return activeConnection;
- }
- return connectionPool.reserveConnection();
- }
-
- /**
- * Fetches the results for the query. This implementation always fetches the
- * entire record set, ignoring the offset and page length parameters. In
- * order to support lazy loading of records, you must supply a
- * FreeformQueryDelegate that implements the
- * FreeformQueryDelegate.getQueryString(int,int) method.
- *
- * @throws SQLException
- *
- * @see FreeformQueryDelegate#getQueryString(int, int)
- */
- @Override
- @SuppressWarnings("deprecation")
- public ResultSet getResults(int offset, int pagelength) throws SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction!");
- }
- String query = queryString;
- if (delegate != null) {
- /* First try using prepared statement */
- if (delegate instanceof FreeformStatementDelegate) {
- try {
- StatementHelper sh = ((FreeformStatementDelegate) delegate)
- .getQueryStatement(offset, pagelength);
- PreparedStatement pstmt = activeConnection
- .prepareStatement(sh.getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- return pstmt.executeQuery();
- } catch (UnsupportedOperationException e) {
- // Statement generation not supported, continue...
- }
- }
- try {
- query = delegate.getQueryString(offset, pagelength);
- } catch (UnsupportedOperationException e) {
- // This is fine, we'll just use the default queryString.
- }
- }
- Statement statement = activeConnection.createStatement();
- ResultSet rs = statement.executeQuery(query);
- return rs;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean implementationRespectsPagingLimits() {
- if (delegate == null) {
- return false;
- }
- /* First try using prepared statement */
- if (delegate instanceof FreeformStatementDelegate) {
- try {
- StatementHelper sh = ((FreeformStatementDelegate) delegate)
- .getCountStatement();
- if (sh != null && sh.getQueryString() != null
- && sh.getQueryString().length() > 0) {
- return true;
- }
- } catch (UnsupportedOperationException e) {
- // Statement generation not supported, continue...
- }
- }
- try {
- String queryString = delegate.getQueryString(0, 50);
- return queryString != null && queryString.length() > 0;
- } catch (UnsupportedOperationException e) {
- return false;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setFilters(java
- * .util.List)
- */
- @Override
- public void setFilters(List<Filter> filters)
- throws UnsupportedOperationException {
- if (delegate != null) {
- delegate.setFilters(filters);
- } else if (filters != null) {
- throw new UnsupportedOperationException(
- "FreeFormQueryDelegate not set!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setOrderBy(java
- * .util.List)
- */
- @Override
- public void setOrderBy(List<OrderBy> orderBys)
- throws UnsupportedOperationException {
- if (delegate != null) {
- delegate.setOrderBy(orderBys);
- } else if (orderBys != null) {
- throw new UnsupportedOperationException(
- "FreeFormQueryDelegate not set!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin
- * .data.util.sqlcontainer.RowItem)
- */
- @Override
- public int storeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
- throw new IllegalStateException("No transaction is active!");
- } else if (primaryKeyColumns.isEmpty()) {
- throw new UnsupportedOperationException(
- "Cannot store items fetched with a read-only freeform query!");
- }
- if (delegate != null) {
- return delegate.storeRow(activeConnection, row);
- } else {
- throw new UnsupportedOperationException(
- "FreeFormQueryDelegate not set!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#removeRow(com.vaadin
- * .data.util.sqlcontainer.RowItem)
- */
- @Override
- public boolean removeRow(RowItem row) throws SQLException {
- if (activeConnection == null) {
- throw new IllegalStateException("No transaction is active!");
- } else if (primaryKeyColumns.isEmpty()) {
- throw new UnsupportedOperationException(
- "Cannot remove items fetched with a read-only freeform query!");
- }
- if (delegate != null) {
- return delegate.removeRow(activeConnection, row);
- } else {
- throw new UnsupportedOperationException(
- "FreeFormQueryDelegate not set!");
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#beginTransaction()
- */
- @Override
- public synchronized void beginTransaction()
- throws UnsupportedOperationException, SQLException {
- if (activeConnection != null) {
- throw new IllegalStateException("A transaction is already active!");
- }
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#commit()
- */
- @Override
- public synchronized void commit() throws UnsupportedOperationException,
- SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- if (!activeConnection.getAutoCommit()) {
- activeConnection.commit();
- }
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#rollback()
- */
- @Override
- public synchronized void rollback() throws UnsupportedOperationException,
- SQLException {
- if (activeConnection == null) {
- throw new SQLException("No active transaction");
- }
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- activeConnection = null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.util.sqlcontainer.query.QueryDelegate#getPrimaryKeyColumns
- * ()
- */
- @Override
- public List<String> getPrimaryKeyColumns() {
- return primaryKeyColumns;
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public FreeformQueryDelegate getDelegate() {
- return delegate;
- }
-
- public void setDelegate(FreeformQueryDelegate delegate) {
- this.delegate = delegate;
- }
-
- /**
- * This implementation of the containsRowWithKey method rewrites existing
- * WHERE clauses in the query string. The logic is, however, not very
- * complex and some times can do the Wrong Thing<sup>TM</sup>. For the
- * situations where this logic is not enough, you can implement the
- * getContainsRowQueryString method in FreeformQueryDelegate and this will
- * be used instead of the logic.
- *
- * @see FreeformQueryDelegate#getContainsRowQueryString(Object...)
- *
- */
- @Override
- @SuppressWarnings("deprecation")
- public boolean containsRowWithKey(Object... keys) throws SQLException {
- String query = null;
- boolean contains = false;
- if (delegate != null) {
- if (delegate instanceof FreeformStatementDelegate) {
- try {
- StatementHelper sh = ((FreeformStatementDelegate) delegate)
- .getContainsRowQueryStatement(keys);
- Connection c = getConnection();
- PreparedStatement pstmt = c.prepareStatement(sh
- .getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- ResultSet rs = pstmt.executeQuery();
- contains = rs.next();
- rs.close();
- pstmt.clearParameters();
- pstmt.close();
- releaseConnection(c);
- return contains;
- } catch (UnsupportedOperationException e) {
- // Statement generation not supported, continue...
- }
- }
- try {
- query = delegate.getContainsRowQueryString(keys);
- } catch (UnsupportedOperationException e) {
- query = modifyWhereClause(keys);
- }
- } else {
- query = modifyWhereClause(keys);
- }
- Connection conn = getConnection();
- try {
- Statement statement = conn.createStatement();
- ResultSet rs = statement.executeQuery(query);
- contains = rs.next();
- rs.close();
- statement.close();
- } finally {
- releaseConnection(conn);
- }
- return contains;
- }
-
- /**
- * Releases the connection if it is not part of an active transaction.
- *
- * @param conn
- * the connection to release
- */
- private void releaseConnection(Connection conn) {
- if (conn != activeConnection) {
- connectionPool.releaseConnection(conn);
- }
- }
-
- private String modifyWhereClause(Object... keys) {
- // Build the where rules for the provided keys
- StringBuffer where = new StringBuffer();
- for (int ix = 0; ix < primaryKeyColumns.size(); ix++) {
- where.append(QueryBuilder.quote(primaryKeyColumns.get(ix)));
- if (keys[ix] == null) {
- where.append(" IS NULL");
- } else {
- where.append(" = '").append(keys[ix]).append("'");
- }
- if (ix < primaryKeyColumns.size() - 1) {
- where.append(" AND ");
- }
- }
- // Is there already a WHERE clause in the query string?
- int index = queryString.toLowerCase().indexOf("where ");
- if (index > -1) {
- // Rewrite the where clause
- return queryString.substring(0, index) + "WHERE " + where + " AND "
- + queryString.substring(index + 6);
- }
- // Append a where clause
- return queryString + " WHERE " + where;
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- try {
- rollback();
- } catch (SQLException ignored) {
- }
- out.defaultWriteObject();
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java
deleted file mode 100644
index 433d742be8..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-
-public interface FreeformQueryDelegate extends Serializable {
- /**
- * Should return the SQL query string to be performed. This method is
- * responsible for gluing together the select query from the filters and the
- * order by conditions if these are supported.
- *
- * @param offset
- * the first record (row) to fetch.
- * @param pagelength
- * the number of records (rows) to fetch. 0 means all records
- * starting from offset.
- * @deprecated Implement {@link FreeformStatementDelegate} instead of
- * {@link FreeformQueryDelegate}
- */
- @Deprecated
- public String getQueryString(int offset, int limit)
- throws UnsupportedOperationException;
-
- /**
- * Generates and executes a query to determine the current row count from
- * the DB. Row count will be fetched using filters that are currently set to
- * the QueryDelegate.
- *
- * @return row count
- * @throws SQLException
- * @deprecated Implement {@link FreeformStatementDelegate} instead of
- * {@link FreeformQueryDelegate}
- */
- @Deprecated
- public String getCountQuery() throws UnsupportedOperationException;
-
- /**
- * Sets the filters to apply when performing the SQL query. These are
- * translated into a WHERE clause. Default filtering mode will be used.
- *
- * @param filters
- * The filters to apply.
- * @throws UnsupportedOperationException
- * if the implementation doesn't support filtering.
- */
- public void setFilters(List<Filter> filters)
- throws UnsupportedOperationException;
-
- /**
- * Sets the order in which to retrieve rows from the database. The result
- * can be ordered by zero or more columns and each column can be in
- * ascending or descending order. These are translated into an ORDER BY
- * clause in the SQL query.
- *
- * @param orderBys
- * A list of the OrderBy conditions.
- * @throws UnsupportedOperationException
- * if the implementation doesn't support ordering.
- */
- public void setOrderBy(List<OrderBy> orderBys)
- throws UnsupportedOperationException;
-
- /**
- * Stores a row in the database. The implementation of this interface
- * decides how to identify whether to store a new row or update an existing
- * one.
- *
- * @param conn
- * the JDBC connection to use
- * @param row
- * RowItem to be stored or updated.
- * @throws UnsupportedOperationException
- * if the implementation is read only.
- * @throws SQLException
- */
- public int storeRow(Connection conn, RowItem row)
- throws UnsupportedOperationException, SQLException;
-
- /**
- * Removes the given RowItem from the database.
- *
- * @param conn
- * the JDBC connection to use
- * @param row
- * RowItem to be removed
- * @return true on success
- * @throws UnsupportedOperationException
- * @throws SQLException
- */
- public boolean removeRow(Connection conn, RowItem row)
- throws UnsupportedOperationException, SQLException;
-
- /**
- * Generates an SQL Query string that allows the user of the FreeformQuery
- * class to customize the query string used by the
- * FreeformQuery.containsRowWithKeys() method. This is useful for cases when
- * the logic in the containsRowWithKeys method is not enough to support more
- * complex free form queries.
- *
- * @param keys
- * the values of the primary keys
- * @throws UnsupportedOperationException
- * to use the default logic in FreeformQuery
- * @deprecated Implement {@link FreeformStatementDelegate} instead of
- * {@link FreeformQueryDelegate}
- */
- @Deprecated
- public String getContainsRowQueryString(Object... keys)
- throws UnsupportedOperationException;
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
deleted file mode 100644
index 95521c5019..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-/**
- * FreeformStatementDelegate is an extension to FreeformQueryDelegate that
- * provides definitions for methods that produce StatementHelper objects instead
- * of basic query strings. This allows the FreeformQuery query delegate to use
- * PreparedStatements instead of regular Statement when accessing the database.
- *
- * Due to the injection protection and other benefits of prepared statements, it
- * is advisable to implement this interface instead of the FreeformQueryDelegate
- * whenever possible.
- */
-public interface FreeformStatementDelegate extends FreeformQueryDelegate {
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement. This
- * method is responsible for gluing together the select query from the
- * filters and the order by conditions if these are supported.
- *
- * @param offset
- * the first record (row) to fetch.
- * @param pagelength
- * the number of records (rows) to fetch. 0 means all records
- * starting from offset.
- */
- public StatementHelper getQueryStatement(int offset, int limit)
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement that
- * will fetch the row count from the DB. Row count should be fetched using
- * filters that are currently set to the QueryDelegate.
- */
- public StatementHelper getCountStatement()
- throws UnsupportedOperationException;
-
- /**
- * Should return a new instance of StatementHelper that contains the query
- * string and parameter values required to create a PreparedStatement used
- * by the FreeformQuery.containsRowWithKeys() method. This is useful for
- * cases when the default logic in said method is not enough to support more
- * complex free form queries.
- *
- * @param keys
- * the values of the primary keys
- * @throws UnsupportedOperationException
- * to use the default logic in FreeformQuery
- */
- public StatementHelper getContainsRowQueryStatement(Object... keys)
- throws UnsupportedOperationException;
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java b/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java
deleted file mode 100644
index 8ebe10067e..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import java.io.Serializable;
-
-/**
- * OrderBy represents a sorting rule to be applied to a query made by the
- * SQLContainer's QueryDelegate.
- *
- * The sorting rule is simple and contains only the affected column's name and
- * the direction of the sort.
- */
-public class OrderBy implements Serializable {
- private String column;
- private boolean isAscending;
-
- /**
- * Prevent instantiation without required parameters.
- */
- @SuppressWarnings("unused")
- private OrderBy() {
- }
-
- public OrderBy(String column, boolean isAscending) {
- setColumn(column);
- setAscending(isAscending);
- }
-
- public void setColumn(String column) {
- this.column = column;
- }
-
- public String getColumn() {
- return column;
- }
-
- public void setAscending(boolean isAscending) {
- this.isAscending = isAscending;
- }
-
- public boolean isAscending() {
- return isAscending;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java b/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java
deleted file mode 100644
index 6e4396fad1..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.RowId;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-
-public interface QueryDelegate extends Serializable {
- /**
- * Generates and executes a query to determine the current row count from
- * the DB. Row count will be fetched using filters that are currently set to
- * the QueryDelegate.
- *
- * @return row count
- * @throws SQLException
- */
- public int getCount() throws SQLException;
-
- /**
- * Executes a paged SQL query and returns the ResultSet. The query is
- * defined through implementations of this QueryDelegate interface.
- *
- * @param offset
- * the first item of the page to load
- * @param pagelength
- * the length of the page to load
- * @return a ResultSet containing the rows of the page
- * @throws SQLException
- * if the database access fails.
- */
- public ResultSet getResults(int offset, int pagelength) throws SQLException;
-
- /**
- * Allows the SQLContainer implementation to check whether the QueryDelegate
- * implementation implements paging in the getResults method.
- *
- * @see QueryDelegate#getResults(int, int)
- *
- * @return true if the delegate implements paging
- */
- public boolean implementationRespectsPagingLimits();
-
- /**
- * Sets the filters to apply when performing the SQL query. These are
- * translated into a WHERE clause. Default filtering mode will be used.
- *
- * @param filters
- * The filters to apply.
- * @throws UnsupportedOperationException
- * if the implementation doesn't support filtering.
- */
- public void setFilters(List<Filter> filters)
- throws UnsupportedOperationException;
-
- /**
- * Sets the order in which to retrieve rows from the database. The result
- * can be ordered by zero or more columns and each column can be in
- * ascending or descending order. These are translated into an ORDER BY
- * clause in the SQL query.
- *
- * @param orderBys
- * A list of the OrderBy conditions.
- * @throws UnsupportedOperationException
- * if the implementation doesn't support ordering.
- */
- public void setOrderBy(List<OrderBy> orderBys)
- throws UnsupportedOperationException;
-
- /**
- * Stores a row in the database. The implementation of this interface
- * decides how to identify whether to store a new row or update an existing
- * one.
- *
- * @param columnToValueMap
- * A map containing the values for all columns to be stored or
- * updated.
- * @return the number of affected rows in the database table
- * @throws UnsupportedOperationException
- * if the implementation is read only.
- */
- public int storeRow(RowItem row) throws UnsupportedOperationException,
- SQLException;
-
- /**
- * Removes the given RowItem from the database.
- *
- * @param row
- * RowItem to be removed
- * @return true on success
- * @throws UnsupportedOperationException
- * @throws SQLException
- */
- public boolean removeRow(RowItem row) throws UnsupportedOperationException,
- SQLException;
-
- /**
- * Starts a new database transaction. Used when storing multiple changes.
- *
- * Note that if a transaction is already open, it will be rolled back when a
- * new transaction is started.
- *
- * @throws SQLException
- * if the database access fails.
- */
- public void beginTransaction() throws SQLException;
-
- /**
- * Commits a transaction. If a transaction is not open nothing should
- * happen.
- *
- * @throws SQLException
- * if the database access fails.
- */
- public void commit() throws SQLException;
-
- /**
- * Rolls a transaction back. If a transaction is not open nothing should
- * happen.
- *
- * @throws SQLException
- * if the database access fails.
- */
- public void rollback() throws SQLException;
-
- /**
- * Returns a list of primary key column names. The list is either fetched
- * from the database (TableQuery) or given as an argument depending on
- * implementation.
- *
- * @return
- */
- public List<String> getPrimaryKeyColumns();
-
- /**
- * Performs a query to find out whether the SQL table contains a row with
- * the given set of primary keys.
- *
- * @param keys
- * the primary keys
- * @return true if the SQL table contains a row with the provided keys
- * @throws SQLException
- */
- public boolean containsRowWithKey(Object... keys) throws SQLException;
-
- /************************/
- /** ROWID CHANGE EVENT **/
- /************************/
-
- /**
- * An <code>Event</code> object specifying the old and new RowId of an added
- * item after the addition has been successfully committed.
- */
- public interface RowIdChangeEvent extends Serializable {
- /**
- * Gets the old (temporary) RowId of the added row that raised this
- * event.
- *
- * @return old RowId
- */
- public RowId getOldRowId();
-
- /**
- * Gets the new, possibly database assigned RowId of the added row that
- * raised this event.
- *
- * @return new RowId
- */
- public RowId getNewRowId();
- }
-
- /** RowId change listener interface. */
- public interface RowIdChangeListener extends Serializable {
- /**
- * Lets the listener know that a RowId has been changed.
- *
- * @param event
- */
- public void rowIdChange(QueryDelegate.RowIdChangeEvent event);
- }
-
- /**
- * The interface for adding and removing <code>RowIdChangeEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate a <code>RowIdChangeEvent</code> when it performs a
- * database commit that may change the RowId.
- */
- public interface RowIdChangeNotifier extends Serializable {
- /**
- * Adds a RowIdChangeListener for the object.
- *
- * @param listener
- * listener to be added
- */
- public void addListener(QueryDelegate.RowIdChangeListener listener);
-
- /**
- * Removes the specified RowIdChangeListener from the object.
- *
- * @param listener
- * listener to be removed
- */
- public void removeListener(QueryDelegate.RowIdChangeListener listener);
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java b/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
deleted file mode 100644
index d0606704f7..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java
+++ /dev/null
@@ -1,715 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query;
-
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EventObject;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Compare.Equal;
-import com.vaadin.data.util.sqlcontainer.ColumnProperty;
-import com.vaadin.data.util.sqlcontainer.OptimisticLockException;
-import com.vaadin.data.util.sqlcontainer.RowId;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-import com.vaadin.data.util.sqlcontainer.SQLUtil;
-import com.vaadin.data.util.sqlcontainer.TemporaryRowId;
-import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
-import com.vaadin.data.util.sqlcontainer.query.generator.DefaultSQLGenerator;
-import com.vaadin.data.util.sqlcontainer.query.generator.MSSQLGenerator;
-import com.vaadin.data.util.sqlcontainer.query.generator.SQLGenerator;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-@SuppressWarnings("serial")
-public class TableQuery implements QueryDelegate,
- QueryDelegate.RowIdChangeNotifier {
-
- /** Table name, primary key column name(s) and version column name */
- private String tableName;
- private List<String> primaryKeyColumns;
- private String versionColumn;
-
- /** Currently set Filters and OrderBys */
- private List<Filter> filters;
- private List<OrderBy> orderBys;
-
- /** SQLGenerator instance to use for generating queries */
- private SQLGenerator sqlGenerator;
-
- /** Fields related to Connection and Transaction handling */
- private JDBCConnectionPool connectionPool;
- private transient Connection activeConnection;
- private boolean transactionOpen;
-
- /** Row ID change listeners */
- private LinkedList<RowIdChangeListener> rowIdChangeListeners;
- /** Row ID change events, stored until commit() is called */
- private final List<RowIdChangeEvent> bufferedEvents = new ArrayList<RowIdChangeEvent>();
-
- /** Set to true to output generated SQL Queries to System.out */
- private boolean debug = false;
-
- /** Prevent no-parameters instantiation of TableQuery */
- @SuppressWarnings("unused")
- private TableQuery() {
- }
-
- /**
- * Creates a new TableQuery using the given connection pool, SQL generator
- * and table name to fetch the data from. All parameters must be non-null.
- *
- * @param tableName
- * Name of the database table to connect to
- * @param connectionPool
- * Connection pool for accessing the database
- * @param sqlGenerator
- * SQL query generator implementation
- */
- public TableQuery(String tableName, JDBCConnectionPool connectionPool,
- SQLGenerator sqlGenerator) {
- if (tableName == null || tableName.trim().length() < 1
- || connectionPool == null || sqlGenerator == null) {
- throw new IllegalArgumentException(
- "All parameters must be non-null and a table name must be given.");
- }
- this.tableName = tableName;
- this.sqlGenerator = sqlGenerator;
- this.connectionPool = connectionPool;
- fetchMetaData();
- }
-
- /**
- * Creates a new TableQuery using the given connection pool and table name
- * to fetch the data from. All parameters must be non-null. The default SQL
- * generator will be used for queries.
- *
- * @param tableName
- * Name of the database table to connect to
- * @param connectionPool
- * Connection pool for accessing the database
- */
- public TableQuery(String tableName, JDBCConnectionPool connectionPool) {
- this(tableName, connectionPool, new DefaultSQLGenerator());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getCount()
- */
- @Override
- public int getCount() throws SQLException {
- getLogger().log(Level.FINE, "Fetching count...");
- StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
- filters, null, 0, 0, "COUNT(*)");
- boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
- shouldCloseTransaction = true;
- beginTransaction();
- }
- ResultSet r = executeQuery(sh);
- r.next();
- int count = r.getInt(1);
- r.getStatement().close();
- r.close();
- if (shouldCloseTransaction) {
- commit();
- }
- return count;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#getResults(int,
- * int)
- */
- @Override
- public ResultSet getResults(int offset, int pagelength) throws SQLException {
- StatementHelper sh;
- /*
- * If no ordering is explicitly set, results will be ordered by the
- * first primary key column.
- */
- if (orderBys == null || orderBys.isEmpty()) {
- List<OrderBy> ob = new ArrayList<OrderBy>();
- ob.add(new OrderBy(primaryKeyColumns.get(0), true));
- sh = sqlGenerator.generateSelectQuery(tableName, filters, ob,
- offset, pagelength, null);
- } else {
- sh = sqlGenerator.generateSelectQuery(tableName, filters, orderBys,
- offset, pagelength, null);
- }
- return executeQuery(sh);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#
- * implementationRespectsPagingLimits()
- */
- @Override
- public boolean implementationRespectsPagingLimits() {
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin
- * .addon.sqlcontainer.RowItem)
- */
- @Override
- public int storeRow(RowItem row) throws UnsupportedOperationException,
- SQLException {
- if (row == null) {
- throw new IllegalArgumentException("Row argument must be non-null.");
- }
- StatementHelper sh;
- int result = 0;
- if (row.getId() instanceof TemporaryRowId) {
- setVersionColumnFlagInProperty(row);
- sh = sqlGenerator.generateInsertQuery(tableName, row);
- result = executeUpdateReturnKeys(sh, row);
- } else {
- setVersionColumnFlagInProperty(row);
- sh = sqlGenerator.generateUpdateQuery(tableName, row);
- result = executeUpdate(sh);
- }
- if (versionColumn != null && result == 0) {
- throw new OptimisticLockException(
- "Someone else changed the row that was being updated.",
- row.getId());
- }
- return result;
- }
-
- private void setVersionColumnFlagInProperty(RowItem row) {
- ColumnProperty versionProperty = (ColumnProperty) row
- .getItemProperty(versionColumn);
- if (versionProperty != null) {
- versionProperty.setVersionColumn(true);
- }
- }
-
- /**
- * Inserts the given row in the database table immediately. Begins and
- * commits the transaction needed. This method was added specifically to
- * solve the problem of returning the final RowId immediately on the
- * SQLContainer.addItem() call when auto commit mode is enabled in the
- * SQLContainer.
- *
- * @param row
- * RowItem to add to the database
- * @return Final RowId of the added row
- * @throws SQLException
- */
- public RowId storeRowImmediately(RowItem row) throws SQLException {
- beginTransaction();
- /* Set version column, if one is provided */
- setVersionColumnFlagInProperty(row);
- /* Generate query */
- StatementHelper sh = sqlGenerator.generateInsertQuery(tableName, row);
- PreparedStatement pstmt = activeConnection.prepareStatement(
- sh.getQueryString(), primaryKeyColumns.toArray(new String[0]));
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
- int result = pstmt.executeUpdate();
- if (result > 0) {
- /*
- * If affected rows exist, we'll get the new RowId, commit the
- * transaction and return the new RowId.
- */
- ResultSet generatedKeys = pstmt.getGeneratedKeys();
- RowId newId = getNewRowId(row, generatedKeys);
- generatedKeys.close();
- pstmt.clearParameters();
- pstmt.close();
- commit();
- return newId;
- } else {
- pstmt.clearParameters();
- pstmt.close();
- /* On failure return null */
- return null;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setFilters(java.util
- * .List)
- */
- @Override
- public void setFilters(List<Filter> filters)
- throws UnsupportedOperationException {
- if (filters == null) {
- this.filters = null;
- return;
- }
- this.filters = Collections.unmodifiableList(filters);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#setOrderBy(java.util
- * .List)
- */
- @Override
- public void setOrderBy(List<OrderBy> orderBys)
- throws UnsupportedOperationException {
- if (orderBys == null) {
- this.orderBys = null;
- return;
- }
- this.orderBys = Collections.unmodifiableList(orderBys);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#beginTransaction()
- */
- @Override
- public void beginTransaction() throws UnsupportedOperationException,
- SQLException {
- if (transactionOpen && activeConnection != null) {
- throw new IllegalStateException();
- }
-
- getLogger().log(Level.FINE, "DB -> begin transaction");
- activeConnection = connectionPool.reserveConnection();
- activeConnection.setAutoCommit(false);
- transactionOpen = true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#commit()
- */
- @Override
- public void commit() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> commit");
- activeConnection.commit();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
-
- /* Handle firing row ID change events */
- RowIdChangeEvent[] unFiredEvents = bufferedEvents
- .toArray(new RowIdChangeEvent[] {});
- bufferedEvents.clear();
- if (rowIdChangeListeners != null && !rowIdChangeListeners.isEmpty()) {
- for (RowIdChangeListener r : rowIdChangeListeners) {
- for (RowIdChangeEvent e : unFiredEvents) {
- r.rowIdChange(e);
- }
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.QueryDelegate#rollback()
- */
- @Override
- public void rollback() throws UnsupportedOperationException, SQLException {
- if (transactionOpen && activeConnection != null) {
- getLogger().log(Level.FINE, "DB -> rollback");
- activeConnection.rollback();
- connectionPool.releaseConnection(activeConnection);
- } else {
- throw new SQLException("No active transaction");
- }
- transactionOpen = false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#getPrimaryKeyColumns()
- */
- @Override
- public List<String> getPrimaryKeyColumns() {
- return Collections.unmodifiableList(primaryKeyColumns);
- }
-
- public String getVersionColumn() {
- return versionColumn;
- }
-
- public void setVersionColumn(String column) {
- versionColumn = column;
- }
-
- public String getTableName() {
- return tableName;
- }
-
- public SQLGenerator getSqlGenerator() {
- return sqlGenerator;
- }
-
- /**
- * Executes the given query string using either the active connection if a
- * transaction is already open, or a new connection from this query's
- * connection pool.
- *
- * @param sh
- * an instance of StatementHelper, containing the query string
- * and parameter values.
- * @return ResultSet of the query
- * @throws SQLException
- */
- private ResultSet executeQuery(StatementHelper sh) throws SQLException {
- Connection c = null;
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- throw new SQLException("No active transaction!");
- }
- PreparedStatement pstmt = c.prepareStatement(sh.getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
- return pstmt.executeQuery();
- }
-
- /**
- * Executes the given update query string using either the active connection
- * if a transaction is already open, or a new connection from this query's
- * connection pool.
- *
- * @param sh
- * an instance of StatementHelper, containing the query string
- * and parameter values.
- * @return Number of affected rows
- * @throws SQLException
- */
- private int executeUpdate(StatementHelper sh) throws SQLException {
- Connection c = null;
- PreparedStatement pstmt = null;
- try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString());
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
- int retval = pstmt.executeUpdate();
- return retval;
- } finally {
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
- }
- }
-
- /**
- * Executes the given update query string using either the active connection
- * if a transaction is already open, or a new connection from this query's
- * connection pool.
- *
- * Additionally adds a new RowIdChangeEvent to the event buffer.
- *
- * @param sh
- * an instance of StatementHelper, containing the query string
- * and parameter values.
- * @param row
- * the row item to update
- * @return Number of affected rows
- * @throws SQLException
- */
- private int executeUpdateReturnKeys(StatementHelper sh, RowItem row)
- throws SQLException {
- Connection c = null;
- PreparedStatement pstmt = null;
- ResultSet genKeys = null;
- try {
- if (transactionOpen && activeConnection != null) {
- c = activeConnection;
- } else {
- c = connectionPool.reserveConnection();
- }
- pstmt = c.prepareStatement(sh.getQueryString(),
- primaryKeyColumns.toArray(new String[0]));
- sh.setParameterValuesToStatement(pstmt);
- getLogger().log(Level.FINE, "DB -> " + sh.getQueryString());
- int result = pstmt.executeUpdate();
- genKeys = pstmt.getGeneratedKeys();
- RowId newId = getNewRowId(row, genKeys);
- bufferedEvents.add(new RowIdChangeEvent(row.getId(), newId));
- return result;
- } finally {
- if (genKeys != null) {
- genKeys.close();
- }
- if (pstmt != null) {
- pstmt.clearParameters();
- pstmt.close();
- }
- if (!transactionOpen) {
- connectionPool.releaseConnection(c);
- }
- }
- }
-
- /**
- * Fetches name(s) of primary key column(s) from DB metadata.
- *
- * Also tries to get the escape string to be used in search strings.
- */
- private void fetchMetaData() {
- Connection c = null;
- try {
- c = connectionPool.reserveConnection();
- DatabaseMetaData dbmd = c.getMetaData();
- if (dbmd != null) {
- tableName = SQLUtil.escapeSQL(tableName);
- ResultSet tables = dbmd.getTables(null, null, tableName, null);
- if (!tables.next()) {
- tables = dbmd.getTables(null, null,
- tableName.toUpperCase(), null);
- if (!tables.next()) {
- throw new IllegalArgumentException(
- "Table with the name \""
- + tableName
- + "\" was not found. Check your database contents.");
- } else {
- tableName = tableName.toUpperCase();
- }
- }
- tables.close();
- ResultSet rs = dbmd.getPrimaryKeys(null, null, tableName);
- List<String> names = new ArrayList<String>();
- while (rs.next()) {
- names.add(rs.getString("COLUMN_NAME"));
- }
- rs.close();
- if (!names.isEmpty()) {
- primaryKeyColumns = names;
- }
- if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) {
- throw new IllegalArgumentException(
- "Primary key constraints have not been defined for the table \""
- + tableName
- + "\". Use FreeFormQuery to access this table.");
- }
- for (String colName : primaryKeyColumns) {
- if (colName.equalsIgnoreCase("rownum")) {
- if (getSqlGenerator() instanceof MSSQLGenerator
- || getSqlGenerator() instanceof MSSQLGenerator) {
- throw new IllegalArgumentException(
- "When using Oracle or MSSQL, a primary key column"
- + " named \'rownum\' is not allowed!");
- }
- }
- }
- }
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- connectionPool.releaseConnection(c);
- }
- }
-
- private RowId getNewRowId(RowItem row, ResultSet genKeys) {
- try {
- /* Fetch primary key values and generate a map out of them. */
- Map<String, Object> values = new HashMap<String, Object>();
- ResultSetMetaData rsmd = genKeys.getMetaData();
- int colCount = rsmd.getColumnCount();
- if (genKeys.next()) {
- for (int i = 1; i <= colCount; i++) {
- values.put(rsmd.getColumnName(i), genKeys.getObject(i));
- }
- }
- /* Generate new RowId */
- List<Object> newRowId = new ArrayList<Object>();
- if (values.size() == 1) {
- if (primaryKeyColumns.size() == 1) {
- newRowId.add(values.get(values.keySet().iterator().next()));
- } else {
- for (String s : primaryKeyColumns) {
- if (!((ColumnProperty) row.getItemProperty(s))
- .isReadOnlyChangeAllowed()) {
- newRowId.add(values.get(values.keySet().iterator()
- .next()));
- } else {
- newRowId.add(values.get(s));
- }
- }
- }
- } else {
- for (String s : primaryKeyColumns) {
- newRowId.add(values.get(s));
- }
- }
- return new RowId(newRowId.toArray());
- } catch (Exception e) {
- getLogger().log(Level.FINE,
- "Failed to fetch key values on insert: " + e.getMessage());
- return null;
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#removeRow(com.vaadin
- * .addon.sqlcontainer.RowItem)
- */
- @Override
- public boolean removeRow(RowItem row) throws UnsupportedOperationException,
- SQLException {
- getLogger().log(Level.FINE,
- "Removing row with id: " + row.getId().getId()[0].toString());
- if (executeUpdate(sqlGenerator.generateDeleteQuery(getTableName(),
- primaryKeyColumns, versionColumn, row)) == 1) {
- return true;
- }
- if (versionColumn != null) {
- throw new OptimisticLockException(
- "Someone else changed the row that was being deleted.",
- row.getId());
- }
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.addon.sqlcontainer.query.QueryDelegate#containsRowWithKey(
- * java.lang.Object[])
- */
- @Override
- public boolean containsRowWithKey(Object... keys) throws SQLException {
- ArrayList<Filter> filtersAndKeys = new ArrayList<Filter>();
- if (filters != null) {
- filtersAndKeys.addAll(filters);
- }
- int ix = 0;
- for (String colName : primaryKeyColumns) {
- filtersAndKeys.add(new Equal(colName, keys[ix]));
- ix++;
- }
- StatementHelper sh = sqlGenerator.generateSelectQuery(tableName,
- filtersAndKeys, orderBys, 0, 0, "*");
-
- boolean shouldCloseTransaction = false;
- if (!transactionOpen) {
- shouldCloseTransaction = true;
- beginTransaction();
- }
- ResultSet rs = null;
- try {
- rs = executeQuery(sh);
- boolean contains = rs.next();
- return contains;
- } finally {
- if (rs != null) {
- if (rs.getStatement() != null) {
- rs.getStatement().close();
- }
- rs.close();
- }
- if (shouldCloseTransaction) {
- commit();
- }
- }
- }
-
- /**
- * Custom writeObject to call rollback() if object is serialized.
- */
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- try {
- rollback();
- } catch (SQLException ignored) {
- }
- out.defaultWriteObject();
- }
-
- /**
- * Simple RowIdChangeEvent implementation.
- */
- public class RowIdChangeEvent extends EventObject implements
- QueryDelegate.RowIdChangeEvent {
- private final RowId oldId;
- private final RowId newId;
-
- private RowIdChangeEvent(RowId oldId, RowId newId) {
- super(oldId);
- this.oldId = oldId;
- this.newId = newId;
- }
-
- @Override
- public RowId getNewRowId() {
- return newId;
- }
-
- @Override
- public RowId getOldRowId() {
- return oldId;
- }
- }
-
- /**
- * Adds RowIdChangeListener to this query
- */
- @Override
- public void addListener(RowIdChangeListener listener) {
- if (rowIdChangeListeners == null) {
- rowIdChangeListeners = new LinkedList<QueryDelegate.RowIdChangeListener>();
- }
- rowIdChangeListeners.add(listener);
- }
-
- /**
- * Removes the given RowIdChangeListener from this query
- */
- @Override
- public void removeListener(RowIdChangeListener listener) {
- if (rowIdChangeListeners != null) {
- rowIdChangeListeners.remove(listener);
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(TableQuery.class.getName());
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
deleted file mode 100644
index 6485330541..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.ColumnProperty;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-import com.vaadin.data.util.sqlcontainer.SQLUtil;
-import com.vaadin.data.util.sqlcontainer.TemporaryRowId;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
-import com.vaadin.data.util.sqlcontainer.query.generator.filter.StringDecorator;
-
-/**
- * Generates generic SQL that is supported by HSQLDB, MySQL and PostgreSQL.
- *
- * @author Jonatan Kronqvist / Vaadin Ltd
- */
-@SuppressWarnings("serial")
-public class DefaultSQLGenerator implements SQLGenerator {
-
- private Class<? extends StatementHelper> statementHelperClass = null;
-
- public DefaultSQLGenerator() {
-
- }
-
- /**
- * Create a new DefaultSqlGenerator instance that uses the given
- * implementation of {@link StatementHelper}
- *
- * @param statementHelper
- */
- public DefaultSQLGenerator(
- Class<? extends StatementHelper> statementHelperClazz) {
- this();
- statementHelperClass = statementHelperClazz;
- }
-
- /**
- * Construct a DefaultSQLGenerator with the specified identifiers for start
- * and end of quoted strings. The identifiers may be different depending on
- * the database engine and it's settings.
- *
- * @param quoteStart
- * the identifier (character) denoting the start of a quoted
- * string
- * @param quoteEnd
- * the identifier (character) denoting the end of a quoted string
- */
- public DefaultSQLGenerator(String quoteStart, String quoteEnd) {
- QueryBuilder.setStringDecorator(new StringDecorator(quoteStart,
- quoteEnd));
- }
-
- /**
- * Same as {@link #DefaultSQLGenerator(String, String)} but with support for
- * custom {@link StatementHelper} implementation.
- *
- * @param quoteStart
- * @param quoteEnd
- * @param statementHelperClazz
- */
- public DefaultSQLGenerator(String quoteStart, String quoteEnd,
- Class<? extends StatementHelper> statementHelperClazz) {
- this(quoteStart, quoteEnd);
- statementHelperClass = statementHelperClazz;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator#
- * generateSelectQuery(java.lang.String, java.util.List, java.util.List,
- * int, int, java.lang.String)
- */
- @Override
- public StatementHelper generateSelectQuery(String tableName,
- List<Filter> filters, List<OrderBy> orderBys, int offset,
- int pagelength, String toSelect) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- toSelect = toSelect == null ? "*" : toSelect;
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
- query.append("SELECT " + toSelect + " FROM ").append(
- SQLUtil.escapeSQL(tableName));
- if (filters != null) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- if (orderBys != null) {
- for (OrderBy o : orderBys) {
- generateOrderBy(query, o, orderBys.indexOf(o) == 0);
- }
- }
- if (pagelength != 0) {
- generateLimits(query, offset, pagelength);
- }
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator#
- * generateUpdateQuery(java.lang.String,
- * com.vaadin.addon.sqlcontainer.RowItem)
- */
- @Override
- public StatementHelper generateUpdateQuery(String tableName, RowItem item) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- if (item == null) {
- throw new IllegalArgumentException("Updated item must be given.");
- }
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
- query.append("UPDATE ").append(tableName).append(" SET");
-
- /* Generate column<->value and rowidentifiers map */
- Map<String, Object> columnToValueMap = generateColumnToValueMap(item);
- Map<String, Object> rowIdentifiers = generateRowIdentifiers(item);
- /* Generate columns and values to update */
- boolean first = true;
- for (String column : columnToValueMap.keySet()) {
- if (first) {
- query.append(" " + QueryBuilder.quote(column) + " = ?");
- } else {
- query.append(", " + QueryBuilder.quote(column) + " = ?");
- }
- sh.addParameterValue(columnToValueMap.get(column), item
- .getItemProperty(column).getType());
- first = false;
- }
- /* Generate identifiers for the row to be updated */
- first = true;
- for (String column : rowIdentifiers.keySet()) {
- if (first) {
- query.append(" WHERE " + QueryBuilder.quote(column) + " = ?");
- } else {
- query.append(" AND " + QueryBuilder.quote(column) + " = ?");
- }
- sh.addParameterValue(rowIdentifiers.get(column), item
- .getItemProperty(column).getType());
- first = false;
- }
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator#
- * generateInsertQuery(java.lang.String,
- * com.vaadin.addon.sqlcontainer.RowItem)
- */
- @Override
- public StatementHelper generateInsertQuery(String tableName, RowItem item) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- if (item == null) {
- throw new IllegalArgumentException("New item must be given.");
- }
- if (!(item.getId() instanceof TemporaryRowId)) {
- throw new IllegalArgumentException(
- "Cannot generate an insert query for item already in database.");
- }
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
- query.append("INSERT INTO ").append(tableName).append(" (");
-
- /* Generate column<->value map */
- Map<String, Object> columnToValueMap = generateColumnToValueMap(item);
- /* Generate column names for insert query */
- boolean first = true;
- for (String column : columnToValueMap.keySet()) {
- if (!first) {
- query.append(", ");
- }
- query.append(QueryBuilder.quote(column));
- first = false;
- }
-
- /* Generate values for insert query */
- query.append(") VALUES (");
- first = true;
- for (String column : columnToValueMap.keySet()) {
- if (!first) {
- query.append(", ");
- }
- query.append("?");
- sh.addParameterValue(columnToValueMap.get(column), item
- .getItemProperty(column).getType());
- first = false;
- }
- query.append(")");
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.SQLGenerator#
- * generateDeleteQuery(java.lang.String,
- * com.vaadin.addon.sqlcontainer.RowItem)
- */
- @Override
- public StatementHelper generateDeleteQuery(String tableName,
- List<String> primaryKeyColumns, String versionColumn, RowItem item) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- if (item == null) {
- throw new IllegalArgumentException(
- "Item to be deleted must be given.");
- }
- if (primaryKeyColumns == null || primaryKeyColumns.isEmpty()) {
- throw new IllegalArgumentException(
- "Valid keyColumnNames must be provided.");
- }
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
- query.append("DELETE FROM ").append(tableName).append(" WHERE ");
- int count = 1;
- for (String keyColName : primaryKeyColumns) {
- if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator)
- && keyColName.equalsIgnoreCase("rownum")) {
- count++;
- continue;
- }
- if (count > 1) {
- query.append(" AND ");
- }
- if (item.getItemProperty(keyColName).getValue() != null) {
- query.append(QueryBuilder.quote(keyColName) + " = ?");
- sh.addParameterValue(item.getItemProperty(keyColName)
- .getValue(), item.getItemProperty(keyColName).getType());
- }
- count++;
- }
- if (versionColumn != null) {
- query.append(String.format(" AND %s = ?",
- QueryBuilder.quote(versionColumn)));
- sh.addParameterValue(
- item.getItemProperty(versionColumn).getValue(), item
- .getItemProperty(versionColumn).getType());
- }
-
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /**
- * Generates sorting rules as an ORDER BY -clause
- *
- * @param sb
- * StringBuffer to which the clause is appended.
- * @param o
- * OrderBy object to be added into the sb.
- * @param firstOrderBy
- * If true, this is the first OrderBy.
- * @return
- */
- protected StringBuffer generateOrderBy(StringBuffer sb, OrderBy o,
- boolean firstOrderBy) {
- if (firstOrderBy) {
- sb.append(" ORDER BY ");
- } else {
- sb.append(", ");
- }
- sb.append(QueryBuilder.quote(o.getColumn()));
- if (o.isAscending()) {
- sb.append(" ASC");
- } else {
- sb.append(" DESC");
- }
- return sb;
- }
-
- /**
- * Generates the LIMIT and OFFSET clause.
- *
- * @param sb
- * StringBuffer to which the clause is appended.
- * @param offset
- * Value for offset.
- * @param pagelength
- * Value for pagelength.
- * @return StringBuffer with LIMIT and OFFSET clause added.
- */
- protected StringBuffer generateLimits(StringBuffer sb, int offset,
- int pagelength) {
- sb.append(" LIMIT ").append(pagelength).append(" OFFSET ")
- .append(offset);
- return sb;
- }
-
- protected Map<String, Object> generateColumnToValueMap(RowItem item) {
- Map<String, Object> columnToValueMap = new HashMap<String, Object>();
- for (Object id : item.getItemPropertyIds()) {
- ColumnProperty cp = (ColumnProperty) item.getItemProperty(id);
- /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */
- if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator)
- && cp.getPropertyId().equalsIgnoreCase("rownum")) {
- continue;
- }
- Object value = cp.getValue() == null ? null : cp.getValue();
- /* Only include properties whose read-only status can be altered */
- if (cp.isReadOnlyChangeAllowed() && !cp.isVersionColumn()) {
- columnToValueMap.put(cp.getPropertyId(), value);
- }
- }
- return columnToValueMap;
- }
-
- protected Map<String, Object> generateRowIdentifiers(RowItem item) {
- Map<String, Object> rowIdentifiers = new HashMap<String, Object>();
- for (Object id : item.getItemPropertyIds()) {
- ColumnProperty cp = (ColumnProperty) item.getItemProperty(id);
- /* Prevent "rownum" usage as a column name if MSSQL or ORACLE */
- if ((this instanceof MSSQLGenerator || this instanceof OracleGenerator)
- && cp.getPropertyId().equalsIgnoreCase("rownum")) {
- continue;
- }
- Object value = cp.getValue() == null ? null : cp.getValue();
- if (!cp.isReadOnlyChangeAllowed() || cp.isVersionColumn()) {
- rowIdentifiers.put(cp.getPropertyId(), value);
- }
- }
- return rowIdentifiers;
- }
-
- /**
- * Returns the statement helper for the generator. Override this to handle
- * platform specific data types.
- *
- * @see http://dev.vaadin.com/ticket/9148
- * @return a new instance of the statement helper
- */
- protected StatementHelper getStatementHelper() {
- if (statementHelperClass == null) {
- return new StatementHelper();
- }
-
- try {
- return statementHelperClass.newInstance();
- } catch (InstantiationException e) {
- throw new RuntimeException(
- "Unable to instantiate custom StatementHelper", e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(
- "Unable to instantiate custom StatementHelper", e);
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java
deleted file mode 100644
index 13ef1d0090..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
-
-@SuppressWarnings("serial")
-public class MSSQLGenerator extends DefaultSQLGenerator {
-
- public MSSQLGenerator() {
-
- }
-
- /**
- * Construct a MSSQLGenerator with the specified identifiers for start and
- * end of quoted strings. The identifiers may be different depending on the
- * database engine and it's settings.
- *
- * @param quoteStart
- * the identifier (character) denoting the start of a quoted
- * string
- * @param quoteEnd
- * the identifier (character) denoting the end of a quoted string
- */
- public MSSQLGenerator(String quoteStart, String quoteEnd) {
- super(quoteStart, quoteEnd);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator#
- * generateSelectQuery(java.lang.String, java.util.List,
- * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int,
- * int, java.lang.String)
- */
- @Override
- public StatementHelper generateSelectQuery(String tableName,
- List<Filter> filters, List<OrderBy> orderBys, int offset,
- int pagelength, String toSelect) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- /* Adjust offset and page length parameters to match "row numbers" */
- offset = pagelength > 1 ? ++offset : offset;
- pagelength = pagelength > 1 ? --pagelength : pagelength;
- toSelect = toSelect == null ? "*" : toSelect;
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
-
- /* Row count request is handled here */
- if ("COUNT(*)".equalsIgnoreCase(toSelect)) {
- query.append(String.format(
- "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s",
- QueryBuilder.quote("rowcount"), tableName));
- if (filters != null && !filters.isEmpty()) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- query.append(") AS t");
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /* SELECT without row number constraints */
- if (offset == 0 && pagelength == 0) {
- query.append("SELECT ").append(toSelect).append(" FROM ")
- .append(tableName);
- if (filters != null) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- if (orderBys != null) {
- for (OrderBy o : orderBys) {
- generateOrderBy(query, o, orderBys.indexOf(o) == 0);
- }
- }
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /* Remaining SELECT cases are handled here */
- query.append("SELECT * FROM (SELECT row_number() OVER (");
- if (orderBys != null) {
- for (OrderBy o : orderBys) {
- generateOrderBy(query, o, orderBys.indexOf(o) == 0);
- }
- }
- query.append(") AS rownum, " + toSelect + " FROM ").append(tableName);
- if (filters != null) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- query.append(") AS a WHERE a.rownum BETWEEN ").append(offset)
- .append(" AND ").append(Integer.toString(offset + pagelength));
- sh.setQueryString(query.toString());
- return sh;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java
deleted file mode 100644
index 43a562d3a8..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-import com.vaadin.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
-
-@SuppressWarnings("serial")
-public class OracleGenerator extends DefaultSQLGenerator {
-
- public OracleGenerator() {
-
- }
-
- public OracleGenerator(Class<? extends StatementHelper> statementHelperClazz) {
- super(statementHelperClazz);
- }
-
- /**
- * Construct an OracleSQLGenerator with the specified identifiers for start
- * and end of quoted strings. The identifiers may be different depending on
- * the database engine and it's settings.
- *
- * @param quoteStart
- * the identifier (character) denoting the start of a quoted
- * string
- * @param quoteEnd
- * the identifier (character) denoting the end of a quoted string
- */
- public OracleGenerator(String quoteStart, String quoteEnd) {
- super(quoteStart, quoteEnd);
- }
-
- public OracleGenerator(String quoteStart, String quoteEnd,
- Class<? extends StatementHelper> statementHelperClazz) {
- super(quoteStart, quoteEnd, statementHelperClazz);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.addon.sqlcontainer.query.generator.DefaultSQLGenerator#
- * generateSelectQuery(java.lang.String, java.util.List,
- * com.vaadin.addon.sqlcontainer.query.FilteringMode, java.util.List, int,
- * int, java.lang.String)
- */
- @Override
- public StatementHelper generateSelectQuery(String tableName,
- List<Filter> filters, List<OrderBy> orderBys, int offset,
- int pagelength, String toSelect) {
- if (tableName == null || tableName.trim().equals("")) {
- throw new IllegalArgumentException("Table name must be given.");
- }
- /* Adjust offset and page length parameters to match "row numbers" */
- offset = pagelength > 1 ? ++offset : offset;
- pagelength = pagelength > 1 ? --pagelength : pagelength;
- toSelect = toSelect == null ? "*" : toSelect;
- StatementHelper sh = getStatementHelper();
- StringBuffer query = new StringBuffer();
-
- /* Row count request is handled here */
- if ("COUNT(*)".equalsIgnoreCase(toSelect)) {
- query.append(String.format(
- "SELECT COUNT(*) AS %s FROM (SELECT * FROM %s",
- QueryBuilder.quote("rowcount"), tableName));
- if (filters != null && !filters.isEmpty()) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- query.append(")");
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /* SELECT without row number constraints */
- if (offset == 0 && pagelength == 0) {
- query.append("SELECT ").append(toSelect).append(" FROM ")
- .append(tableName);
- if (filters != null) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- if (orderBys != null) {
- for (OrderBy o : orderBys) {
- generateOrderBy(query, o, orderBys.indexOf(o) == 0);
- }
- }
- sh.setQueryString(query.toString());
- return sh;
- }
-
- /* Remaining SELECT cases are handled here */
- query.append(String
- .format("SELECT * FROM (SELECT x.*, ROWNUM AS %s FROM (SELECT %s FROM %s",
- QueryBuilder.quote("rownum"), toSelect, tableName));
- if (filters != null) {
- query.append(QueryBuilder.getWhereStringForFilters(filters, sh));
- }
- if (orderBys != null) {
- for (OrderBy o : orderBys) {
- generateOrderBy(query, o, orderBys.indexOf(o) == 0);
- }
- }
- query.append(String.format(") x) WHERE %s BETWEEN %d AND %d",
- QueryBuilder.quote("rownum"), offset, offset + pagelength));
- sh.setQueryString(query.toString());
- return sh;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java
deleted file mode 100644
index dde7077eee..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.io.Serializable;
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.RowItem;
-import com.vaadin.data.util.sqlcontainer.query.OrderBy;
-
-/**
- * The SQLGenerator interface is meant to be implemented for each different SQL
- * syntax that is to be supported. By default there are implementations for
- * HSQLDB, MySQL, PostgreSQL, MSSQL and Oracle syntaxes.
- *
- * @author Jonatan Kronqvist / Vaadin Ltd
- */
-public interface SQLGenerator extends Serializable {
- /**
- * Generates a SELECT query with the provided parameters. Uses default
- * filtering mode (INCLUSIVE).
- *
- * @param tableName
- * Name of the table queried
- * @param filters
- * The filters, converted into a WHERE clause
- * @param orderBys
- * The the ordering conditions, converted into an ORDER BY clause
- * @param offset
- * The offset of the first row to be included
- * @param pagelength
- * The number of rows to be returned when the query executes
- * @param toSelect
- * String containing what to select, e.g. "*", "COUNT(*)"
- * @return StatementHelper instance containing the query string for a
- * PreparedStatement and the values required for the parameters
- */
- public StatementHelper generateSelectQuery(String tableName,
- List<Filter> filters, List<OrderBy> orderBys, int offset,
- int pagelength, String toSelect);
-
- /**
- * Generates an UPDATE query with the provided parameters.
- *
- * @param tableName
- * Name of the table queried
- * @param item
- * RowItem containing the updated values update.
- * @return StatementHelper instance containing the query string for a
- * PreparedStatement and the values required for the parameters
- */
- public StatementHelper generateUpdateQuery(String tableName, RowItem item);
-
- /**
- * Generates an INSERT query for inserting a new row with the provided
- * values.
- *
- * @param tableName
- * Name of the table queried
- * @param item
- * New RowItem to be inserted into the database.
- * @return StatementHelper instance containing the query string for a
- * PreparedStatement and the values required for the parameters
- */
- public StatementHelper generateInsertQuery(String tableName, RowItem item);
-
- /**
- * Generates a DELETE query for deleting data related to the given RowItem
- * from the database.
- *
- * @param tableName
- * Name of the table queried
- * @param primaryKeyColumns
- * the names of the columns holding the primary key. Usually just
- * one column, but might be several.
- * @param versionColumn
- * the column containing the version number of the row, null if
- * versioning (optimistic locking) not enabled.
- * @param item
- * Item to be deleted from the database
- * @return StatementHelper instance containing the query string for a
- * PreparedStatement and the values required for the parameters
- */
- public StatementHelper generateDeleteQuery(String tableName,
- List<String> primaryKeyColumns, String versionColumn, RowItem item);
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
deleted file mode 100644
index b012ce7685..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * StatementHelper is a simple helper class that assists TableQuery and the
- * query generators in filling a PreparedStatement. The actual statement is
- * generated by the query generator methods, but the resulting statement and all
- * the parameter values are stored in an instance of StatementHelper.
- *
- * This class will also fill the values with correct setters into the
- * PreparedStatement on request.
- */
-public class StatementHelper implements Serializable {
-
- private String queryString;
-
- private List<Object> parameters = new ArrayList<Object>();
- private Map<Integer, Class<?>> dataTypes = new HashMap<Integer, Class<?>>();
-
- public StatementHelper() {
- }
-
- public void setQueryString(String queryString) {
- this.queryString = queryString;
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public void addParameterValue(Object parameter) {
- if (parameter != null) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, parameter.getClass());
- } else {
- throw new IllegalArgumentException(
- "You cannot add null parameters using addParamaters(Object). "
- + "Use addParameters(Object,Class) instead");
- }
- }
-
- public void addParameterValue(Object parameter, Class<?> type) {
- parameters.add(parameter);
- dataTypes.put(parameters.size() - 1, type);
- }
-
- public void setParameterValuesToStatement(PreparedStatement pstmt)
- throws SQLException {
- for (int i = 0; i < parameters.size(); i++) {
- if (parameters.get(i) == null) {
- handleNullValue(i, pstmt);
- } else {
- pstmt.setObject(i + 1, parameters.get(i));
- }
- }
-
- /*
- * The following list contains the data types supported by
- * PreparedStatement but not supported by SQLContainer:
- *
- * [The list is provided as PreparedStatement method signatures]
- *
- * setNCharacterStream(int parameterIndex, Reader value)
- *
- * setNClob(int parameterIndex, NClob value)
- *
- * setNString(int parameterIndex, String value)
- *
- * setRef(int parameterIndex, Ref x)
- *
- * setRowId(int parameterIndex, RowId x)
- *
- * setSQLXML(int parameterIndex, SQLXML xmlObject)
- *
- * setBytes(int parameterIndex, byte[] x)
- *
- * setCharacterStream(int parameterIndex, Reader reader)
- *
- * setClob(int parameterIndex, Clob x)
- *
- * setURL(int parameterIndex, URL x)
- *
- * setArray(int parameterIndex, Array x)
- *
- * setAsciiStream(int parameterIndex, InputStream x)
- *
- * setBinaryStream(int parameterIndex, InputStream x)
- *
- * setBlob(int parameterIndex, Blob x)
- */
- }
-
- private void handleNullValue(int i, PreparedStatement pstmt)
- throws SQLException {
- if (BigDecimal.class.equals(dataTypes.get(i))) {
- pstmt.setBigDecimal(i + 1, null);
- } else if (Boolean.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BOOLEAN);
- } else if (Byte.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (Date.class.equals(dataTypes.get(i))) {
- pstmt.setDate(i + 1, null);
- } else if (Double.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.DOUBLE);
- } else if (Float.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.FLOAT);
- } else if (Integer.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.INTEGER);
- } else if (Long.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.BIGINT);
- } else if (Short.class.equals(dataTypes.get(i))) {
- pstmt.setNull(i + 1, Types.SMALLINT);
- } else if (String.class.equals(dataTypes.get(i))) {
- pstmt.setString(i + 1, null);
- } else if (Time.class.equals(dataTypes.get(i))) {
- pstmt.setTime(i + 1, null);
- } else if (Timestamp.class.equals(dataTypes.get(i))) {
- pstmt.setTimestamp(i + 1, null);
- } else {
-
- if (handleUnrecognizedTypeNullValue(i, pstmt, dataTypes)) {
- return;
- }
-
- throw new SQLException("Data type not supported by SQLContainer: "
- + parameters.get(i).getClass().toString());
- }
- }
-
- /**
- * Handle unrecognized null values. Override this to handle null values for
- * platform specific data types that are not handled by the default
- * implementation of the {@link StatementHelper}.
- *
- * @param i
- * @param pstmt
- * @param dataTypes2
- *
- * @return true if handled, false otherwise
- *
- * @see {@link http://dev.vaadin.com/ticket/9148}
- */
- protected boolean handleUnrecognizedTypeNullValue(int i,
- PreparedStatement pstmt, Map<Integer, Class<?>> dataTypes)
- throws SQLException {
- return false;
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java
deleted file mode 100644
index 251a543a8a..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.And;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class AndTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof And;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- return QueryBuilder.group(QueryBuilder.getJoinedFilterString(
- ((And) filter).getFilters(), "AND", sh));
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java
deleted file mode 100644
index 4fcaf759ea..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Between;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class BetweenTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof Between;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- Between between = (Between) filter;
- sh.addParameterValue(between.getStartValue());
- sh.addParameterValue(between.getEndValue());
- return QueryBuilder.quote(between.getPropertyId()) + " BETWEEN ? AND ?";
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java
deleted file mode 100644
index 4293e1d630..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Compare;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class CompareTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof Compare;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- Compare compare = (Compare) filter;
- sh.addParameterValue(compare.getValue());
- String prop = QueryBuilder.quote(compare.getPropertyId());
- switch (compare.getOperation()) {
- case EQUAL:
- return prop + " = ?";
- case GREATER:
- return prop + " > ?";
- case GREATER_OR_EQUAL:
- return prop + " >= ?";
- case LESS:
- return prop + " < ?";
- case LESS_OR_EQUAL:
- return prop + " <= ?";
- default:
- return "";
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java
deleted file mode 100644
index 84af9d5c97..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import java.io.Serializable;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public interface FilterTranslator extends Serializable {
- public boolean translatesFilter(Filter filter);
-
- public String getWhereStringForFilter(Filter filter, StatementHelper sh);
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java
deleted file mode 100644
index a2a6cd2c09..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.IsNull;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class IsNullTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof IsNull;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- IsNull in = (IsNull) filter;
- return QueryBuilder.quote(in.getPropertyId()) + " IS NULL";
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java
deleted file mode 100644
index 25a85caec0..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Like;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class LikeTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof Like;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- Like like = (Like) filter;
- if (like.isCaseSensitive()) {
- sh.addParameterValue(like.getValue());
- return QueryBuilder.quote(like.getPropertyId()) + " LIKE ?";
- } else {
- sh.addParameterValue(like.getValue().toUpperCase());
- return "UPPER(" + QueryBuilder.quote(like.getPropertyId())
- + ") LIKE ?";
- }
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java
deleted file mode 100644
index 5dfbe240e7..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.IsNull;
-import com.vaadin.data.util.filter.Not;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class NotTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof Not;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- Not not = (Not) filter;
- if (not.getFilter() instanceof IsNull) {
- IsNull in = (IsNull) not.getFilter();
- return QueryBuilder.quote(in.getPropertyId()) + " IS NOT NULL";
- }
- return "NOT "
- + QueryBuilder.getWhereStringForFilter(not.getFilter(), sh);
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java
deleted file mode 100644
index 2f0ed814e0..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Or;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class OrTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof Or;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- return QueryBuilder.group(QueryBuilder.getJoinedFilterString(
- ((Or) filter).getFilters(), "OR", sh));
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java
deleted file mode 100644
index 24be8963e0..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class QueryBuilder implements Serializable {
-
- private static ArrayList<FilterTranslator> filterTranslators = new ArrayList<FilterTranslator>();
- private static StringDecorator stringDecorator = new StringDecorator("\"",
- "\"");
-
- static {
- /* Register all default filter translators */
- addFilterTranslator(new AndTranslator());
- addFilterTranslator(new OrTranslator());
- addFilterTranslator(new LikeTranslator());
- addFilterTranslator(new BetweenTranslator());
- addFilterTranslator(new CompareTranslator());
- addFilterTranslator(new NotTranslator());
- addFilterTranslator(new IsNullTranslator());
- addFilterTranslator(new SimpleStringTranslator());
- }
-
- public synchronized static void addFilterTranslator(
- FilterTranslator translator) {
- filterTranslators.add(translator);
- }
-
- /**
- * Allows specification of a custom ColumnQuoter instance that handles
- * quoting of column names for the current DB dialect.
- *
- * @param decorator
- * the ColumnQuoter instance to use.
- */
- public static void setStringDecorator(StringDecorator decorator) {
- stringDecorator = decorator;
- }
-
- public static String quote(Object str) {
- return stringDecorator.quote(str);
- }
-
- public static String group(String str) {
- return stringDecorator.group(str);
- }
-
- /**
- * Constructs and returns a string representing the filter that can be used
- * in a WHERE clause.
- *
- * @param filter
- * the filter to translate
- * @param sh
- * the statement helper to update with the value(s) of the filter
- * @return a string representing the filter.
- */
- public synchronized static String getWhereStringForFilter(Filter filter,
- StatementHelper sh) {
- for (FilterTranslator ft : filterTranslators) {
- if (ft.translatesFilter(filter)) {
- return ft.getWhereStringForFilter(filter, sh);
- }
- }
- return "";
- }
-
- public static String getJoinedFilterString(Collection<Filter> filters,
- String joinString, StatementHelper sh) {
- StringBuilder result = new StringBuilder();
- for (Filter f : filters) {
- result.append(getWhereStringForFilter(f, sh));
- result.append(" ").append(joinString).append(" ");
- }
- // Remove the last instance of joinString
- result.delete(result.length() - joinString.length() - 2,
- result.length());
- return result.toString();
- }
-
- public static String getWhereStringForFilters(List<Filter> filters,
- StatementHelper sh) {
- if (filters == null || filters.isEmpty()) {
- return "";
- }
- StringBuilder where = new StringBuilder(" WHERE ");
- where.append(getJoinedFilterString(filters, "AND", sh));
- return where.toString();
- }
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java
deleted file mode 100644
index f108003535..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import com.vaadin.data.Container.Filter;
-import com.vaadin.data.util.filter.Like;
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.data.util.sqlcontainer.query.generator.StatementHelper;
-
-public class SimpleStringTranslator implements FilterTranslator {
-
- @Override
- public boolean translatesFilter(Filter filter) {
- return filter instanceof SimpleStringFilter;
- }
-
- @Override
- public String getWhereStringForFilter(Filter filter, StatementHelper sh) {
- SimpleStringFilter ssf = (SimpleStringFilter) filter;
- // Create a Like filter based on the SimpleStringFilter and execute the
- // LikeTranslator
- String likeStr = ssf.isOnlyMatchPrefix() ? ssf.getFilterString() + "%"
- : "%" + ssf.getFilterString() + "%";
- Like like = new Like(ssf.getPropertyId().toString(), likeStr);
- like.setCaseSensitive(!ssf.isIgnoreCase());
- return new LikeTranslator().getWhereStringForFilter(like, sh);
- }
-
-}
diff --git a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java b/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java
deleted file mode 100644
index 8d2eabb5bc..0000000000
--- a/src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.util.sqlcontainer.query.generator.filter;
-
-import java.io.Serializable;
-
-/**
- * The StringDecorator knows how to produce a quoted string using the specified
- * quote start and quote end characters. It also handles grouping of a string
- * (surrounding it in parenthesis).
- *
- * Extend this class if you need to support special characters for grouping
- * (parenthesis).
- *
- * @author Vaadin Ltd
- */
-public class StringDecorator implements Serializable {
-
- private final String quoteStart;
- private final String quoteEnd;
-
- /**
- * Constructs a StringDecorator that uses the quoteStart and quoteEnd
- * characters to create quoted strings.
- *
- * @param quoteStart
- * the character denoting the start of a quote.
- * @param quoteEnd
- * the character denoting the end of a quote.
- */
- public StringDecorator(String quoteStart, String quoteEnd) {
- this.quoteStart = quoteStart;
- this.quoteEnd = quoteEnd;
- }
-
- /**
- * Surround a string with quote characters.
- *
- * @param str
- * the string to quote
- * @return the quoted string
- */
- public String quote(Object str) {
- return quoteStart + str + quoteEnd;
- }
-
- /**
- * Groups a string by surrounding it in parenthesis
- *
- * @param str
- * the string to group
- * @return the grouped string
- */
- public String group(String str) {
- return "(" + str + ")";
- }
-}
diff --git a/src/com/vaadin/data/validator/AbstractStringValidator.java b/src/com/vaadin/data/validator/AbstractStringValidator.java
deleted file mode 100644
index 5267cc7b7b..0000000000
--- a/src/com/vaadin/data/validator/AbstractStringValidator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * Validator base class for validating strings.
- * <p>
- * To include the value that failed validation in the exception message you can
- * use "{0}" in the error message. This will be replaced with the failed value
- * (converted to string using {@link #toString()}) or "null" if the value is
- * null.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- * @since 5.4
- */
-@SuppressWarnings("serial")
-public abstract class AbstractStringValidator extends AbstractValidator<String> {
-
- /**
- * Constructs a validator for strings.
- *
- * <p>
- * Null and empty string values are always accepted. To reject empty values,
- * set the field being validated as required.
- * </p>
- *
- * @param errorMessage
- * the message to be included in an {@link InvalidValueException}
- * (with "{0}" replaced by the value that failed validation).
- * */
- public AbstractStringValidator(String errorMessage) {
- super(errorMessage);
- }
-
- @Override
- public Class<String> getType() {
- return String.class;
- }
-}
diff --git a/src/com/vaadin/data/validator/AbstractValidator.java b/src/com/vaadin/data/validator/AbstractValidator.java
deleted file mode 100644
index 8febe5338a..0000000000
--- a/src/com/vaadin/data/validator/AbstractValidator.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import com.vaadin.data.Validator;
-
-/**
- * Abstract {@link com.vaadin.data.Validator Validator} implementation that
- * provides a basic Validator implementation except the
- * {@link #isValidValue(Object)} method.
- * <p>
- * To include the value that failed validation in the exception message you can
- * use "{0}" in the error message. This will be replaced with the failed value
- * (converted to string using {@link #toString()}) or "null" if the value is
- * null.
- * </p>
- * <p>
- * The default implementation of AbstractValidator does not support HTML in
- * error messages. To enable HTML support, override
- * {@link InvalidValueException#getHtmlMessage()} and throw such exceptions from
- * {@link #validate(Object)}.
- * </p>
- * <p>
- * Since Vaadin 7, subclasses can either implement {@link #validate(Object)}
- * directly or implement {@link #isValidValue(Object)} when migrating legacy
- * applications. To check validity, {@link #validate(Object)} should be used.
- * </p>
- *
- * @param <T>
- * The type
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- */
-public abstract class AbstractValidator<T> implements Validator {
-
- /**
- * Error message that is included in an {@link InvalidValueException} if
- * such is thrown.
- */
- private String errorMessage;
-
- /**
- * Constructs a validator with the given error message.
- *
- * @param errorMessage
- * the message to be included in an {@link InvalidValueException}
- * (with "{0}" replaced by the value that failed validation).
- */
- public AbstractValidator(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- /**
- * Since Vaadin 7, subclasses of AbstractValidator should override
- * {@link #isValidValue(Object)} or {@link #validate(Object)} instead of
- * {@link #isValid(Object)}. {@link #validate(Object)} should normally be
- * used to check values.
- *
- * @param value
- * @return true if the value is valid
- */
- public boolean isValid(Object value) {
- try {
- validate(value);
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Internally check the validity of a value. This method can be used to
- * perform validation in subclasses if customization of the error message is
- * not needed. Otherwise, subclasses should override
- * {@link #validate(Object)} and the return value of this method is ignored.
- *
- * This method should not be called from outside the validator class itself.
- *
- * @param value
- * @return
- */
- protected abstract boolean isValidValue(T value);
-
- @Override
- public void validate(Object value) throws InvalidValueException {
- // isValidType ensures that value can safely be cast to TYPE
- if (!isValidType(value) || !isValidValue((T) value)) {
- String message = getErrorMessage().replace("{0}",
- String.valueOf(value));
- throw new InvalidValueException(message);
- }
- }
-
- /**
- * Checks the type of the value to validate to ensure it conforms with
- * getType. Enables sub classes to handle the specific type instead of
- * Object.
- *
- * @param value
- * The value to check
- * @return true if the value can safely be cast to the type specified by
- * {@link #getType()}
- */
- protected boolean isValidType(Object value) {
- if (value == null) {
- return true;
- }
-
- return getType().isAssignableFrom(value.getClass());
- }
-
- /**
- * Returns the message to be included in the exception in case the value
- * does not validate.
- *
- * @return the error message provided in the constructor or using
- * {@link #setErrorMessage(String)}.
- */
- public String getErrorMessage() {
- return errorMessage;
- }
-
- /**
- * Sets the message to be included in the exception in case the value does
- * not validate. The exception message is typically shown to the end user.
- *
- * @param errorMessage
- * the error message. "{0}" is automatically replaced by the
- * value that did not validate.
- */
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- public abstract Class<T> getType();
-}
diff --git a/src/com/vaadin/data/validator/BeanValidator.java b/src/com/vaadin/data/validator/BeanValidator.java
deleted file mode 100644
index 816ff79b83..0000000000
--- a/src/com/vaadin/data/validator/BeanValidator.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-import javax.validation.ConstraintViolation;
-import javax.validation.MessageInterpolator.Context;
-import javax.validation.Validation;
-import javax.validation.ValidatorFactory;
-import javax.validation.metadata.ConstraintDescriptor;
-
-import com.vaadin.data.Validator;
-
-/**
- * Vaadin {@link Validator} using the JSR-303 (javax.validation)
- * annotation-based bean validation.
- *
- * The annotations of the fields of the beans are used to determine the
- * validation to perform.
- *
- * Note that a JSR-303 implementation (e.g. Hibernate Validator or Apache Bean
- * Validation - formerly agimatec validation) must be present on the project
- * classpath when using bean validation.
- *
- * @since 7.0
- *
- * @author Petri Hakala
- * @author Henri Sara
- */
-public class BeanValidator implements Validator {
-
- private static final long serialVersionUID = 1L;
- private static ValidatorFactory factory;
-
- private transient javax.validation.Validator javaxBeanValidator;
- private String propertyName;
- private Class<?> beanClass;
- private Locale locale;
-
- /**
- * Simple implementation of a message interpolator context that returns
- * fixed values.
- */
- protected static class SimpleContext implements Context, Serializable {
-
- private final Object value;
- private final ConstraintDescriptor<?> descriptor;
-
- /**
- * Create a simple immutable message interpolator context.
- *
- * @param value
- * value being validated
- * @param descriptor
- * ConstraintDescriptor corresponding to the constraint being
- * validated
- */
- public SimpleContext(Object value, ConstraintDescriptor<?> descriptor) {
- this.value = value;
- this.descriptor = descriptor;
- }
-
- @Override
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return descriptor;
- }
-
- @Override
- public Object getValidatedValue() {
- return value;
- }
-
- }
-
- /**
- * Creates a Vaadin {@link Validator} utilizing JSR-303 bean validation.
- *
- * @param beanClass
- * bean class based on which the validation should be performed
- * @param propertyName
- * property to validate
- */
- public BeanValidator(Class<?> beanClass, String propertyName) {
- this.beanClass = beanClass;
- this.propertyName = propertyName;
- locale = Locale.getDefault();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Validator#validate(java.lang.Object)
- */
- @Override
- public void validate(final Object value) throws InvalidValueException {
- Set<?> violations = getJavaxBeanValidator().validateValue(beanClass,
- propertyName, value);
- if (violations.size() > 0) {
- List<String> exceptions = new ArrayList<String>();
- for (Object v : violations) {
- final ConstraintViolation<?> violation = (ConstraintViolation<?>) v;
- String msg = getJavaxBeanValidatorFactory()
- .getMessageInterpolator().interpolate(
- violation.getMessageTemplate(),
- new SimpleContext(value, violation
- .getConstraintDescriptor()), locale);
- exceptions.add(msg);
- }
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < exceptions.size(); i++) {
- if (i != 0) {
- b.append("<br/>");
- }
- b.append(exceptions.get(i));
- }
- throw new InvalidValueException(b.toString());
- }
- }
-
- /**
- * Sets the locale used for validation error messages.
- *
- * Revalidation is not automatically triggered by setting the locale.
- *
- * @param locale
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Gets the locale used for validation error messages.
- *
- * @return locale used for validation
- */
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Returns the underlying JSR-303 bean validator factory used. A factory is
- * created using {@link Validation} if necessary.
- *
- * @return {@link ValidatorFactory} to use
- */
- protected static ValidatorFactory getJavaxBeanValidatorFactory() {
- if (factory == null) {
- factory = Validation.buildDefaultValidatorFactory();
- }
-
- return factory;
- }
-
- /**
- * Returns a shared Validator instance to use. An instance is created using
- * the validator factory if necessary and thereafter reused by the
- * {@link BeanValidator} instance.
- *
- * @return the JSR-303 {@link javax.validation.Validator} to use
- */
- protected javax.validation.Validator getJavaxBeanValidator() {
- if (javaxBeanValidator == null) {
- javaxBeanValidator = getJavaxBeanValidatorFactory().getValidator();
- }
-
- return javaxBeanValidator;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/data/validator/CompositeValidator.java b/src/com/vaadin/data/validator/CompositeValidator.java
deleted file mode 100644
index cad31c9d4d..0000000000
--- a/src/com/vaadin/data/validator/CompositeValidator.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.data.Validator;
-
-/**
- * The <code>CompositeValidator</code> allows you to chain (compose) many
- * validators to validate one field. The contained validators may be required to
- * all validate the value to validate or it may be enough that one contained
- * validator validates the value. This behaviour is controlled by the modes
- * <code>AND</code> and <code>OR</code>.
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class CompositeValidator implements Validator {
-
- public enum CombinationMode {
- /**
- * The validators are combined with <code>AND</code> clause: validity of
- * the composite implies validity of the all validators it is composed
- * of must be valid.
- */
- AND,
- /**
- * The validators are combined with <code>OR</code> clause: validity of
- * the composite implies that some of validators it is composed of must
- * be valid.
- */
- OR;
- }
-
- /**
- * @deprecated from 7.0, use {@link CombinationMode#AND} instead    
- */
- @Deprecated
- public static final CombinationMode MODE_AND = CombinationMode.AND;
- /**
- * @deprecated from 7.0, use {@link CombinationMode#OR} instead    
- */
- @Deprecated
- public static final CombinationMode MODE_OR = CombinationMode.OR;
-
- private String errorMessage;
-
- /**
- * Operation mode.
- */
- private CombinationMode mode = CombinationMode.AND;
-
- /**
- * List of contained validators.
- */
- private final List<Validator> validators = new LinkedList<Validator>();
-
- /**
- * Construct a composite validator in <code>AND</code> mode without error
- * message.
- */
- public CompositeValidator() {
- this(CombinationMode.AND, "");
- }
-
- /**
- * Constructs a composite validator in given mode.
- *
- * @param mode
- * @param errorMessage
- */
- public CompositeValidator(CombinationMode mode, String errorMessage) {
- setErrorMessage(errorMessage);
- setMode(mode);
- }
-
- /**
- * Validates the given value.
- * <p>
- * The value is valid, if:
- * <ul>
- * <li><code>MODE_AND</code>: All of the sub-validators are valid
- * <li><code>MODE_OR</code>: Any of the sub-validators are valid
- * </ul>
- *
- * If the value is invalid, validation error is thrown. If the error message
- * is set (non-null), it is used. If the error message has not been set, the
- * first error occurred is thrown.
- * </p>
- *
- * @param value
- * the value to check.
- * @throws Validator.InvalidValueException
- * if the value is not valid.
- */
- @Override
- public void validate(Object value) throws Validator.InvalidValueException {
- switch (mode) {
- case AND:
- for (Validator validator : validators) {
- validator.validate(value);
- }
- return;
-
- case OR:
- Validator.InvalidValueException first = null;
- for (Validator v : validators) {
- try {
- v.validate(value);
- return;
- } catch (final Validator.InvalidValueException e) {
- if (first == null) {
- first = e;
- }
- }
- }
- if (first == null) {
- return;
- }
- final String em = getErrorMessage();
- if (em != null) {
- throw new Validator.InvalidValueException(em);
- } else {
- throw first;
- }
- }
- }
-
- /**
- * Gets the mode of the validator.
- *
- * @return Operation mode of the validator: {@link CombinationMode#AND} or
- * {@link CombinationMode#OR}.
- */
- public final CombinationMode getMode() {
- return mode;
- }
-
- /**
- * Sets the mode of the validator. The valid modes are:
- * <ul>
- * <li>{@link CombinationMode#AND} (default)
- * <li>{@link CombinationMode#OR}
- * </ul>
- *
- * @param mode
- * the mode to set.
- */
- public void setMode(CombinationMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException(
- "The validator can't be set to null");
- }
- this.mode = mode;
- }
-
- /**
- * Gets the error message for the composite validator. If the error message
- * is null, original error messages of the sub-validators are used instead.
- */
- public String getErrorMessage() {
- if (errorMessage != null) {
- return errorMessage;
- }
-
- // TODO Return composite error message
-
- return null;
- }
-
- /**
- * Adds validator to the interface.
- *
- * @param validator
- * the Validator object which performs validation checks on this
- * set of data field values.
- */
- public void addValidator(Validator validator) {
- if (validator == null) {
- return;
- }
- validators.add(validator);
- }
-
- /**
- * Removes a validator from the composite.
- *
- * @param validator
- * the Validator object which performs validation checks on this
- * set of data field values.
- */
- public void removeValidator(Validator validator) {
- validators.remove(validator);
- }
-
- /**
- * Gets sub-validators by class.
- *
- * <p>
- * If the component contains directly or recursively (it contains another
- * composite containing the validator) validators compatible with given type
- * they are returned. This only applies to <code>AND</code> mode composite
- * validators.
- * </p>
- *
- * <p>
- * If the validator is in <code>OR</code> mode or does not contain any
- * validators of given type null is returned.
- * </p>
- *
- * @param validatorType
- * The type of validators to return
- *
- * @return Collection<Validator> of validators compatible with given type
- * that must apply or null if none found.
- */
- public Collection<Validator> getSubValidators(Class validatorType) {
- if (mode != CombinationMode.AND) {
- return null;
- }
-
- final HashSet<Validator> found = new HashSet<Validator>();
- for (Validator v : validators) {
- if (validatorType.isAssignableFrom(v.getClass())) {
- found.add(v);
- }
- if (v instanceof CompositeValidator
- && ((CompositeValidator) v).getMode() == MODE_AND) {
- final Collection<Validator> c = ((CompositeValidator) v)
- .getSubValidators(validatorType);
- if (c != null) {
- found.addAll(c);
- }
- }
- }
-
- return found.isEmpty() ? null : found;
- }
-
- /**
- * Sets the message to be included in the exception in case the value does
- * not validate. The exception message is typically shown to the end user.
- *
- * @param errorMessage
- * the error message.
- */
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
-}
diff --git a/src/com/vaadin/data/validator/DateRangeValidator.java b/src/com/vaadin/data/validator/DateRangeValidator.java
deleted file mode 100644
index 24f3d3ce10..0000000000
--- a/src/com/vaadin/data/validator/DateRangeValidator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import java.util.Date;
-
-import com.vaadin.ui.DateField.Resolution;
-
-/**
- * Validator for validating that a Date is inside a given range.
- *
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class DateRangeValidator extends RangeValidator<Date> {
-
- /**
- * Creates a validator for checking that an Date is within a given range.
- * <p>
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- * </p>
- * <p>
- * Note that the comparison is done directly on the Date object so take care
- * that the hours/minutes/seconds/milliseconds of the min/max values are
- * properly set.
- * </p>
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public DateRangeValidator(String errorMessage, Date minValue,
- Date maxValue, Resolution resolution) {
- super(errorMessage, Date.class, minValue, maxValue);
- }
-
-}
diff --git a/src/com/vaadin/data/validator/DoubleRangeValidator.java b/src/com/vaadin/data/validator/DoubleRangeValidator.java
deleted file mode 100644
index 05ae2f827e..0000000000
--- a/src/com/vaadin/data/validator/DoubleRangeValidator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * Validator for validating that a {@link Double} is inside a given range.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-@SuppressWarnings("serial")
-public class DoubleRangeValidator extends RangeValidator<Double> {
-
- /**
- * Creates a validator for checking that an Double is within a given range.
- *
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- *
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public DoubleRangeValidator(String errorMessage, Double minValue,
- Double maxValue) {
- super(errorMessage, Double.class, minValue, maxValue);
- }
-
-}
diff --git a/src/com/vaadin/data/validator/DoubleValidator.java b/src/com/vaadin/data/validator/DoubleValidator.java
deleted file mode 100644
index 18f1909add..0000000000
--- a/src/com/vaadin/data/validator/DoubleValidator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * String validator for a double precision floating point number. See
- * {@link com.vaadin.data.validator.AbstractStringValidator} for more
- * information.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- * @deprecated in Vaadin 7.0. Use an Double converter on the field instead.
- */
-@Deprecated
-@SuppressWarnings("serial")
-public class DoubleValidator extends AbstractStringValidator {
-
- /**
- * Creates a validator for checking that a string can be parsed as an
- * double.
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @deprecated in Vaadin 7.0. Use a Double converter on the field instead
- * and/or use a {@link DoubleRangeValidator} for validating that
- * the value is inside a given range.
- */
- @Deprecated
- public DoubleValidator(String errorMessage) {
- super(errorMessage);
- }
-
- @Override
- protected boolean isValidValue(String value) {
- try {
- Double.parseDouble(value);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- @Override
- public void validate(Object value) throws InvalidValueException {
- if (value != null && value instanceof Double) {
- // Allow Doubles to pass through the validator for easier
- // migration. Otherwise a TextField connected to an double property
- // with a DoubleValidator will fail.
- return;
- }
-
- super.validate(value);
- }
-
-}
diff --git a/src/com/vaadin/data/validator/EmailValidator.java b/src/com/vaadin/data/validator/EmailValidator.java
deleted file mode 100644
index c76d7e13dc..0000000000
--- a/src/com/vaadin/data/validator/EmailValidator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * String validator for e-mail addresses. The e-mail address syntax is not
- * complete according to RFC 822 but handles the vast majority of valid e-mail
- * addresses correctly.
- *
- * See {@link com.vaadin.data.validator.AbstractStringValidator} for more
- * information.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- */
-@SuppressWarnings("serial")
-public class EmailValidator extends RegexpValidator {
-
- /**
- * Creates a validator for checking that a string is a syntactically valid
- * e-mail address.
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- */
- public EmailValidator(String errorMessage) {
- super(
- "^([a-zA-Z0-9_\\.\\-+])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$",
- true, errorMessage);
- }
-
-}
diff --git a/src/com/vaadin/data/validator/IntegerRangeValidator.java b/src/com/vaadin/data/validator/IntegerRangeValidator.java
deleted file mode 100644
index c171dd97d8..0000000000
--- a/src/com/vaadin/data/validator/IntegerRangeValidator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * Validator for validating that an {@link Integer} is inside a given range.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- */
-@SuppressWarnings("serial")
-public class IntegerRangeValidator extends RangeValidator<Integer> {
-
- /**
- * Creates a validator for checking that an Integer is within a given range.
- *
- * By default the range is inclusive i.e. both minValue and maxValue are
- * valid values. Use {@link #setMinValueIncluded(boolean)} or
- * {@link #setMaxValueIncluded(boolean)} to change it.
- *
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minValue
- * The minimum value to accept or null for no limit
- * @param maxValue
- * The maximum value to accept or null for no limit
- */
- public IntegerRangeValidator(String errorMessage, Integer minValue,
- Integer maxValue) {
- super(errorMessage, Integer.class, minValue, maxValue);
- }
-
-}
diff --git a/src/com/vaadin/data/validator/IntegerValidator.java b/src/com/vaadin/data/validator/IntegerValidator.java
deleted file mode 100644
index 88ae9f3f0b..0000000000
--- a/src/com/vaadin/data/validator/IntegerValidator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * String validator for integers. See
- * {@link com.vaadin.data.validator.AbstractStringValidator} for more
- * information.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- * @deprecated in Vaadin 7.0. Use an Integer converter on the field instead.
- */
-@SuppressWarnings("serial")
-@Deprecated
-public class IntegerValidator extends AbstractStringValidator {
-
- /**
- * Creates a validator for checking that a string can be parsed as an
- * integer.
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @deprecated in Vaadin 7.0. Use an Integer converter on the field instead
- * and/or use an {@link IntegerRangeValidator} for validating
- * that the value is inside a given range.
- */
- @Deprecated
- public IntegerValidator(String errorMessage) {
- super(errorMessage);
-
- }
-
- @Override
- protected boolean isValidValue(String value) {
- try {
- Integer.parseInt(value);
- return true;
- } catch (Exception e) {
- return false;
- }
- }
-
- @Override
- public void validate(Object value) throws InvalidValueException {
- if (value != null && value instanceof Integer) {
- // Allow Integers to pass through the validator for easier
- // migration. Otherwise a TextField connected to an integer property
- // with an IntegerValidator will fail.
- return;
- }
-
- super.validate(value);
- }
-}
diff --git a/src/com/vaadin/data/validator/NullValidator.java b/src/com/vaadin/data/validator/NullValidator.java
deleted file mode 100644
index 551d88c776..0000000000
--- a/src/com/vaadin/data/validator/NullValidator.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-import com.vaadin.data.Validator;
-
-/**
- * This validator is used for validating properties that do or do not allow null
- * values. By default, nulls are not allowed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class NullValidator implements Validator {
-
- private boolean onlyNullAllowed;
-
- private String errorMessage;
-
- /**
- * Creates a new NullValidator.
- *
- * @param errorMessage
- * the error message to display on invalidation.
- * @param onlyNullAllowed
- * Are only nulls allowed?
- */
- public NullValidator(String errorMessage, boolean onlyNullAllowed) {
- setErrorMessage(errorMessage);
- setNullAllowed(onlyNullAllowed);
- }
-
- /**
- * Validates the data given in value.
- *
- * @param value
- * the value to validate.
- * @throws Validator.InvalidValueException
- * if the value was invalid.
- */
- @Override
- public void validate(Object value) throws Validator.InvalidValueException {
- if ((onlyNullAllowed && value != null)
- || (!onlyNullAllowed && value == null)) {
- throw new Validator.InvalidValueException(errorMessage);
- }
- }
-
- /**
- * Returns <code>true</code> if nulls are allowed otherwise
- * <code>false</code>.
- */
- public final boolean isNullAllowed() {
- return onlyNullAllowed;
- }
-
- /**
- * Sets if nulls (and only nulls) are to be allowed.
- *
- * @param onlyNullAllowed
- * If true, only nulls are allowed. If false only non-nulls are
- * allowed. Do we allow nulls?
- */
- public void setNullAllowed(boolean onlyNullAllowed) {
- this.onlyNullAllowed = onlyNullAllowed;
- }
-
- /**
- * Gets the error message that is displayed in case the value is invalid.
- *
- * @return the Error Message.
- */
- public String getErrorMessage() {
- return errorMessage;
- }
-
- /**
- * Sets the error message to be displayed on invalid value.
- *
- * @param errorMessage
- * the Error Message to set.
- */
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
-}
diff --git a/src/com/vaadin/data/validator/RangeValidator.java b/src/com/vaadin/data/validator/RangeValidator.java
deleted file mode 100644
index 433271274f..0000000000
--- a/src/com/vaadin/data/validator/RangeValidator.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-/**
- * An base implementation for validating any objects that implement
- * {@link Comparable}.
- *
- * Verifies that the value is of the given type and within the (optionally)
- * given limits. Typically you want to use a sub class of this like
- * {@link IntegerRangeValidator}, {@link DoubleRangeValidator} or
- * {@link DateRangeValidator} in applications.
- * <p>
- * Note that {@link RangeValidator} always accept null values. Make a field
- * required to ensure that no empty values are accepted or override
- * {@link #isValidValue(Comparable)}.
- * </p>
- *
- * @param <T>
- * The type of Number to validate. Must implement Comparable so that
- * minimum and maximum checks work.
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
-public class RangeValidator<T extends Comparable> extends AbstractValidator<T> {
-
- private T minValue = null;
- private boolean minValueIncluded = true;
- private T maxValue = null;
- private boolean maxValueIncluded = true;
- private Class<T> type;
-
- /**
- * Creates a new range validator of the given type.
- *
- * @param errorMessage
- * The error message to use if validation fails
- * @param type
- * The type of object the validator can validate.
- * @param minValue
- * The minimum value that should be accepted or null for no limit
- * @param maxValue
- * The maximum value that should be accepted or null for no limit
- */
- public RangeValidator(String errorMessage, Class<T> type, T minValue,
- T maxValue) {
- super(errorMessage);
- this.type = type;
- this.minValue = minValue;
- this.maxValue = maxValue;
- }
-
- /**
- * Checks if the minimum value is part of the accepted range
- *
- * @return true if the minimum value is part of the range, false otherwise
- */
- public boolean isMinValueIncluded() {
- return minValueIncluded;
- }
-
- /**
- * Sets if the minimum value is part of the accepted range
- *
- * @param minValueIncluded
- * true if the minimum value should be part of the range, false
- * otherwise
- */
- public void setMinValueIncluded(boolean minValueIncluded) {
- this.minValueIncluded = minValueIncluded;
- }
-
- /**
- * Checks if the maximum value is part of the accepted range
- *
- * @return true if the maximum value is part of the range, false otherwise
- */
- public boolean isMaxValueIncluded() {
- return maxValueIncluded;
- }
-
- /**
- * Sets if the maximum value is part of the accepted range
- *
- * @param maxValueIncluded
- * true if the maximum value should be part of the range, false
- * otherwise
- */
- public void setMaxValueIncluded(boolean maxValueIncluded) {
- this.maxValueIncluded = maxValueIncluded;
- }
-
- /**
- * Gets the minimum value of the range
- *
- * @return the minimum value
- */
- public T getMinValue() {
- return minValue;
- }
-
- /**
- * Sets the minimum value of the range. Use
- * {@link #setMinValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param minValue
- * the minimum value
- */
- public void setMinValue(T minValue) {
- this.minValue = minValue;
- }
-
- /**
- * Gets the maximum value of the range
- *
- * @return the maximum value
- */
- public T getMaxValue() {
- return maxValue;
- }
-
- /**
- * Sets the maximum value of the range. Use
- * {@link #setMaxValueIncluded(boolean)} to control whether this value is
- * part of the range or not.
- *
- * @param maxValue
- * the maximum value
- */
- public void setMaxValue(T maxValue) {
- this.maxValue = maxValue;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
- * )
- */
- @Override
- protected boolean isValidValue(T value) {
- if (value == null) {
- return true;
- }
-
- if (getMinValue() != null) {
- // Ensure that the min limit is ok
- int result = value.compareTo(getMinValue());
- if (result < 0) {
- // value less than min value
- return false;
- } else if (result == 0 && !isMinValueIncluded()) {
- // values equal and min value not included
- return false;
- }
- }
- if (getMaxValue() != null) {
- // Ensure that the Max limit is ok
- int result = value.compareTo(getMaxValue());
- if (result > 0) {
- // value greater than max value
- return false;
- } else if (result == 0 && !isMaxValueIncluded()) {
- // values equal and max value not included
- return false;
- }
- }
- return true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.validator.AbstractValidator#getType()
- */
- @Override
- public Class<T> getType() {
- return type;
- }
-
-}
diff --git a/src/com/vaadin/data/validator/RegexpValidator.java b/src/com/vaadin/data/validator/RegexpValidator.java
deleted file mode 100644
index 8143d54c97..0000000000
--- a/src/com/vaadin/data/validator/RegexpValidator.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.data.validator;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * String validator comparing the string against a Java regular expression. Both
- * complete matches and substring matches are supported.
- *
- * <p>
- * For the Java regular expression syntax, see
- * {@link java.util.regex.Pattern#sum}
- * </p>
- * <p>
- * See {@link com.vaadin.data.validator.AbstractStringValidator} for more
- * information.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.4
- */
-@SuppressWarnings("serial")
-public class RegexpValidator extends AbstractStringValidator {
-
- private Pattern pattern;
- private boolean complete;
- private transient Matcher matcher = null;
-
- /**
- * Creates a validator for checking that the regular expression matches the
- * complete string to validate.
- *
- * @param regexp
- * a Java regular expression
- * @param errorMessage
- * the message to display in case the value does not validate.
- */
- public RegexpValidator(String regexp, String errorMessage) {
- this(regexp, true, errorMessage);
- }
-
- /**
- * Creates a validator for checking that the regular expression matches the
- * string to validate.
- *
- * @param regexp
- * a Java regular expression
- * @param complete
- * true to use check for a complete match, false to look for a
- * matching substring
- * @param errorMessage
- * the message to display in case the value does not validate.
- */
- public RegexpValidator(String regexp, boolean complete, String errorMessage) {
- super(errorMessage);
- pattern = Pattern.compile(regexp);
- this.complete = complete;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.data.validator.AbstractValidator#isValidValue(java.lang.Object
- * )
- */
- @Override
- protected boolean isValidValue(String value) {
- if (complete) {
- return getMatcher(value).matches();
- } else {
- return getMatcher(value).find();
- }
- }
-
- /**
- * Get a new or reused matcher for the pattern
- *
- * @param value
- * the string to find matches in
- * @return Matcher for the string
- */
- private Matcher getMatcher(String value) {
- if (matcher == null) {
- matcher = pattern.matcher(value);
- } else {
- matcher.reset(value);
- }
- return matcher;
- }
-
-}
diff --git a/src/com/vaadin/data/validator/StringLengthValidator.java b/src/com/vaadin/data/validator/StringLengthValidator.java
deleted file mode 100644
index 54b2d28f58..0000000000
--- a/src/com/vaadin/data/validator/StringLengthValidator.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.data.validator;
-
-/**
- * This <code>StringLengthValidator</code> is used to validate the length of
- * strings.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class StringLengthValidator extends AbstractStringValidator {
-
- private Integer minLength = null;
-
- private Integer maxLength = null;
-
- private boolean allowNull = true;
-
- /**
- * Creates a new StringLengthValidator with a given error message.
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- */
- public StringLengthValidator(String errorMessage) {
- super(errorMessage);
- }
-
- /**
- * Creates a new StringLengthValidator with a given error message and
- * minimum and maximum length limits.
- *
- * @param errorMessage
- * the message to display in case the value does not validate.
- * @param minLength
- * the minimum permissible length of the string or null for no
- * limit. A negative value for no limit is also supported for
- * backwards compatibility.
- * @param maxLength
- * the maximum permissible length of the string or null for no
- * limit. A negative value for no limit is also supported for
- * backwards compatibility.
- * @param allowNull
- * Are null strings permissible? This can be handled better by
- * setting a field as required or not.
- */
- public StringLengthValidator(String errorMessage, Integer minLength,
- Integer maxLength, boolean allowNull) {
- this(errorMessage);
- setMinLength(minLength);
- setMaxLength(maxLength);
- setNullAllowed(allowNull);
- }
-
- /**
- * Checks if the given value is valid.
- *
- * @param value
- * the value to validate.
- * @return <code>true</code> for valid value, otherwise <code>false</code>.
- */
- @Override
- protected boolean isValidValue(String value) {
- if (value == null) {
- return allowNull;
- }
- final int len = value.length();
- if ((minLength != null && minLength > -1 && len < minLength)
- || (maxLength != null && maxLength > -1 && len > maxLength)) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns <code>true</code> if null strings are allowed.
- *
- * @return <code>true</code> if allows null string, otherwise
- * <code>false</code>.
- */
- @Deprecated
- public final boolean isNullAllowed() {
- return allowNull;
- }
-
- /**
- * Gets the maximum permissible length of the string.
- *
- * @return the maximum length of the string or null if there is no limit
- */
- public Integer getMaxLength() {
- return maxLength;
- }
-
- /**
- * Gets the minimum permissible length of the string.
- *
- * @return the minimum length of the string or null if there is no limit
- */
- public Integer getMinLength() {
- return minLength;
- }
-
- /**
- * Sets whether null-strings are to be allowed. This can be better handled
- * by setting a field as required or not.
- */
- @Deprecated
- public void setNullAllowed(boolean allowNull) {
- this.allowNull = allowNull;
- }
-
- /**
- * Sets the maximum permissible length of the string.
- *
- * @param maxLength
- * the maximum length to accept or null for no limit
- */
- public void setMaxLength(Integer maxLength) {
- this.maxLength = maxLength;
- }
-
- /**
- * Sets the minimum permissible length.
- *
- * @param minLength
- * the minimum length to accept or null for no limit
- */
- public void setMinLength(Integer minLength) {
- this.minLength = minLength;
- }
-
-}
diff --git a/src/com/vaadin/data/validator/package.html b/src/com/vaadin/data/validator/package.html
deleted file mode 100644
index c991bfc82a..0000000000
--- a/src/com/vaadin/data/validator/package.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-
-</head>
-
-<body bgcolor="white">
-
-<!-- Package summary here -->
-
-<p>Provides various {@link com.vaadin.data.Validator}
-implementations.</p>
-
-<p>{@link com.vaadin.data.validator.AbstractValidator
-AbstractValidator} provides an abstract implementation of the {@link
-com.vaadin.data.Validator} interface and can be extended for custom
-validation needs. {@link
-com.vaadin.data.validator.AbstractStringValidator
-AbstractStringValidator} can also be extended if the value is a String.</p>
-
-
-</body>
-</html>
diff --git a/src/com/vaadin/event/Action.java b/src/com/vaadin/event/Action.java
deleted file mode 100644
index 6c218c25dc..0000000000
--- a/src/com/vaadin/event/Action.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.Resource;
-
-/**
- * Implements the action framework. This class contains subinterfaces for action
- * handling and listing, and for action handler registrations and
- * unregistration.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Action implements Serializable {
-
- /**
- * Action title.
- */
- private String caption;
-
- /**
- * Action icon.
- */
- private Resource icon = null;
-
- /**
- * Constructs a new action with the given caption.
- *
- * @param caption
- * the caption for the new action.
- */
- public Action(String caption) {
- this.caption = caption;
- }
-
- /**
- * Constructs a new action with the given caption string and icon.
- *
- * @param caption
- * the caption for the new action.
- * @param icon
- * the icon for the new action.
- */
- public Action(String caption, Resource icon) {
- this.caption = caption;
- this.icon = icon;
- }
-
- /**
- * Returns the action's caption.
- *
- * @return the action's caption as a <code>String</code>.
- */
- public String getCaption() {
- return caption;
- }
-
- /**
- * Returns the action's icon.
- *
- * @return the action's Icon.
- */
- public Resource getIcon() {
- return icon;
- }
-
- /**
- * An Action that implements this interface can be added to an
- * Action.Notifier (or NotifierProxy) via the <code>addAction()</code>
- * -method, which in many cases is easier than implementing the
- * Action.Handler interface.<br/>
- *
- */
- public interface Listener extends Serializable {
- public void handleAction(Object sender, Object target);
- }
-
- /**
- * Action.Containers implementing this support an easier way of adding
- * single Actions than the more involved Action.Handler. The added actions
- * must be Action.Listeners, thus handling the action themselves.
- *
- */
- public interface Notifier extends Container {
- public <T extends Action & Action.Listener> void addAction(T action);
-
- public <T extends Action & Action.Listener> void removeAction(T action);
- }
-
- public interface ShortcutNotifier extends Serializable {
- public void addShortcutListener(ShortcutListener shortcut);
-
- public void removeShortcutListener(ShortcutListener shortcut);
- }
-
- /**
- * Interface implemented by classes who wish to handle actions.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface Handler extends Serializable {
-
- /**
- * Gets the list of actions applicable to this handler.
- *
- * @param target
- * the target handler to list actions for. For item
- * containers this is the item id.
- * @param sender
- * the party that would be sending the actions. Most of this
- * is the action container.
- * @return the list of Action
- */
- public Action[] getActions(Object target, Object sender);
-
- /**
- * Handles an action for the given target. The handler method may just
- * discard the action if it's not suitable.
- *
- * @param action
- * the action to be handled.
- * @param sender
- * the sender of the action. This is most often the action
- * container.
- * @param target
- * the target of the action. For item containers this is the
- * item id.
- */
- public void handleAction(Action action, Object sender, Object target);
- }
-
- /**
- * Interface implemented by all components where actions can be registered.
- * This means that the components lets others to register as action handlers
- * to it. When the component receives an action targeting its contents it
- * should loop all action handlers registered to it and let them handle the
- * action.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface Container extends Serializable {
-
- /**
- * Registers a new action handler for this container
- *
- * @param actionHandler
- * the new handler to be added.
- */
- public void addActionHandler(Action.Handler actionHandler);
-
- /**
- * Removes a previously registered action handler for the contents of
- * this container.
- *
- * @param actionHandler
- * the handler to be removed.
- */
- public void removeActionHandler(Action.Handler actionHandler);
- }
-
- /**
- * Sets the caption.
- *
- * @param caption
- * the caption to set.
- */
- public void setCaption(String caption) {
- this.caption = caption;
- }
-
- /**
- * Sets the icon.
- *
- * @param icon
- * the icon to set.
- */
- public void setIcon(Resource icon) {
- this.icon = icon;
- }
-
-}
diff --git a/src/com/vaadin/event/ActionManager.java b/src/com/vaadin/event/ActionManager.java
deleted file mode 100644
index 64fdeea69b..0000000000
--- a/src/com/vaadin/event/ActionManager.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.util.HashSet;
-import java.util.Map;
-
-import com.vaadin.event.Action.Container;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.terminal.KeyMapper;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.ui.Component;
-
-/**
- * Javadoc TODO
- *
- * Notes:
- * <p>
- * Empties the keymapper for each repaint to avoid leaks; can cause problems in
- * the future if the client assumes key don't change. (if lazyloading, one must
- * not cache results)
- * </p>
- *
- *
- */
-public class ActionManager implements Action.Container, Action.Handler,
- Action.Notifier {
-
- private static final long serialVersionUID = 1641868163608066491L;
-
- /** List of action handlers */
- protected HashSet<Action> ownActions = null;
-
- /** List of action handlers */
- protected HashSet<Handler> actionHandlers = null;
-
- /** Action mapper */
- protected KeyMapper<Action> actionMapper = null;
-
- protected Component viewer;
-
- private boolean clientHasActions = false;
-
- public ActionManager() {
-
- }
-
- public <T extends Component & Container & VariableOwner> ActionManager(
- T viewer) {
- this.viewer = viewer;
- }
-
- private void requestRepaint() {
- if (viewer != null) {
- viewer.requestRepaint();
- }
- }
-
- public <T extends Component & Container & VariableOwner> void setViewer(
- T viewer) {
- if (viewer == this.viewer) {
- return;
- }
- if (this.viewer != null) {
- ((Container) this.viewer).removeActionHandler(this);
- }
- requestRepaint(); // this goes to the old viewer
- if (viewer != null) {
- viewer.addActionHandler(this);
- }
- this.viewer = viewer;
- requestRepaint(); // this goes to the new viewer
- }
-
- @Override
- public <T extends Action & Action.Listener> void addAction(T action) {
- if (ownActions == null) {
- ownActions = new HashSet<Action>();
- }
- if (ownActions.add(action)) {
- requestRepaint();
- }
- }
-
- @Override
- public <T extends Action & Action.Listener> void removeAction(T action) {
- if (ownActions != null) {
- if (ownActions.remove(action)) {
- requestRepaint();
- }
- }
- }
-
- @Override
- public void addActionHandler(Handler actionHandler) {
- if (actionHandler == this) {
- // don't add the actionHandler to itself
- return;
- }
- if (actionHandler != null) {
-
- if (actionHandlers == null) {
- actionHandlers = new HashSet<Handler>();
- }
-
- if (actionHandlers.add(actionHandler)) {
- requestRepaint();
- }
- }
- }
-
- @Override
- public void removeActionHandler(Action.Handler actionHandler) {
- if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
-
- if (actionHandlers.remove(actionHandler)) {
- requestRepaint();
- }
- if (actionHandlers.isEmpty()) {
- actionHandlers = null;
- }
-
- }
- }
-
- public void removeAllActionHandlers() {
- if (actionHandlers != null) {
- actionHandlers = null;
- requestRepaint();
- }
- }
-
- public void paintActions(Object actionTarget, PaintTarget paintTarget)
- throws PaintException {
-
- actionMapper = null;
-
- HashSet<Action> actions = new HashSet<Action>();
- if (actionHandlers != null) {
- for (Action.Handler handler : actionHandlers) {
- Action[] as = handler.getActions(actionTarget, viewer);
- if (as != null) {
- for (Action action : as) {
- actions.add(action);
- }
- }
- }
- }
- if (ownActions != null) {
- actions.addAll(ownActions);
- }
-
- /*
- * Must repaint whenever there are actions OR if all actions have been
- * removed but still exist on client side
- */
- if (!actions.isEmpty() || clientHasActions) {
- actionMapper = new KeyMapper<Action>();
-
- paintTarget.addVariable((VariableOwner) viewer, "action", "");
- paintTarget.startTag("actions");
-
- for (final Action a : actions) {
- paintTarget.startTag("action");
- final String akey = actionMapper.key(a);
- paintTarget.addAttribute("key", akey);
- if (a.getCaption() != null) {
- paintTarget.addAttribute("caption", a.getCaption());
- }
- if (a.getIcon() != null) {
- paintTarget.addAttribute("icon", a.getIcon());
- }
- if (a instanceof ShortcutAction) {
- final ShortcutAction sa = (ShortcutAction) a;
- paintTarget.addAttribute("kc", sa.getKeyCode());
- final int[] modifiers = sa.getModifiers();
- if (modifiers != null) {
- final String[] smodifiers = new String[modifiers.length];
- for (int i = 0; i < modifiers.length; i++) {
- smodifiers[i] = String.valueOf(modifiers[i]);
- }
- paintTarget.addAttribute("mk", smodifiers);
- }
- }
- paintTarget.endTag("action");
- }
-
- paintTarget.endTag("actions");
- }
-
- /*
- * Update flag for next repaint so we know if we need to paint empty
- * actions or not (must send actions is client had actions before and
- * all actions were removed).
- */
- clientHasActions = !actions.isEmpty();
- }
-
- public void handleActions(Map<String, Object> variables, Container sender) {
- if (variables.containsKey("action") && actionMapper != null) {
- final String key = (String) variables.get("action");
- final Action action = actionMapper.get(key);
- final Object target = variables.get("actiontarget");
- if (action != null) {
- handleAction(action, sender, target);
- }
- }
- }
-
- @Override
- public Action[] getActions(Object target, Object sender) {
- HashSet<Action> actions = new HashSet<Action>();
- if (ownActions != null) {
- for (Action a : ownActions) {
- actions.add(a);
- }
- }
- if (actionHandlers != null) {
- for (Action.Handler h : actionHandlers) {
- Action[] as = h.getActions(target, sender);
- if (as != null) {
- for (Action a : as) {
- actions.add(a);
- }
- }
- }
- }
- return actions.toArray(new Action[actions.size()]);
- }
-
- @Override
- public void handleAction(Action action, Object sender, Object target) {
- if (actionHandlers != null) {
- Handler[] array = actionHandlers.toArray(new Handler[actionHandlers
- .size()]);
- for (Handler handler : array) {
- handler.handleAction(action, sender, target);
- }
- }
- if (ownActions != null && ownActions.contains(action)
- && action instanceof Action.Listener) {
- ((Action.Listener) action).handleAction(sender, target);
- }
- }
-
-}
diff --git a/src/com/vaadin/event/ComponentEventListener.java b/src/com/vaadin/event/ComponentEventListener.java
deleted file mode 100644
index 21fe8683f6..0000000000
--- a/src/com/vaadin/event/ComponentEventListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.util.EventListener;
-
-public interface ComponentEventListener extends EventListener, Serializable {
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/DataBoundTransferable.java b/src/com/vaadin/event/DataBoundTransferable.java
deleted file mode 100644
index 6f742e68d3..0000000000
--- a/src/com/vaadin/event/DataBoundTransferable.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.util.Map;
-
-import com.vaadin.data.Container;
-import com.vaadin.ui.Component;
-
-/**
- * Parent class for {@link Transferable} implementations that have a Vaadin
- * container as a data source. The transfer is associated with an item
- * (identified by its Id) and optionally also a property identifier (e.g. a
- * table column identifier when transferring a single table cell).
- *
- * The component must implement the interface
- * {@link com.vaadin.data.Container.Viewer}.
- *
- * In most cases, receivers of data transfers should depend on this class
- * instead of its concrete subclasses.
- *
- * @since 6.3
- */
-public abstract class DataBoundTransferable extends TransferableImpl {
-
- public DataBoundTransferable(Component sourceComponent,
- Map<String, Object> rawVariables) {
- super(sourceComponent, rawVariables);
- }
-
- /**
- * Returns the identifier of the item being transferred.
- *
- * @return item identifier
- */
- public abstract Object getItemId();
-
- /**
- * Returns the optional property identifier that the transfer concerns.
- *
- * This can be e.g. the table column from which a drag operation originated.
- *
- * @return property identifier
- */
- public abstract Object getPropertyId();
-
- /**
- * Returns the container data source from which the transfer occurs.
- *
- * {@link com.vaadin.data.Container.Viewer#getContainerDataSource()} is used
- * to obtain the underlying container of the source component.
- *
- * @return Container
- */
- public Container getSourceContainer() {
- Component sourceComponent = getSourceComponent();
- if (sourceComponent instanceof Container.Viewer) {
- return ((Container.Viewer) sourceComponent)
- .getContainerDataSource();
- } else {
- // this should not happen
- return null;
- }
- }
-}
diff --git a/src/com/vaadin/event/EventRouter.java b/src/com/vaadin/event/EventRouter.java
deleted file mode 100644
index 90c080b860..0000000000
--- a/src/com/vaadin/event/EventRouter.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EventObject;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-
-/**
- * <code>EventRouter</code> class implementing the inheritable event listening
- * model. For more information on the event model see the
- * {@link com.vaadin.event package documentation}.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class EventRouter implements MethodEventSource {
-
- /**
- * List of registered listeners.
- */
- private LinkedHashSet<ListenerMethod> listenerList = null;
-
- /*
- * Registers a new listener with the specified activation method to listen
- * events generated by this component. Don't add a JavaDoc comment here, we
- * use the default documentation from implemented interface.
- */
- @Override
- public void addListener(Class<?> eventType, Object object, Method method) {
- if (listenerList == null) {
- listenerList = new LinkedHashSet<ListenerMethod>();
- }
- listenerList.add(new ListenerMethod(eventType, object, method));
- }
-
- /*
- * Registers a new listener with the specified named activation method to
- * listen events generated by this component. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public void addListener(Class<?> eventType, Object object, String methodName) {
- if (listenerList == null) {
- listenerList = new LinkedHashSet<ListenerMethod>();
- }
- listenerList.add(new ListenerMethod(eventType, object, methodName));
- }
-
- /*
- * Removes all registered listeners matching the given parameters. Don't add
- * a JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target) {
- if (listenerList != null) {
- final Iterator<ListenerMethod> i = listenerList.iterator();
- while (i.hasNext()) {
- final ListenerMethod lm = i.next();
- if (lm.matches(eventType, target)) {
- i.remove();
- return;
- }
- }
- }
- }
-
- /*
- * Removes the event listener methods matching the given given paramaters.
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target, Method method) {
- if (listenerList != null) {
- final Iterator<ListenerMethod> i = listenerList.iterator();
- while (i.hasNext()) {
- final ListenerMethod lm = i.next();
- if (lm.matches(eventType, target, method)) {
- i.remove();
- return;
- }
- }
- }
- }
-
- /*
- * Removes the event listener method matching the given given parameters.
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target,
- String methodName) {
-
- // Find the correct method
- final Method[] methods = target.getClass().getMethods();
- Method method = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().equals(methodName)) {
- method = methods[i];
- }
- }
- if (method == null) {
- throw new IllegalArgumentException();
- }
-
- // Remove the listeners
- if (listenerList != null) {
- final Iterator<ListenerMethod> i = listenerList.iterator();
- while (i.hasNext()) {
- final ListenerMethod lm = i.next();
- if (lm.matches(eventType, target, method)) {
- i.remove();
- return;
- }
- }
- }
-
- }
-
- /**
- * Removes all listeners from event router.
- */
- public void removeAllListeners() {
- listenerList = null;
- }
-
- /**
- * Sends an event to all registered listeners. The listeners will decide if
- * the activation method should be called or not.
- *
- * @param event
- * the Event to be sent to all listeners.
- */
- public void fireEvent(EventObject event) {
- // It is not necessary to send any events if there are no listeners
- if (listenerList != null) {
-
- // Make a copy of the listener list to allow listeners to be added
- // inside listener methods. Fixes #3605.
-
- // Send the event to all listeners. The listeners themselves
- // will filter out unwanted events.
- final Object[] listeners = listenerList.toArray();
- for (int i = 0; i < listeners.length; i++) {
- ((ListenerMethod) listeners[i]).receiveEvent(event);
- }
-
- }
- }
-
- /**
- * Checks if the given Event type is listened by a listener registered to
- * this router.
- *
- * @param eventType
- * the event type to be checked
- * @return true if a listener is registered for the given event type
- */
- public boolean hasListeners(Class<?> eventType) {
- if (listenerList != null) {
- for (ListenerMethod lm : listenerList) {
- if (lm.isType(eventType)) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Returns all listeners that match or extend the given event type.
- *
- * @param eventType
- * The type of event to return listeners for.
- * @return A collection with all registered listeners. Empty if no listeners
- * are found.
- */
- public Collection<?> getListeners(Class<?> eventType) {
- List<Object> listeners = new ArrayList<Object>();
- if (listenerList != null) {
- for (ListenerMethod lm : listenerList) {
- if (lm.isOrExtendsType(eventType)) {
- listeners.add(lm.getTarget());
- }
- }
- }
- return listeners;
- }
-}
diff --git a/src/com/vaadin/event/FieldEvents.java b/src/com/vaadin/event/FieldEvents.java
deleted file mode 100644
index 8f101c1913..0000000000
--- a/src/com/vaadin/event/FieldEvents.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.shared.EventId;
-import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Component.Event;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.Field.ValueChangeEvent;
-import com.vaadin.ui.TextField;
-
-/**
- * Interface that serves as a wrapper for {@link Field} related events.
- */
-public interface FieldEvents {
-
- /**
- * The interface for adding and removing <code>FocusEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>FocusEvent</code> when it receives keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see FocusListener
- * @see FocusEvent
- */
- public interface FocusNotifier extends Serializable {
- /**
- * Adds a <code>FocusListener</code> to the Component which gets fired
- * when a <code>Field</code> receives keyboard focus.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void addListener(FocusListener listener);
-
- /**
- * Removes a <code>FocusListener</code> from the Component.
- *
- * @param listener
- * @see FocusListener
- * @since 6.2
- */
- public void removeListener(FocusListener listener);
- }
-
- /**
- * The interface for adding and removing <code>BlurEvent</code> listeners.
- * By implementing this interface a class explicitly announces that it will
- * generate a <code>BlurEvent</code> when it loses keyboard focus.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.2
- * @see BlurListener
- * @see BlurEvent
- */
- public interface BlurNotifier extends Serializable {
- /**
- * Adds a <code>BlurListener</code> to the Component which gets fired
- * when a <code>Field</code> loses keyboard focus.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void addListener(BlurListener listener);
-
- /**
- * Removes a <code>BlurListener</code> from the Component.
- *
- * @param listener
- * @see BlurListener
- * @since 6.2
- */
- public void removeListener(BlurListener listener);
- }
-
- /**
- * <code>FocusEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> receives keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class FocusEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.FOCUS;
-
- public FocusEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>FocusListener</code> interface for listening for
- * <code>FocusEvent</code> fired by a <code>Field</code>.
- *
- * @see FocusEvent
- * @since 6.2
- */
- public interface FocusListener extends ComponentEventListener {
-
- public static final Method focusMethod = ReflectTools.findMethod(
- FocusListener.class, "focus", FocusEvent.class);
-
- /**
- * Component has been focused
- *
- * @param event
- * Component focus event.
- */
- public void focus(FocusEvent event);
- }
-
- /**
- * <code>BlurEvent</code> class for holding additional event information.
- * Fired when a <code>Field</code> loses keyboard focus.
- *
- * @since 6.2
- */
- @SuppressWarnings("serial")
- public class BlurEvent extends Component.Event {
-
- /**
- * Identifier for event that can be used in {@link EventRouter}
- */
- public static final String EVENT_ID = EventId.BLUR;
-
- public BlurEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>BlurListener</code> interface for listening for
- * <code>BlurEvent</code> fired by a <code>Field</code>.
- *
- * @see BlurEvent
- * @since 6.2
- */
- public interface BlurListener extends ComponentEventListener {
-
- public static final Method blurMethod = ReflectTools.findMethod(
- BlurListener.class, "blur", BlurEvent.class);
-
- /**
- * Component has been blurred
- *
- * @param event
- * Component blur event.
- */
- public void blur(BlurEvent event);
- }
-
- /**
- * TextChangeEvents are fired when the user is editing the text content of a
- * field. Most commonly text change events are triggered by typing text with
- * keyboard, but e.g. pasting content from clip board to a text field also
- * triggers an event.
- * <p>
- * TextChangeEvents differ from {@link ValueChangeEvent}s so that they are
- * triggered repeatedly while the end user is filling the field.
- * ValueChangeEvents are not fired until the user for example hits enter or
- * focuses another field. Also note the difference that TextChangeEvents are
- * only fired if the change is triggered from the user, while
- * ValueChangeEvents are also fired if the field value is set by the
- * application code.
- * <p>
- * The {@link TextChangeNotifier}s implementation may decide when exactly
- * TextChangeEvents are fired. TextChangeEvents are not necessary fire for
- * example on each key press, but buffered with a small delay. The
- * {@link TextField} component supports different modes for triggering
- * TextChangeEvents.
- *
- * @see TextChangeListener
- * @see TextChangeNotifier
- * @see TextField#setTextChangeEventMode(com.vaadin.ui.TextField.TextChangeEventMode)
- * @since 6.5
- */
- public static abstract class TextChangeEvent extends Component.Event {
- public TextChangeEvent(Component source) {
- super(source);
- }
-
- /**
- * @return the text content of the field after the
- * {@link TextChangeEvent}
- */
- public abstract String getText();
-
- /**
- * @return the cursor position during after the {@link TextChangeEvent}
- */
- public abstract int getCursorPosition();
- }
-
- /**
- * A listener for {@link TextChangeEvent}s.
- *
- * @since 6.5
- */
- public interface TextChangeListener extends ComponentEventListener {
-
- public static String EVENT_ID = "ie";
- public static Method EVENT_METHOD = ReflectTools.findMethod(
- TextChangeListener.class, "textChange", TextChangeEvent.class);
-
- /**
- * This method is called repeatedly while the text is edited by a user.
- *
- * @param event
- * the event providing details of the text change
- */
- public void textChange(TextChangeEvent event);
- }
-
- /**
- * An interface implemented by a {@link Field} supporting
- * {@link TextChangeEvent}s. An example a {@link TextField} supports
- * {@link TextChangeListener}s.
- */
- public interface TextChangeNotifier extends Serializable {
- public void addListener(TextChangeListener listener);
-
- public void removeListener(TextChangeListener listener);
- }
-
- public static abstract class FocusAndBlurServerRpcImpl implements
- FocusAndBlurServerRpc {
-
- private Component component;
-
- public FocusAndBlurServerRpcImpl(Component component) {
- this.component = component;
- }
-
- protected abstract void fireEvent(Event event);
-
- @Override
- public void blur() {
- fireEvent(new BlurEvent(component));
- }
-
- @Override
- public void focus() {
- fireEvent(new FocusEvent(component));
- }
- };
-
-}
diff --git a/src/com/vaadin/event/ItemClickEvent.java b/src/com/vaadin/event/ItemClickEvent.java
deleted file mode 100644
index 0aa0e106c5..0000000000
--- a/src/com/vaadin/event/ItemClickEvent.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.ui.Component;
-
-/**
- *
- * Click event fired by a {@link Component} implementing
- * {@link com.vaadin.data.Container} interface. ItemClickEvents happens on an
- * {@link Item} rendered somehow on terminal. Event may also contain a specific
- * {@link Property} on which the click event happened.
- *
- * @since 5.3
- *
- */
-@SuppressWarnings("serial")
-public class ItemClickEvent extends ClickEvent implements Serializable {
- private Item item;
- private Object itemId;
- private Object propertyId;
-
- public ItemClickEvent(Component source, Item item, Object itemId,
- Object propertyId, MouseEventDetails details) {
- super(source, details);
- this.item = item;
- this.itemId = itemId;
- this.propertyId = propertyId;
- }
-
- /**
- * Gets the item on which the click event occurred.
- *
- * @return item which was clicked
- */
- public Item getItem() {
- return item;
- }
-
- /**
- * Gets a possible identifier in source for clicked Item
- *
- * @return
- */
- public Object getItemId() {
- return itemId;
- }
-
- /**
- * Returns property on which click event occurred. Returns null if source
- * cannot be resolved at property leve. For example if clicked a cell in
- * table, the "column id" is returned.
- *
- * @return a property id of clicked property or null if click didn't occur
- * on any distinct property.
- */
- public Object getPropertyId() {
- return propertyId;
- }
-
- public static final Method ITEM_CLICK_METHOD;
-
- static {
- try {
- ITEM_CLICK_METHOD = ItemClickListener.class.getDeclaredMethod(
- "itemClick", new Class[] { ItemClickEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException();
- }
- }
-
- public interface ItemClickListener extends Serializable {
- public void itemClick(ItemClickEvent event);
- }
-
- /**
- * The interface for adding and removing <code>ItemClickEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate an <code>ItemClickEvent</code> when one of its
- * items is clicked.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.5
- * @see ItemClickListener
- * @see ItemClickEvent
- */
- public interface ItemClickNotifier extends Serializable {
- /**
- * Register a listener to handle {@link ItemClickEvent}s.
- *
- * @param listener
- * ItemClickListener to be registered
- */
- public void addListener(ItemClickListener listener);
-
- /**
- * Removes an ItemClickListener.
- *
- * @param listener
- * ItemClickListener to be removed
- */
- public void removeListener(ItemClickListener listener);
- }
-
-}
diff --git a/src/com/vaadin/event/LayoutEvents.java b/src/com/vaadin/event/LayoutEvents.java
deleted file mode 100644
index 602440ea07..0000000000
--- a/src/com/vaadin/event/LayoutEvents.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-
-public interface LayoutEvents {
-
- public interface LayoutClickListener extends ComponentEventListener {
-
- public static final Method clickMethod = ReflectTools.findMethod(
- LayoutClickListener.class, "layoutClick",
- LayoutClickEvent.class);
-
- /**
- * Layout has been clicked
- *
- * @param event
- * Component click event.
- */
- public void layoutClick(LayoutClickEvent event);
- }
-
- /**
- * The interface for adding and removing <code>LayoutClickEvent</code>
- * listeners. By implementing this interface a class explicitly announces
- * that it will generate a <code>LayoutClickEvent</code> when a component
- * inside it is clicked and a <code>LayoutClickListener</code> is
- * registered.
- * <p>
- * Note: The general Java convention is not to explicitly declare that a
- * class generates events, but to directly define the
- * <code>addListener</code> and <code>removeListener</code> methods. That
- * way the caller of these methods has no real way of finding out if the
- * class really will send the events, or if it just defines the methods to
- * be able to implement an interface.
- * </p>
- *
- * @since 6.5.2
- * @see LayoutClickListener
- * @see LayoutClickEvent
- */
- public interface LayoutClickNotifier extends Serializable {
- /**
- * Add a click listener to the layout. The listener is called whenever
- * the user clicks inside the layout. An event is also triggered when
- * the click targets a component inside a nested layout or Panel,
- * provided the targeted component does not prevent the click event from
- * propagating. A caption is not considered part of a component.
- *
- * The child component that was clicked is included in the
- * {@link LayoutClickEvent}.
- *
- * Use {@link #removeListener(LayoutClickListener)} to remove the
- * listener.
- *
- * @param listener
- * The listener to add
- */
- public void addListener(LayoutClickListener listener);
-
- /**
- * Removes an LayoutClickListener.
- *
- * @param listener
- * LayoutClickListener to be removed
- */
- public void removeListener(LayoutClickListener listener);
- }
-
- /**
- * An event fired when the layout has been clicked. The event contains
- * information about the target layout (component) and the child component
- * that was clicked. If no child component was found it is set to null.
- */
- public static class LayoutClickEvent extends ClickEvent {
-
- private final Component clickedComponent;
- private final Component childComponent;
-
- public LayoutClickEvent(Component source,
- MouseEventDetails mouseEventDetails,
- Component clickedComponent, Component childComponent) {
- super(source, mouseEventDetails);
- this.clickedComponent = clickedComponent;
- this.childComponent = childComponent;
- }
-
- /**
- * Returns the component that was clicked, which is somewhere inside the
- * parent layout on which the listener was registered.
- *
- * For the direct child component of the layout, see
- * {@link #getChildComponent()}.
- *
- * @return clicked {@link Component}, null if none found
- */
- public Component getClickedComponent() {
- return clickedComponent;
- }
-
- /**
- * Returns the direct child component of the layout which contains the
- * clicked component.
- *
- * For the clicked component inside that child component of the layout,
- * see {@link #getClickedComponent()}.
- *
- * @return direct child {@link Component} of the layout which contains
- * the clicked Component, null if none found
- */
- public Component getChildComponent() {
- return childComponent;
- }
-
- public static LayoutClickEvent createEvent(ComponentContainer layout,
- MouseEventDetails mouseDetails, Connector clickedConnector) {
- Component clickedComponent = (Component) clickedConnector;
- Component childComponent = clickedComponent;
- while (childComponent != null
- && childComponent.getParent() != layout) {
- childComponent = childComponent.getParent();
- }
-
- return new LayoutClickEvent(layout, mouseDetails, clickedComponent,
- childComponent);
- }
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/ListenerMethod.java b/src/com/vaadin/event/ListenerMethod.java
deleted file mode 100644
index f7dc8a7f13..0000000000
--- a/src/com/vaadin/event/ListenerMethod.java
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.EventListener;
-import java.util.EventObject;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * <p>
- * One registered event listener. This class contains the listener object
- * reference, listened event type, the trigger method to call when the event
- * fires, and the optional argument list to pass to the method and the index of
- * the argument to replace with the event object.
- * </p>
- *
- * <p>
- * This Class provides several constructors that allow omission of the optional
- * arguments, and giving the listener method directly, or having the constructor
- * to reflect it using merely the name of the method.
- * </p>
- *
- * <p>
- * It should be pointed out that the method
- * {@link #receiveEvent(EventObject event)} is the one that filters out the
- * events that do not match with the given event type and thus do not result in
- * calling of the trigger method.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ListenerMethod implements EventListener, Serializable {
-
- /**
- * Type of the event that should trigger this listener. Also the subclasses
- * of this class are accepted to trigger the listener.
- */
- private final Class<?> eventType;
-
- /**
- * The object containing the trigger method.
- */
- private final Object target;
-
- /**
- * The trigger method to call when an event passing the given criteria
- * fires.
- */
- private transient Method method;
-
- /**
- * Optional argument set to pass to the trigger method.
- */
- private Object[] arguments;
-
- /**
- * Optional index to <code>arguments</code> that point out which one should
- * be replaced with the triggering event object and thus be passed to the
- * trigger method.
- */
- private int eventArgumentIndex;
-
- /* Special serialization to handle method references */
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- try {
- out.defaultWriteObject();
- String name = method.getName();
- Class<?>[] paramTypes = method.getParameterTypes();
- out.writeObject(name);
- out.writeObject(paramTypes);
- } catch (NotSerializableException e) {
- getLogger().warning(
- "Error in serialization of the application: Class "
- + target.getClass().getName()
- + " must implement serialization.");
- throw e;
- }
-
- };
-
- /* Special serialization to handle method references */
- private void readObject(java.io.ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- in.defaultReadObject();
- try {
- String name = (String) in.readObject();
- Class<?>[] paramTypes = (Class<?>[]) in.readObject();
- // We can not use getMethod directly as we want to support anonymous
- // inner classes
- method = findHighestMethod(target.getClass(), name, paramTypes);
- } catch (SecurityException e) {
- getLogger().log(Level.SEVERE, "Internal deserialization error", e);
- }
- };
-
- private static Method findHighestMethod(Class<?> cls, String method,
- Class<?>[] paramTypes) {
- Class<?>[] ifaces = cls.getInterfaces();
- for (int i = 0; i < ifaces.length; i++) {
- Method ifaceMethod = findHighestMethod(ifaces[i], method,
- paramTypes);
- if (ifaceMethod != null) {
- return ifaceMethod;
- }
- }
- if (cls.getSuperclass() != null) {
- Method parentMethod = findHighestMethod(cls.getSuperclass(),
- method, paramTypes);
- if (parentMethod != null) {
- return parentMethod;
- }
- }
- Method[] methods = cls.getMethods();
- for (int i = 0; i < methods.length; i++) {
- // we ignore parameter types for now - you need to add this
- if (methods[i].getName().equals(method)) {
- return methods[i];
- }
- }
- return null;
- }
-
- /**
- * <p>
- * Constructs a new event listener from a trigger method, it's arguments and
- * the argument index specifying which one is replaced with the event object
- * when the trigger method is called.
- * </p>
- *
- * <p>
- * This constructor gets the trigger method as a parameter so it does not
- * need to reflect to find it out.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method
- * @param method
- * the trigger method
- * @param arguments
- * the arguments to be passed to the trigger method
- * @param eventArgumentIndex
- * An index to the argument list. This index points out the
- * argument that is replaced with the event object before the
- * argument set is passed to the trigger method. If the
- * eventArgumentIndex is negative, the triggering event object
- * will not be passed to the trigger method, though it is still
- * called.
- * @throws java.lang.IllegalArgumentException
- * if <code>method</code> is not a member of <code>target</code>
- * .
- */
- public ListenerMethod(Class<?> eventType, Object target, Method method,
- Object[] arguments, int eventArgumentIndex)
- throws java.lang.IllegalArgumentException {
-
- // Checks that the object is of correct type
- if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) {
- throw new java.lang.IllegalArgumentException("The method "
- + method.getName()
- + " cannot be used for the given target: "
- + target.getClass().getName());
- }
-
- // Checks that the event argument is null
- if (eventArgumentIndex >= 0 && arguments[eventArgumentIndex] != null) {
- throw new java.lang.IllegalArgumentException("argument["
- + eventArgumentIndex + "] must be null");
- }
-
- // Checks the event type is supported by the method
- if (eventArgumentIndex >= 0
- && !method.getParameterTypes()[eventArgumentIndex]
- .isAssignableFrom(eventType)) {
- throw new java.lang.IllegalArgumentException("The method "
- + method.getName()
- + " does not accept the given eventType: "
- + eventType.getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- this.arguments = arguments;
- this.eventArgumentIndex = eventArgumentIndex;
- }
-
- /**
- * <p>
- * Constructs a new event listener from a trigger method name, it's
- * arguments and the argument index specifying which one is replaced with
- * the event object. The actual trigger method is reflected from
- * <code>object</code>, and <code>java.lang.IllegalArgumentException</code>
- * is thrown unless exactly one match is found.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method.
- * @param methodName
- * the name of the trigger method. If the object does not contain
- * the method or it contains more than one matching methods
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * @param arguments
- * the arguments to be passed to the trigger method.
- * @param eventArgumentIndex
- * An index to the argument list. This index points out the
- * argument that is replaced with the event object before the
- * argument set is passed to the trigger method. If the
- * eventArgumentIndex is negative, the triggering event object
- * will not be passed to the trigger method, though it is still
- * called.
- * @throws java.lang.IllegalArgumentException
- * unless exactly one match <code>methodName</code> is found in
- * <code>target</code>.
- */
- public ListenerMethod(Class<?> eventType, Object target, String methodName,
- Object[] arguments, int eventArgumentIndex)
- throws java.lang.IllegalArgumentException {
-
- // Finds the correct method
- final Method[] methods = target.getClass().getMethods();
- Method method = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().equals(methodName)) {
- method = methods[i];
- }
- }
- if (method == null) {
- throw new IllegalArgumentException("Method " + methodName
- + " not found in class " + target.getClass().getName());
- }
-
- // Checks that the event argument is null
- if (eventArgumentIndex >= 0 && arguments[eventArgumentIndex] != null) {
- throw new java.lang.IllegalArgumentException("argument["
- + eventArgumentIndex + "] must be null");
- }
-
- // Checks the event type is supported by the method
- if (eventArgumentIndex >= 0
- && !method.getParameterTypes()[eventArgumentIndex]
- .isAssignableFrom(eventType)) {
- throw new java.lang.IllegalArgumentException("The method "
- + method.getName()
- + " does not accept the given eventType: "
- + eventType.getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- this.arguments = arguments;
- this.eventArgumentIndex = eventArgumentIndex;
- }
-
- /**
- * <p>
- * Constructs a new event listener from the trigger method and it's
- * arguments. Since the the index to the replaced parameter is not specified
- * the event triggering this listener will not be passed to the trigger
- * method.
- * </p>
- *
- * <p>
- * This constructor gets the trigger method as a parameter so it does not
- * need to reflect to find it out.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method.
- * @param method
- * the trigger method.
- * @param arguments
- * the arguments to be passed to the trigger method.
- * @throws java.lang.IllegalArgumentException
- * if <code>method</code> is not a member of <code>target</code>
- * .
- */
- public ListenerMethod(Class<?> eventType, Object target, Method method,
- Object[] arguments) throws java.lang.IllegalArgumentException {
-
- // Check that the object is of correct type
- if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) {
- throw new java.lang.IllegalArgumentException("The method "
- + method.getName()
- + " cannot be used for the given target: "
- + target.getClass().getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- this.arguments = arguments;
- eventArgumentIndex = -1;
- }
-
- /**
- * <p>
- * Constructs a new event listener from a trigger method name and it's
- * arguments. Since the the index to the replaced parameter is not specified
- * the event triggering this listener will not be passed to the trigger
- * method.
- * </p>
- *
- * <p>
- * The actual trigger method is reflected from <code>target</code>, and
- * <code>java.lang.IllegalArgumentException</code> is thrown unless exactly
- * one match is found.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method.
- * @param methodName
- * the name of the trigger method. If the object does not contain
- * the method or it contains more than one matching methods
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * @param arguments
- * the arguments to be passed to the trigger method.
- * @throws java.lang.IllegalArgumentException
- * unless exactly one match <code>methodName</code> is found in
- * <code>object</code>.
- */
- public ListenerMethod(Class<?> eventType, Object target, String methodName,
- Object[] arguments) throws java.lang.IllegalArgumentException {
-
- // Find the correct method
- final Method[] methods = target.getClass().getMethods();
- Method method = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().equals(methodName)) {
- method = methods[i];
- }
- }
- if (method == null) {
- throw new IllegalArgumentException("Method " + methodName
- + " not found in class " + target.getClass().getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- this.arguments = arguments;
- eventArgumentIndex = -1;
- }
-
- /**
- * <p>
- * Constructs a new event listener from a trigger method. Since the argument
- * list is unspecified no parameters are passed to the trigger method when
- * the listener is triggered.
- * </p>
- *
- * <p>
- * This constructor gets the trigger method as a parameter so it does not
- * need to reflect to find it out.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method.
- * @param method
- * the trigger method.
- * @throws java.lang.IllegalArgumentException
- * if <code>method</code> is not a member of <code>object</code>
- * .
- */
- public ListenerMethod(Class<?> eventType, Object target, Method method)
- throws java.lang.IllegalArgumentException {
-
- // Checks that the object is of correct type
- if (!method.getDeclaringClass().isAssignableFrom(target.getClass())) {
- throw new java.lang.IllegalArgumentException("The method "
- + method.getName()
- + " cannot be used for the given target: "
- + target.getClass().getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- eventArgumentIndex = -1;
-
- final Class<?>[] params = method.getParameterTypes();
-
- if (params.length == 0) {
- arguments = new Object[0];
- } else if (params.length == 1 && params[0].isAssignableFrom(eventType)) {
- arguments = new Object[] { null };
- eventArgumentIndex = 0;
- } else {
- throw new IllegalArgumentException(
- "Method requires unknown parameters");
- }
- }
-
- /**
- * <p>
- * Constructs a new event listener from a trigger method name. Since the
- * argument list is unspecified no parameters are passed to the trigger
- * method when the listener is triggered.
- * </p>
- *
- * <p>
- * The actual trigger method is reflected from <code>object</code>, and
- * <code>java.lang.IllegalArgumentException</code> is thrown unless exactly
- * one match is found.
- * </p>
- *
- * @param eventType
- * the event type that is listener listens to. All events of this
- * kind (or its subclasses) result in calling the trigger method.
- * @param target
- * the object instance that contains the trigger method.
- * @param methodName
- * the name of the trigger method. If the object does not contain
- * the method or it contains more than one matching methods
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * @throws java.lang.IllegalArgumentException
- * unless exactly one match <code>methodName</code> is found in
- * <code>target</code>.
- */
- public ListenerMethod(Class<?> eventType, Object target, String methodName)
- throws java.lang.IllegalArgumentException {
-
- // Finds the correct method
- final Method[] methods = target.getClass().getMethods();
- Method method = null;
- for (int i = 0; i < methods.length; i++) {
- if (methods[i].getName().equals(methodName)) {
- method = methods[i];
- }
- }
- if (method == null) {
- throw new IllegalArgumentException("Method " + methodName
- + " not found in class " + target.getClass().getName());
- }
-
- this.eventType = eventType;
- this.target = target;
- this.method = method;
- eventArgumentIndex = -1;
-
- final Class<?>[] params = method.getParameterTypes();
-
- if (params.length == 0) {
- arguments = new Object[0];
- } else if (params.length == 1 && params[0].isAssignableFrom(eventType)) {
- arguments = new Object[] { null };
- eventArgumentIndex = 0;
- } else {
- throw new IllegalArgumentException(
- "Method requires unknown parameters");
- }
- }
-
- /**
- * Receives one event from the <code>EventRouter</code> and calls the
- * trigger method if it matches with the criteria defined for the listener.
- * Only the events of the same or subclass of the specified event class
- * result in the trigger method to be called.
- *
- * @param event
- * the fired event. Unless the trigger method's argument list and
- * the index to the to be replaced argument is specified, this
- * event will not be passed to the trigger method.
- */
- public void receiveEvent(EventObject event) {
- // Only send events supported by the method
- if (eventType.isAssignableFrom(event.getClass())) {
- try {
- if (eventArgumentIndex >= 0) {
- if (eventArgumentIndex == 0 && arguments.length == 1) {
- method.invoke(target, new Object[] { event });
- } else {
- final Object[] arg = new Object[arguments.length];
- for (int i = 0; i < arg.length; i++) {
- arg[i] = arguments[i];
- }
- arg[eventArgumentIndex] = event;
- method.invoke(target, arg);
- }
- } else {
- method.invoke(target, arguments);
- }
-
- } catch (final java.lang.IllegalAccessException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error - please report", e);
- } catch (final java.lang.reflect.InvocationTargetException e) {
- // An exception was thrown by the invocation target. Throw it
- // forwards.
- throw new MethodException("Invocation of method "
- + method.getName() + " in "
- + target.getClass().getName() + " failed.",
- e.getTargetException());
- }
- }
- }
-
- /**
- * Checks if the given object and event match with the ones stored in this
- * listener.
- *
- * @param target
- * the object to be matched against the object stored by this
- * listener.
- * @param eventType
- * the type to be tested for equality against the type stored by
- * this listener.
- * @return <code>true</code> if <code>target</code> is the same object as
- * the one stored in this object and <code>eventType</code> equals
- * the event type stored in this object. *
- */
- public boolean matches(Class<?> eventType, Object target) {
- return (this.target == target) && (eventType.equals(this.eventType));
- }
-
- /**
- * Checks if the given object, event and method match with the ones stored
- * in this listener.
- *
- * @param target
- * the object to be matched against the object stored by this
- * listener.
- * @param eventType
- * the type to be tested for equality against the type stored by
- * this listener.
- * @param method
- * the method to be tested for equality against the method stored
- * by this listener.
- * @return <code>true</code> if <code>target</code> is the same object as
- * the one stored in this object, <code>eventType</code> equals with
- * the event type stored in this object and <code>method</code>
- * equals with the method stored in this object
- */
- public boolean matches(Class<?> eventType, Object target, Method method) {
- return (this.target == target)
- && (eventType.equals(this.eventType) && method
- .equals(this.method));
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
-
- hash = 31 * hash + eventArgumentIndex;
- hash = 31 * hash + (eventType == null ? 0 : eventType.hashCode());
- hash = 31 * hash + (target == null ? 0 : target.hashCode());
- hash = 31 * hash + (method == null ? 0 : method.hashCode());
-
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
-
- if (this == obj) {
- return true;
- }
-
- // return false if obj is a subclass (do not use instanceof check)
- if ((obj == null) || (obj.getClass() != getClass())) {
- return false;
- }
-
- // obj is of same class, test it further
- ListenerMethod t = (ListenerMethod) obj;
-
- return eventArgumentIndex == t.eventArgumentIndex
- && (eventType == t.eventType || (eventType != null && eventType
- .equals(t.eventType)))
- && (target == t.target || (target != null && target
- .equals(t.target)))
- && (method == t.method || (method != null && method
- .equals(t.method)))
- && (arguments == t.arguments || (Arrays.equals(arguments,
- t.arguments)));
- }
-
- /**
- * Exception that wraps an exception thrown by an invoked method. When
- * <code>ListenerMethod</code> invokes the target method, it may throw
- * arbitrary exception. The original exception is wrapped into
- * MethodException instance and rethrown by the <code>ListenerMethod</code>.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class MethodException extends RuntimeException implements
- Serializable {
-
- private MethodException(String message, Throwable cause) {
- super(message, cause);
- }
-
- }
-
- /**
- * Compares the type of this ListenerMethod to the given type
- *
- * @param eventType
- * The type to compare with
- * @return true if this type of this ListenerMethod matches the given type,
- * false otherwise
- */
- public boolean isType(Class<?> eventType) {
- return this.eventType == eventType;
- }
-
- /**
- * Compares the type of this ListenerMethod to the given type
- *
- * @param eventType
- * The type to compare with
- * @return true if this event type can be assigned to the given type, false
- * otherwise
- */
- public boolean isOrExtendsType(Class<?> eventType) {
- return eventType.isAssignableFrom(this.eventType);
- }
-
- /**
- * Returns the target object which contains the trigger method.
- *
- * @return The target object
- */
- public Object getTarget() {
- return target;
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(ListenerMethod.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/event/MethodEventSource.java b/src/com/vaadin/event/MethodEventSource.java
deleted file mode 100644
index fb2e7b029b..0000000000
--- a/src/com/vaadin/event/MethodEventSource.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-/**
- * <p>
- * Interface for classes supporting registration of methods as event receivers.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface MethodEventSource extends Serializable {
-
- /**
- * <p>
- * Registers a new event listener with the specified activation method to
- * listen events generated by this component. If the activation method does
- * not have any arguments the event object will not be passed to it when
- * it's called.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the type of the listened event. Events of this type or its
- * subclasses activate the listener.
- * @param object
- * the object instance who owns the activation method.
- * @param method
- * the activation method.
- * @throws java.lang.IllegalArgumentException
- * unless <code>method</code> has exactly one match in
- * <code>object</code>
- */
- public void addListener(Class<?> eventType, Object object, Method method);
-
- /**
- * <p>
- * Registers a new listener with the specified activation method to listen
- * events generated by this component. If the activation method does not
- * have any arguments the event object will not be passed to it when it's
- * called.
- * </p>
- *
- * <p>
- * This version of <code>addListener</code> gets the name of the activation
- * method as a parameter. The actual method is reflected from
- * <code>object</code>, and unless exactly one match is found,
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the type of the listened event. Events of this type or its
- * subclasses activate the listener.
- * @param object
- * the object instance who owns the activation method.
- * @param methodName
- * the name of the activation method.
- * @throws java.lang.IllegalArgumentException
- * unless <code>method</code> has exactly one match in
- * <code>object</code>
- */
- public void addListener(Class<?> eventType, Object object, String methodName);
-
- /**
- * Removes all registered listeners matching the given parameters. Since
- * this method receives the event type and the listener object as
- * parameters, it will unregister all <code>object</code>'s methods that are
- * registered to listen to events of type <code>eventType</code> generated
- * by this component.
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type <code>eventType</code> with one or more methods.
- */
- public void removeListener(Class<?> eventType, Object target);
-
- /**
- * Removes one registered listener method. The given method owned by the
- * given object will no longer be called when the specified events are
- * generated by this component.
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type eventType with one or more methods.
- * @param method
- * the method owned by the target that's registered to listen to
- * events of type eventType.
- */
- public void removeListener(Class<?> eventType, Object target, Method method);
-
- /**
- * <p>
- * Removes one registered listener method. The given method owned by the
- * given object will no longer be called when the specified events are
- * generated by this component.
- * </p>
- *
- * <p>
- * This version of <code>removeListener</code> gets the name of the
- * activation method as a parameter. The actual method is reflected from the
- * target, and unless exactly one match is found,
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type <code>eventType</code> with one or more methods.
- * @param methodName
- * the name of the method owned by <code>target</code> that's
- * registered to listen to events of type <code>eventType</code>.
- */
- public void removeListener(Class<?> eventType, Object target,
- String methodName);
-}
diff --git a/src/com/vaadin/event/MouseEvents.java b/src/com/vaadin/event/MouseEvents.java
deleted file mode 100644
index fafd44be89..0000000000
--- a/src/com/vaadin/event/MouseEvents.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.lang.reflect.Method;
-
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component;
-
-/**
- * Interface that serves as a wrapper for mouse related events.
- *
- * @author Vaadin Ltd.
- * @see ClickListener
- * @version
- * @VERSION@
- * @since 6.2
- */
-public interface MouseEvents {
-
- /**
- * Class for holding information about a mouse click event. A
- * {@link ClickEvent} is fired when the user clicks on a
- * <code>Component</code>.
- *
- * The information available for click events are terminal dependent.
- * Correct values for all event details cannot be guaranteed.
- *
- * @author Vaadin Ltd.
- * @see ClickListener
- * @version
- * @VERSION@
- * @since 6.2
- */
- public class ClickEvent extends Component.Event {
- public static final int BUTTON_LEFT = MouseEventDetails.BUTTON_LEFT;
- public static final int BUTTON_MIDDLE = MouseEventDetails.BUTTON_MIDDLE;
- public static final int BUTTON_RIGHT = MouseEventDetails.BUTTON_RIGHT;
-
- private MouseEventDetails details;
-
- public ClickEvent(Component source, MouseEventDetails mouseEventDetails) {
- super(source);
- details = mouseEventDetails;
- }
-
- /**
- * Returns an identifier describing which mouse button the user pushed.
- * Compare with {@link #BUTTON_LEFT},{@link #BUTTON_MIDDLE},
- * {@link #BUTTON_RIGHT} to find out which butten it is.
- *
- * @return one of {@link #BUTTON_LEFT}, {@link #BUTTON_MIDDLE},
- * {@link #BUTTON_RIGHT}.
- */
- public int getButton() {
- return details.getButton();
- }
-
- /**
- * Returns the mouse position (x coordinate) when the click took place.
- * The position is relative to the browser client area.
- *
- * @return The mouse cursor x position
- */
- public int getClientX() {
- return details.getClientX();
- }
-
- /**
- * Returns the mouse position (y coordinate) when the click took place.
- * The position is relative to the browser client area.
- *
- * @return The mouse cursor y position
- */
- public int getClientY() {
- return details.getClientY();
- }
-
- /**
- * Returns the relative mouse position (x coordinate) when the click
- * took place. The position is relative to the clicked component.
- *
- * @return The mouse cursor x position relative to the clicked layout
- * component or -1 if no x coordinate available
- */
- public int getRelativeX() {
- return details.getRelativeX();
- }
-
- /**
- * Returns the relative mouse position (y coordinate) when the click
- * took place. The position is relative to the clicked component.
- *
- * @return The mouse cursor y position relative to the clicked layout
- * component or -1 if no y coordinate available
- */
- public int getRelativeY() {
- return details.getRelativeY();
- }
-
- /**
- * Checks if the event is a double click event.
- *
- * @return true if the event is a double click event, false otherwise
- */
- public boolean isDoubleClick() {
- return details.isDoubleClick();
- }
-
- /**
- * Checks if the Alt key was down when the mouse event took place.
- *
- * @return true if Alt was down when the event occured, false otherwise
- */
- public boolean isAltKey() {
- return details.isAltKey();
- }
-
- /**
- * Checks if the Ctrl key was down when the mouse event took place.
- *
- * @return true if Ctrl was pressed when the event occured, false
- * otherwise
- */
- public boolean isCtrlKey() {
- return details.isCtrlKey();
- }
-
- /**
- * Checks if the Meta key was down when the mouse event took place.
- *
- * @return true if Meta was pressed when the event occured, false
- * otherwise
- */
- public boolean isMetaKey() {
- return details.isMetaKey();
- }
-
- /**
- * Checks if the Shift key was down when the mouse event took place.
- *
- * @return true if Shift was pressed when the event occured, false
- * otherwise
- */
- public boolean isShiftKey() {
- return details.isShiftKey();
- }
-
- /**
- * Returns a human readable string representing which button has been
- * pushed. This is meant for debug purposes only and the string returned
- * could change. Use {@link #getButton()} to check which button was
- * pressed.
- *
- * @since 6.3
- * @return A string representation of which button was pushed.
- */
- public String getButtonName() {
- return details.getButtonName();
- }
- }
-
- /**
- * Interface for listening for a {@link ClickEvent} fired by a
- * {@link Component}.
- *
- * @see ClickEvent
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.2
- */
- public interface ClickListener extends ComponentEventListener {
-
- public static final Method clickMethod = ReflectTools.findMethod(
- ClickListener.class, "click", ClickEvent.class);
-
- /**
- * Called when a {@link Component} has been clicked. A reference to the
- * component is given by {@link ClickEvent#getComponent()}.
- *
- * @param event
- * An event containing information about the click.
- */
- public void click(ClickEvent event);
- }
-
- /**
- * Class for holding additional event information for DoubleClick events.
- * Fired when the user double-clicks on a <code>Component</code>.
- *
- * @see ClickEvent
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.2
- */
- public class DoubleClickEvent extends Component.Event {
-
- public DoubleClickEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * Interface for listening for a {@link DoubleClickEvent} fired by a
- * {@link Component}.
- *
- * @see DoubleClickEvent
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.2
- */
- public interface DoubleClickListener extends ComponentEventListener {
-
- public static final Method doubleClickMethod = ReflectTools.findMethod(
- DoubleClickListener.class, "doubleClick",
- DoubleClickEvent.class);
-
- /**
- * Called when a {@link Component} has been double clicked. A reference
- * to the component is given by {@link DoubleClickEvent#getComponent()}.
- *
- * @param event
- * An event containing information about the double click.
- */
- public void doubleClick(DoubleClickEvent event);
- }
-
-}
diff --git a/src/com/vaadin/event/ShortcutAction.java b/src/com/vaadin/event/ShortcutAction.java
deleted file mode 100644
index c42dd731c8..0000000000
--- a/src/com/vaadin/event/ShortcutAction.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.vaadin.terminal.Resource;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.Window;
-
-/**
- * Shortcuts are a special type of {@link Action}s used to create keyboard
- * shortcuts.
- * <p>
- * The ShortcutAction is triggered when the user presses a given key in
- * combination with the (optional) given modifier keys.
- * </p>
- * <p>
- * ShortcutActions can be global (by attaching to the {@link Window}), or
- * attached to different parts of the UI so that a specific shortcut is only
- * valid in part of the UI. For instance, one can attach shortcuts to a specific
- * {@link Panel} - look for {@link ComponentContainer}s implementing
- * {@link Handler Action.Handler} or {@link Notifier Action.Notifier}.
- * </p>
- * <p>
- * ShortcutActions have a caption that may be used to display the shortcut
- * visually. This allows the ShortcutAction to be used as a plain Action while
- * still reacting to a keyboard shortcut. Note that this functionality is not
- * very well supported yet, but it might still be a good idea to give a caption
- * to the shortcut.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @since 4.0.1
- */
-@SuppressWarnings("serial")
-public class ShortcutAction extends Action {
-
- private final int keyCode;
-
- private final int[] modifiers;
-
- /**
- * Creates a shortcut that reacts to the given {@link KeyCode} and
- * (optionally) {@link ModifierKey}s. <br/>
- * The shortcut might be shown in the UI (e.g context menu), in which case
- * the caption will be used.
- *
- * @param caption
- * used when displaying the shortcut visually
- * @param kc
- * KeyCode that the shortcut reacts to
- * @param m
- * optional modifier keys
- */
- public ShortcutAction(String caption, int kc, int[] m) {
- super(caption);
- keyCode = kc;
- modifiers = m;
- }
-
- /**
- * Creates a shortcut that reacts to the given {@link KeyCode} and
- * (optionally) {@link ModifierKey}s. <br/>
- * The shortcut might be shown in the UI (e.g context menu), in which case
- * the caption and icon will be used.
- *
- * @param caption
- * used when displaying the shortcut visually
- * @param icon
- * used when displaying the shortcut visually
- * @param kc
- * KeyCode that the shortcut reacts to
- * @param m
- * optional modifier keys
- */
- public ShortcutAction(String caption, Resource icon, int kc, int[] m) {
- super(caption, icon);
- keyCode = kc;
- modifiers = m;
- }
-
- /**
- * Used in the caption shorthand notation to indicate the ALT modifier.
- */
- public static final char SHORTHAND_CHAR_ALT = '&';
- /**
- * Used in the caption shorthand notation to indicate the SHIFT modifier.
- */
- public static final char SHORTHAND_CHAR_SHIFT = '_';
- /**
- * Used in the caption shorthand notation to indicate the CTRL modifier.
- */
- public static final char SHORTHAND_CHAR_CTRL = '^';
-
- // regex-quote (escape) the characters
- private static final String SHORTHAND_ALT = Pattern.quote(Character
- .toString(SHORTHAND_CHAR_ALT));
- private static final String SHORTHAND_SHIFT = Pattern.quote(Character
- .toString(SHORTHAND_CHAR_SHIFT));
- private static final String SHORTHAND_CTRL = Pattern.quote(Character
- .toString(SHORTHAND_CHAR_CTRL));
- // Used for replacing escaped chars, e.g && with &
- private static final Pattern SHORTHAND_ESCAPE = Pattern.compile("("
- + SHORTHAND_ALT + "?)" + SHORTHAND_ALT + "|(" + SHORTHAND_SHIFT
- + "?)" + SHORTHAND_SHIFT + "|(" + SHORTHAND_CTRL + "?)"
- + SHORTHAND_CTRL);
- // Used for removing escaped chars, only leaving real shorthands
- private static final Pattern SHORTHAND_REMOVE = Pattern.compile("(["
- + SHORTHAND_ALT + "|" + SHORTHAND_SHIFT + "|" + SHORTHAND_CTRL
- + "])\\1");
- // Mnemonic char, optionally followed by another, and optionally a third
- private static final Pattern SHORTHANDS = Pattern.compile("("
- + SHORTHAND_ALT + "|" + SHORTHAND_SHIFT + "|" + SHORTHAND_CTRL
- + ")(?!\\1)(?:(" + SHORTHAND_ALT + "|" + SHORTHAND_SHIFT + "|"
- + SHORTHAND_CTRL + ")(?!\\1|\\2))?(?:(" + SHORTHAND_ALT + "|"
- + SHORTHAND_SHIFT + "|" + SHORTHAND_CTRL + ")(?!\\1|\\2|\\3))?.");
-
- /**
- * Constructs a ShortcutAction using a shorthand notation to encode the
- * keycode and modifiers in the caption.
- * <p>
- * Insert one or more modifier characters before the character to use as
- * keycode. E.g <code>"&Save"</code> will make a shortcut responding to
- * ALT-S, <code>"E^xit"</code> will respond to CTRL-X.<br/>
- * Multiple modifiers can be used, e.g <code>"&^Delete"</code> will respond
- * to CTRL-ALT-D (the order of the modifier characters is not important).
- * </p>
- * <p>
- * The modifier characters will be removed from the caption. The modifier
- * character is be escaped by itself: two consecutive characters are turned
- * into the original character w/o the special meaning. E.g
- * <code>"Save&&&close"</code> will respond to ALT-C, and the caption will
- * say "Save&close".
- * </p>
- *
- * @param shorthandCaption
- * the caption in modifier shorthand
- */
- public ShortcutAction(String shorthandCaption) {
- this(shorthandCaption, null);
- }
-
- /**
- * Constructs a ShortcutAction using a shorthand notation to encode the
- * keycode a in the caption.
- * <p>
- * This works the same way as {@link #ShortcutAction(String)}, with the
- * exception that the modifiers given override those indicated in the
- * caption. I.e use any of the modifier characters in the caption to
- * indicate the keycode, but the modifier will be the given set.<br/>
- * E.g
- * <code>new ShortcutAction("Do &stuff", new int[]{ShortcutAction.ModifierKey.CTRL}));</code>
- * will respond to CTRL-S.
- * </p>
- *
- * @param shorthandCaption
- * @param modifierKeys
- */
- public ShortcutAction(String shorthandCaption, int[] modifierKeys) {
- // && -> & etc
- super(SHORTHAND_ESCAPE.matcher(shorthandCaption).replaceAll("$1$2$3"));
- // replace escaped chars with something that won't accidentally match
- shorthandCaption = SHORTHAND_REMOVE.matcher(shorthandCaption)
- .replaceAll("\u001A");
- Matcher matcher = SHORTHANDS.matcher(shorthandCaption);
- if (matcher.find()) {
- String match = matcher.group();
-
- // KeyCode from last char in match, uppercase
- keyCode = Character.toUpperCase(matcher.group().charAt(
- match.length() - 1));
-
- // Given modifiers override this indicated in the caption
- if (modifierKeys != null) {
- modifiers = modifierKeys;
- } else {
- // Read modifiers from caption
- int[] mod = new int[match.length() - 1];
- for (int i = 0; i < mod.length; i++) {
- int kc = match.charAt(i);
- switch (kc) {
- case SHORTHAND_CHAR_ALT:
- mod[i] = ModifierKey.ALT;
- break;
- case SHORTHAND_CHAR_CTRL:
- mod[i] = ModifierKey.CTRL;
- break;
- case SHORTHAND_CHAR_SHIFT:
- mod[i] = ModifierKey.SHIFT;
- break;
- }
- }
- modifiers = mod;
- }
-
- } else {
- keyCode = -1;
- modifiers = modifierKeys;
- }
- }
-
- /**
- * Get the {@link KeyCode} that this shortcut reacts to (in combination with
- * the {@link ModifierKey}s).
- *
- * @return keycode for this shortcut
- */
- public int getKeyCode() {
- return keyCode;
- }
-
- /**
- * Get the {@link ModifierKey}s required for the shortcut to react.
- *
- * @return modifier keys for this shortcut
- */
- public int[] getModifiers() {
- return modifiers;
- }
-
- /**
- * Key codes that can be used for shortcuts
- *
- */
- public interface KeyCode extends Serializable {
- public static final int ENTER = 13;
-
- public static final int ESCAPE = 27;
-
- public static final int PAGE_UP = 33;
-
- public static final int PAGE_DOWN = 34;
-
- public static final int TAB = 9;
-
- public static final int ARROW_LEFT = 37;
-
- public static final int ARROW_UP = 38;
-
- public static final int ARROW_RIGHT = 39;
-
- public static final int ARROW_DOWN = 40;
-
- public static final int BACKSPACE = 8;
-
- public static final int DELETE = 46;
-
- public static final int INSERT = 45;
-
- public static final int END = 35;
-
- public static final int HOME = 36;
-
- public static final int F1 = 112;
-
- public static final int F2 = 113;
-
- public static final int F3 = 114;
-
- public static final int F4 = 115;
-
- public static final int F5 = 116;
-
- public static final int F6 = 117;
-
- public static final int F7 = 118;
-
- public static final int F8 = 119;
-
- public static final int F9 = 120;
-
- public static final int F10 = 121;
-
- public static final int F11 = 122;
-
- public static final int F12 = 123;
-
- public static final int A = 65;
-
- public static final int B = 66;
-
- public static final int C = 67;
-
- public static final int D = 68;
-
- public static final int E = 69;
-
- public static final int F = 70;
-
- public static final int G = 71;
-
- public static final int H = 72;
-
- public static final int I = 73;
-
- public static final int J = 74;
-
- public static final int K = 75;
-
- public static final int L = 76;
-
- public static final int M = 77;
-
- public static final int N = 78;
-
- public static final int O = 79;
-
- public static final int P = 80;
-
- public static final int Q = 81;
-
- public static final int R = 82;
-
- public static final int S = 83;
-
- public static final int T = 84;
-
- public static final int U = 85;
-
- public static final int V = 86;
-
- public static final int W = 87;
-
- public static final int X = 88;
-
- public static final int Y = 89;
-
- public static final int Z = 90;
-
- public static final int NUM0 = 48;
-
- public static final int NUM1 = 49;
-
- public static final int NUM2 = 50;
-
- public static final int NUM3 = 51;
-
- public static final int NUM4 = 52;
-
- public static final int NUM5 = 53;
-
- public static final int NUM6 = 54;
-
- public static final int NUM7 = 55;
-
- public static final int NUM8 = 56;
-
- public static final int NUM9 = 57;
-
- public static final int SPACEBAR = 32;
- }
-
- /**
- * Modifier key constants
- *
- */
- public interface ModifierKey extends Serializable {
- public static final int SHIFT = 16;
-
- public static final int CTRL = 17;
-
- public static final int ALT = 18;
-
- public static final int META = 91;
- }
-}
diff --git a/src/com/vaadin/event/ShortcutListener.java b/src/com/vaadin/event/ShortcutListener.java
deleted file mode 100644
index b760cfabe6..0000000000
--- a/src/com/vaadin/event/ShortcutListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import com.vaadin.event.Action.Listener;
-import com.vaadin.terminal.Resource;
-
-public abstract class ShortcutListener extends ShortcutAction implements
- Listener {
-
- private static final long serialVersionUID = 1L;
-
- public ShortcutListener(String caption, int keyCode, int... modifierKeys) {
- super(caption, keyCode, modifierKeys);
- }
-
- public ShortcutListener(String shorthandCaption, int... modifierKeys) {
- super(shorthandCaption, modifierKeys);
- }
-
- public ShortcutListener(String caption, Resource icon, int keyCode,
- int... modifierKeys) {
- super(caption, icon, keyCode, modifierKeys);
- }
-
- public ShortcutListener(String shorthandCaption) {
- super(shorthandCaption);
- }
-
- @Override
- abstract public void handleAction(Object sender, Object target);
-}
diff --git a/src/com/vaadin/event/Transferable.java b/src/com/vaadin/event/Transferable.java
deleted file mode 100644
index 838d8ad7e2..0000000000
--- a/src/com/vaadin/event/Transferable.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.io.Serializable;
-import java.util.Collection;
-
-import com.vaadin.ui.Component;
-
-/**
- * Transferable wraps the data that is to be imported into another component.
- * Currently Transferable is only used for drag and drop.
- *
- * @since 6.3
- */
-public interface Transferable extends Serializable {
-
- /**
- * Returns the data from Transferable by its data flavor (aka data type).
- * Data types can be any string keys, but MIME types like "text/plain" are
- * commonly used.
- * <p>
- * Note, implementations of {@link Transferable} often provide a better
- * typed API for accessing data.
- *
- * @param dataFlavor
- * the data flavor to be returned from Transferable
- * @return the data stored in the Transferable or null if Transferable
- * contains no data for given data flavour
- */
- public Object getData(String dataFlavor);
-
- /**
- * Stores data of given data flavor to Transferable. Possibly existing value
- * of the same data flavor will be replaced.
- *
- * @param dataFlavor
- * the data flavor
- * @param value
- * the new value of the data flavor
- */
- public void setData(String dataFlavor, Object value);
-
- /**
- * @return a collection of data flavors ( data types ) available in this
- * Transferable
- */
- public Collection<String> getDataFlavors();
-
- /**
- * @return the component that created the Transferable or null if the source
- * component is unknown
- */
- public Component getSourceComponent();
-
-}
diff --git a/src/com/vaadin/event/TransferableImpl.java b/src/com/vaadin/event/TransferableImpl.java
deleted file mode 100644
index 4c973571f7..0000000000
--- a/src/com/vaadin/event/TransferableImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.vaadin.ui.Component;
-
-/**
- * TODO Javadoc!
- *
- * @since 6.3
- */
-public class TransferableImpl implements Transferable {
- private Map<String, Object> rawVariables = new HashMap<String, Object>();
- private Component sourceComponent;
-
- public TransferableImpl(Component sourceComponent,
- Map<String, Object> rawVariables) {
- this.sourceComponent = sourceComponent;
- this.rawVariables = rawVariables;
- }
-
- @Override
- public Component getSourceComponent() {
- return sourceComponent;
- }
-
- @Override
- public Object getData(String dataFlavor) {
- return rawVariables.get(dataFlavor);
- }
-
- @Override
- public void setData(String dataFlavor, Object value) {
- rawVariables.put(dataFlavor, value);
- }
-
- @Override
- public Collection<String> getDataFlavors() {
- return rawVariables.keySet();
- }
-
-}
diff --git a/src/com/vaadin/event/dd/DragAndDropEvent.java b/src/com/vaadin/event/dd/DragAndDropEvent.java
deleted file mode 100644
index b920d43469..0000000000
--- a/src/com/vaadin/event/dd/DragAndDropEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.io.Serializable;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-
-/**
- * DragAndDropEvent wraps information related to drag and drop operation. It is
- * passed by terminal implementation for
- * {@link DropHandler#drop(DragAndDropEvent)} and
- * {@link AcceptCriterion#accept(DragAndDropEvent)} methods.
- * <p>
- * DragAndDropEvent instances contains both the dragged data in
- * {@link Transferable} (generated by {@link DragSource} and details about the
- * current drop event in {@link TargetDetails} (generated by {@link DropTarget}.
- *
- * @since 6.3
- *
- */
-public class DragAndDropEvent implements Serializable {
- private Transferable transferable;
- private TargetDetails dropTargetDetails;
-
- public DragAndDropEvent(Transferable transferable,
- TargetDetails dropTargetDetails) {
- this.transferable = transferable;
- this.dropTargetDetails = dropTargetDetails;
- }
-
- /**
- * @return the Transferable instance representing the data dragged in this
- * drag and drop event
- */
- public Transferable getTransferable() {
- return transferable;
- }
-
- /**
- * @return the TargetDetails containing drop target related details of drag
- * and drop operation
- */
- public TargetDetails getTargetDetails() {
- return dropTargetDetails;
- }
-
-}
diff --git a/src/com/vaadin/event/dd/DragSource.java b/src/com/vaadin/event/dd/DragSource.java
deleted file mode 100644
index 4daf0dcb18..0000000000
--- a/src/com/vaadin/event/dd/DragSource.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.util.Map;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Tree;
-
-/**
- * DragSource is a {@link Component} that builds a {@link Transferable} for a
- * drag and drop operation.
- * <p>
- * In Vaadin the drag and drop operation practically starts from client side
- * component. The client side component initially defines the data that will be
- * present in {@link Transferable} object on server side. If the server side
- * counterpart of the component implements this interface, terminal
- * implementation lets it create the {@link Transferable} instance from the raw
- * client side "seed data". This way server side implementation may translate or
- * extend the data that will be available for {@link DropHandler}.
- *
- * @since 6.3
- *
- */
-public interface DragSource extends Component {
-
- /**
- * DragSource may convert data added by client side component to meaningful
- * values for server side developer or add other data based on it.
- *
- * <p>
- * For example Tree converts item identifiers to generated string keys for
- * the client side. Vaadin developer don't and can't know anything about
- * these generated keys, only about item identifiers. When tree node is
- * dragged client puts that key to {@link Transferable}s client side
- * counterpart. In {@link Tree#getTransferable(Map)} the key is converted
- * back to item identifier that the server side developer can use.
- * <p>
- *
- * @since 6.3
- * @param rawVariables
- * the data that client side initially included in
- * {@link Transferable}s client side counterpart.
- * @return the {@link Transferable} instance that will be passed to
- * {@link DropHandler} (and/or {@link AcceptCriterion})
- */
- public Transferable getTransferable(Map<String, Object> rawVariables);
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/DropHandler.java b/src/com/vaadin/event/dd/DropHandler.java
deleted file mode 100644
index 7a15ea5b68..0000000000
--- a/src/com/vaadin/event/dd/DropHandler.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.io.Serializable;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.acceptcriteria.AcceptAll;
-import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion;
-
-/**
- * DropHandlers contain the actual business logic for drag and drop operations.
- * <p>
- * The {@link #drop(DragAndDropEvent)} method is used to receive the transferred
- * data and the {@link #getAcceptCriterion()} method contains the (possibly
- * client side verifiable) criterion whether the dragged data will be handled at
- * all.
- *
- * @since 6.3
- *
- */
-public interface DropHandler extends Serializable {
-
- /**
- * Drop method is called when the end user has finished the drag operation
- * on a {@link DropTarget} and {@link DragAndDropEvent} has passed
- * {@link AcceptCriterion} defined by {@link #getAcceptCriterion()} method.
- * The actual business logic of drag and drop operation is implemented into
- * this method.
- *
- * @param event
- * the event related to this drop
- */
- public void drop(DragAndDropEvent event);
-
- /**
- * Returns the {@link AcceptCriterion} used to evaluate whether the
- * {@link Transferable} will be handed over to
- * {@link DropHandler#drop(DragAndDropEvent)} method. If client side can't
- * verify the {@link AcceptCriterion}, the same criteria may be tested also
- * prior to actual drop - during the drag operation.
- * <p>
- * Based on information from {@link AcceptCriterion} components may display
- * some hints for the end user whether the drop will be accepted or not.
- * <p>
- * Vaadin contains a variety of criteria built in that can be composed to
- * more complex criterion. If the build in criteria are not enough,
- * developer can use a {@link ServerSideCriterion} or build own custom
- * criterion with client side counterpart.
- * <p>
- * If developer wants to handle everything in the
- * {@link #drop(DragAndDropEvent)} method, {@link AcceptAll} instance can be
- * returned.
- *
- * @return the {@link AcceptCriterion}
- */
- public AcceptCriterion getAcceptCriterion();
-
-}
diff --git a/src/com/vaadin/event/dd/DropTarget.java b/src/com/vaadin/event/dd/DropTarget.java
deleted file mode 100644
index c18aa60b19..0000000000
--- a/src/com/vaadin/event/dd/DropTarget.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.util.Map;
-
-import com.vaadin.ui.Component;
-
-/**
- * DropTarget is an interface for components supporting drop operations. A
- * component that wants to receive drop events should implement this interface
- * and provide a {@link DropHandler} which will handle the actual drop event.
- *
- * @since 6.3
- */
-public interface DropTarget extends Component {
-
- /**
- * @return the drop hanler that will receive the dragged data or null if
- * drops are not currently accepted
- */
- public DropHandler getDropHandler();
-
- /**
- * Called before the {@link DragAndDropEvent} is passed to
- * {@link DropHandler}. Implementation may for example translate the drop
- * target details provided by the client side (drop target) to meaningful
- * server side values. If null is returned the terminal implementation will
- * automatically create a {@link TargetDetails} with raw client side data.
- *
- * @see DragSource#getTransferable(Map)
- *
- * @param clientVariables
- * data passed from the DropTargets client side counterpart.
- * @return A DropTargetDetails object with the translated data or null to
- * use a default implementation.
- */
- public TargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables);
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/TargetDetails.java b/src/com/vaadin/event/dd/TargetDetails.java
deleted file mode 100644
index a352fbec60..0000000000
--- a/src/com/vaadin/event/dd/TargetDetails.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Tree.TreeTargetDetails;
-
-/**
- * TargetDetails wraps drop target related information about
- * {@link DragAndDropEvent}.
- * <p>
- * When a TargetDetails object is used in {@link DropHandler} it is often
- * preferable to cast the TargetDetails to an implementation provided by
- * DropTarget like {@link TreeTargetDetails}. They often provide a better typed,
- * drop target specific API.
- *
- * @since 6.3
- *
- */
-public interface TargetDetails extends Serializable {
-
- /**
- * Gets target data associated with the given string key
- *
- * @param key
- * @return The data associated with the key
- */
- public Object getData(String key);
-
- /**
- * @return the drop target on which the {@link DragAndDropEvent} happened.
- */
- public DropTarget getTarget();
-
-}
diff --git a/src/com/vaadin/event/dd/TargetDetailsImpl.java b/src/com/vaadin/event/dd/TargetDetailsImpl.java
deleted file mode 100644
index 4a459777ed..0000000000
--- a/src/com/vaadin/event/dd/TargetDetailsImpl.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A HashMap backed implementation of {@link TargetDetails} for terminal
- * implementation and for extension.
- *
- * @since 6.3
- *
- */
-@SuppressWarnings("serial")
-public class TargetDetailsImpl implements TargetDetails {
-
- private HashMap<String, Object> data = new HashMap<String, Object>();
- private DropTarget dropTarget;
-
- protected TargetDetailsImpl(Map<String, Object> rawDropData) {
- data.putAll(rawDropData);
- }
-
- public TargetDetailsImpl(Map<String, Object> rawDropData,
- DropTarget dropTarget) {
- this(rawDropData);
- this.dropTarget = dropTarget;
- }
-
- @Override
- public Object getData(String key) {
- return data.get(key);
- }
-
- public Object setData(String key, Object value) {
- return data.put(key, value);
- }
-
- @Override
- public DropTarget getTarget() {
- return dropTarget;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java b/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java
deleted file mode 100644
index 1457ea9df3..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.dd.DragAndDropEvent;
-
-/**
- * Criterion that accepts all drops anywhere on the component.
- * <p>
- * Note! Class is singleton, use {@link #get()} method to get the instance.
- *
- *
- * @since 6.3
- *
- */
-public final class AcceptAll extends ClientSideCriterion {
-
- private static final long serialVersionUID = 7406683402153141461L;
- private static AcceptCriterion singleton = new AcceptAll();
-
- private AcceptAll() {
- }
-
- public static AcceptCriterion get() {
- return singleton;
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- return true;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java
deleted file mode 100644
index c0f04d362f..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import java.io.Serializable;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * Criterion that can be used create policy to accept/discard dragged content
- * (presented by {@link Transferable}).
- *
- * The drag and drop mechanism will verify the criteria returned by
- * {@link DropHandler#getAcceptCriterion()} before calling
- * {@link DropHandler#drop(DragAndDropEvent)}.
- *
- * The criteria can be evaluated either on the client (browser - see
- * {@link ClientSideCriterion}) or on the server (see
- * {@link ServerSideCriterion}). If no constraints are needed, an
- * {@link AcceptAll} can be used.
- *
- * In addition to accepting or rejecting a possible drop, criteria can provide
- * additional hints for client side painting.
- *
- * @see DropHandler
- * @see ClientSideCriterion
- * @see ServerSideCriterion
- *
- * @since 6.3
- */
-public interface AcceptCriterion extends Serializable {
-
- /**
- * Returns whether the criteria can be checked on the client or whether a
- * server request is needed to check the criteria.
- *
- * This requirement may depend on the state of the criterion (e.g. logical
- * operations between criteria), so this cannot be based on a marker
- * interface.
- */
- public boolean isClientSideVerifiable();
-
- public void paint(PaintTarget target) throws PaintException;
-
- /**
- * This needs to be implemented iff criterion does some lazy server side
- * initialization. The UIDL painted in this method will be passed to client
- * side drop handler implementation. Implementation can assume that
- * {@link #accept(DragAndDropEvent)} is called before this method.
- *
- * @param target
- * @throws PaintException
- */
- public void paintResponse(PaintTarget target) throws PaintException;
-
- /**
- * Validates the data in event to be appropriate for the
- * {@link DropHandler#drop(DragAndDropEvent)} method.
- * <p>
- * Note that even if your criterion is validated on client side, you should
- * always validate the data on server side too.
- *
- * @param dragEvent
- * @return
- */
- public boolean accept(DragAndDropEvent dragEvent);
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/And.java b/src/com/vaadin/event/dd/acceptcriteria/And.java
deleted file mode 100644
index 4122d67160..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/And.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * A compound criterion that accepts the drag if all of its criteria accepts the
- * drag.
- *
- * @see Or
- *
- * @since 6.3
- *
- */
-public class And extends ClientSideCriterion {
-
- private static final long serialVersionUID = -5242574480825471748L;
- protected ClientSideCriterion[] criteria;
-
- /**
- *
- * @param criteria
- * criteria of which the And criterion will be composed
- */
- public And(ClientSideCriterion... criteria) {
- this.criteria = criteria;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- for (ClientSideCriterion crit : criteria) {
- crit.paint(target);
- }
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- for (ClientSideCriterion crit : criteria) {
- if (!crit.accept(dragEvent)) {
- return false;
- }
- }
- return true;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java
deleted file mode 100644
index 7d2c42ecb0..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * Parent class for criteria that can be completely validated on client side.
- * All classes that provide criteria that can be completely validated on client
- * side should extend this class.
- *
- * It is recommended that subclasses of ClientSideCriterion re-validate the
- * condition on the server side in
- * {@link AcceptCriterion#accept(com.vaadin.event.dd.DragAndDropEvent)} after
- * the client side validation has accepted a transfer.
- *
- * @since 6.3
- */
-public abstract class ClientSideCriterion implements Serializable,
- AcceptCriterion {
-
- /*
- * All criteria that extend this must be completely validatable on client
- * side.
- *
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptCriteria.AcceptCriterion#isClientSideVerifiable
- * ()
- */
- @Override
- public final boolean isClientSideVerifiable() {
- return true;
- }
-
- @Override
- public void paint(PaintTarget target) throws PaintException {
- target.startTag("-ac");
- target.addAttribute("name", getIdentifier());
- paintContent(target);
- target.endTag("-ac");
- }
-
- protected void paintContent(PaintTarget target) throws PaintException {
- }
-
- protected String getIdentifier() {
- return getClass().getCanonicalName();
- }
-
- @Override
- public final void paintResponse(PaintTarget target) throws PaintException {
- // NOP, nothing to do as this is client side verified criterion
- }
-
-}
diff --git a/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java b/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java
deleted file mode 100644
index 4c52698a4a..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * A Criterion that checks whether {@link Transferable} contains given data
- * flavor. The developer might for example accept the incoming data only if it
- * contains "Url" or "Text".
- *
- * @since 6.3
- */
-public class ContainsDataFlavor extends ClientSideCriterion {
-
- private String dataFlavorId;
-
- /**
- * Constructs a new instance of {@link ContainsDataFlavor}.
- *
- * @param dataFlawor
- * the type of data that will be checked from
- * {@link Transferable}
- */
- public ContainsDataFlavor(String dataFlawor) {
- dataFlavorId = dataFlawor;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- target.addAttribute("p", dataFlavorId);
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- return dragEvent.getTransferable().getDataFlavors()
- .contains(dataFlavorId);
- }
-
- @Override
- protected String getIdentifier() {
- // extending classes use client side implementation from this class
- return ContainsDataFlavor.class.getCanonicalName();
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/Not.java b/src/com/vaadin/event/dd/acceptcriteria/Not.java
deleted file mode 100644
index 1ed40a324d..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/Not.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * Criterion that wraps another criterion and inverts its return value.
- *
- * @since 6.3
- *
- */
-public class Not extends ClientSideCriterion {
-
- private static final long serialVersionUID = 1131422338558613244L;
- private AcceptCriterion acceptCriterion;
-
- public Not(ClientSideCriterion acceptCriterion) {
- this.acceptCriterion = acceptCriterion;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- acceptCriterion.paint(target);
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- return !acceptCriterion.accept(dragEvent);
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/Or.java b/src/com/vaadin/event/dd/acceptcriteria/Or.java
deleted file mode 100644
index 6ad45c54af..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/Or.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * A compound criterion that accepts the drag if any of its criterion accepts
- * it.
- *
- * @see And
- *
- * @since 6.3
- *
- */
-public class Or extends ClientSideCriterion {
- private static final long serialVersionUID = 1L;
- private AcceptCriterion criteria[];
-
- /**
- * @param criteria
- * the criteria of which the Or criteria will be composed
- */
- public Or(ClientSideCriterion... criteria) {
- this.criteria = criteria;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- for (AcceptCriterion crit : criteria) {
- crit.paint(target);
- }
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- for (AcceptCriterion crit : criteria) {
- if (crit.accept(dragEvent)) {
- return true;
- }
- }
- return false;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java b/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java
deleted file mode 100644
index 47f06d434c..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import java.io.Serializable;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * Parent class for criteria which are verified on the server side during a drag
- * operation to accept/discard dragged content (presented by
- * {@link Transferable}).
- * <p>
- * Subclasses should implement the
- * {@link AcceptCriterion#accept(com.vaadin.event.dd.DragAndDropEvent)} method.
- * <p>
- * As all server side state can be used to make a decision, this is more
- * flexible than {@link ClientSideCriterion}. However, this does require
- * additional requests from the browser to the server during a drag operation.
- *
- * @see AcceptCriterion
- * @see ClientSideCriterion
- *
- * @since 6.3
- */
-public abstract class ServerSideCriterion implements Serializable,
- AcceptCriterion {
-
- private static final long serialVersionUID = 2128510128911628902L;
-
- @Override
- public final boolean isClientSideVerifiable() {
- return false;
- }
-
- @Override
- public void paint(PaintTarget target) throws PaintException {
- target.startTag("-ac");
- target.addAttribute("name", getIdentifier());
- paintContent(target);
- target.endTag("-ac");
- }
-
- public void paintContent(PaintTarget target) {
- }
-
- @Override
- public void paintResponse(PaintTarget target) throws PaintException {
- }
-
- protected String getIdentifier() {
- return ServerSideCriterion.class.getCanonicalName();
- }
-}
diff --git a/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java b/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
deleted file mode 100644
index d4fd20c952..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/SourceIs.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.event.TransferableImpl;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.ui.Component;
-
-/**
- * Client side criteria that checks if the drag source is one of the given
- * components.
- *
- * @since 6.3
- */
-@SuppressWarnings("serial")
-public class SourceIs extends ClientSideCriterion {
-
- private Component[] components;
-
- public SourceIs(Component... component) {
- components = component;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- int paintedComponents = 0;
- for (int i = 0; i < components.length; i++) {
- Component c = components[i];
- if (c.getApplication() != null) {
- target.addAttribute("component" + paintedComponents++, c);
- } else {
- Logger.getLogger(SourceIs.class.getName())
- .log(Level.WARNING,
- "SourceIs component {0} at index {1} is not attached to the component hierachy and will thus be ignored",
- new Object[] { c.getClass().getName(),
- Integer.valueOf(i) });
- }
- }
- target.addAttribute("c", paintedComponents);
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- if (dragEvent.getTransferable() instanceof TransferableImpl) {
- Component sourceComponent = ((TransferableImpl) dragEvent
- .getTransferable()).getSourceComponent();
- for (Component c : components) {
- if (c == sourceComponent) {
- return true;
- }
- }
- }
-
- return false;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java b/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java
deleted file mode 100644
index a644b858e2..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.TransferableImpl;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Table;
-import com.vaadin.ui.Tree;
-
-/**
- *
- * A criterion that ensures the drag source is the same as drop target. Eg.
- * {@link Tree} or {@link Table} could support only re-ordering of items, but no
- * {@link Transferable}s coming outside.
- * <p>
- * Note! Class is singleton, use {@link #get()} method to get the instance.
- *
- * @since 6.3
- *
- */
-public class SourceIsTarget extends ClientSideCriterion {
-
- private static final long serialVersionUID = -451399314705532584L;
- private static SourceIsTarget instance = new SourceIsTarget();
-
- private SourceIsTarget() {
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- if (dragEvent.getTransferable() instanceof TransferableImpl) {
- Component sourceComponent = ((TransferableImpl) dragEvent
- .getTransferable()).getSourceComponent();
- DropTarget target = dragEvent.getTargetDetails().getTarget();
- return sourceComponent == target;
- }
- return false;
- }
-
- public static synchronized SourceIsTarget get() {
- return instance;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java b/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java
deleted file mode 100644
index 5df8f3f618..0000000000
--- a/src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-/**
- *
- */
-package com.vaadin.event.dd.acceptcriteria;
-
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.TargetDetails;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * Criterion for checking if drop target details contains the specific property
- * with the specific value. Currently only String values are supported.
- *
- * @since 6.3
- *
- * TODO add support for other basic data types that we support in UIDL.
- *
- */
-public class TargetDetailIs extends ClientSideCriterion {
-
- private static final long serialVersionUID = 763165450054331246L;
- private String propertyName;
- private Object value;
-
- /**
- * Constructs a criterion which ensures that the value there is a value in
- * {@link TargetDetails} that equals the reference value.
- *
- * @param dataFlavor
- * the type of data to be checked
- * @param value
- * the reference value to which the drop target detail will be
- * compared
- */
- public TargetDetailIs(String dataFlavor, String value) {
- propertyName = dataFlavor;
- this.value = value;
- }
-
- public TargetDetailIs(String dataFlavor, Boolean true1) {
- propertyName = dataFlavor;
- value = true1;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- target.addAttribute("p", propertyName);
- if (value instanceof Boolean) {
- target.addAttribute("v", ((Boolean) value).booleanValue());
- target.addAttribute("t", "b");
- } else if (value instanceof String) {
- target.addAttribute("v", (String) value);
- }
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- Object data = dragEvent.getTargetDetails().getData(propertyName);
- return value.equals(data);
- }
-
- @Override
- protected String getIdentifier() {
- // sub classes by default use VDropDetailEquals a client implementation
- return TargetDetailIs.class.getCanonicalName();
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/event/package.html b/src/com/vaadin/event/package.html
deleted file mode 100644
index 2e7e17b892..0000000000
--- a/src/com/vaadin/event/package.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-
-<!-- Package summary here -->
-
-<p>Provides classes and interfaces for the inheritable event
-model. The model supports inheritable events and a flexible way of
-registering and unregistering event listeners. It's a fundamental building
-block of Vaadin, and as it is included in
-{@link com.vaadin.ui.AbstractComponent}, all UI components
-automatically support it.</p>
-
-<h2>Package Specification</h2>
-
-<p>The core of the event model is the inheritable event class
-hierarchy, and the {@link com.vaadin.event.EventRouter EventRouter}
-which provide a simple, ubiquitous mechanism to transport events to all
-interested parties.</p>
-
-<p>The power of the event inheritance arises from the possibility of
-receiving not only the events of the registered type, <i>but also the
-ones which are inherited from it</i>. For example, let's assume that there
-are the events <code>GeneralEvent</code> and <code>SpecializedEvent</code>
-so that the latter inherits the former. Furthermore we have an object
-<code>A</code> which registers to receive <code>GeneralEvent</code> type
-events from the object <code>B</code>. <code>A</code> would of course
-receive all <code>GeneralEvent</code>s generated by <code>B</code>, but in
-addition to this, <code>A</code> would also receive all
-<code>SpecializedEvent</code>s generated by <code>B</code>. However, if
-<code>B</code> generates some other events that do not have
-<code>GeneralEvent</code> as an ancestor, <code>A</code> would not receive
-them unless it registers to listen for them, too.</p>
-
-<p>The interface to attaching and detaching listeners to and from an object
-works with methods. One specifies the event that should trigger the listener,
-the trigger method that should be called when a suitable event occurs and the
-object owning the method. From these a new listener is constructed and added
-to the event router of the specified component.</p>
-
-<p>The interface is defined in
-{@link com.vaadin.event.MethodEventSource MethodEventSource}, and a
-straightforward implementation of it is defined in
-{@link com.vaadin.event.EventRouter EventRouter} which also includes
-a method to actually fire the events.</p>
-
-<p>All fired events are passed to all registered listeners, which are of
-type {@link com.vaadin.event.ListenerMethod ListenerMethod}. The
-listener then checks if the event type matches with the specified event
-type and calls the specified trigger method if it does.</p>
-
-<!-- Put @see and @since tags down here. -->
-
-</body>
-</html>
diff --git a/src/com/vaadin/external/json/JSONArray.java b/src/com/vaadin/external/json/JSONArray.java
deleted file mode 100644
index 2307749ffc..0000000000
--- a/src/com/vaadin/external/json/JSONArray.java
+++ /dev/null
@@ -1,963 +0,0 @@
-package com.vaadin.external.json;
-
-/*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * A JSONArray is an ordered sequence of values. Its external text form is a
- * string wrapped in square brackets with commas separating the values. The
- * internal form is an object having <code>get</code> and <code>opt</code>
- * methods for accessing the values by index, and <code>put</code> methods for
- * adding or replacing values. The values can be any of these types:
- * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
- * <code>Number</code>, <code>String</code>, or the
- * <code>JSONObject.NULL object</code>.
- * <p>
- * The constructor can convert a JSON text into a Java object. The
- * <code>toString</code> method converts to JSON text.
- * <p>
- * A <code>get</code> method returns a value if one can be found, and throws an
- * exception if one cannot be found. An <code>opt</code> method returns a
- * default value instead of throwing an exception, and so is useful for
- * obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an
- * object which you can cast or query for type. There are also typed
- * <code>get</code> and <code>opt</code> methods that do type checking and type
- * coercion for you.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to
- * JSON syntax rules. The constructors are more forgiving in the texts they will
- * accept:
- * <ul>
- * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
- * before the closing bracket.</li>
- * <li>The <code>null</code> value will be inserted when there is <code>,</code>
- * &nbsp;<small>(comma)</small> elision.</li>
- * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
- * quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a quote
- * or single quote, and if they do not contain leading or trailing spaces, and
- * if they do not contain any of these characters:
- * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and
- * if they are not the reserved words <code>true</code>, <code>false</code>, or
- * <code>null</code>.</li>
- * <li>Values can be separated by <code>;</code> <small>(semicolon)</small> as
- * well as by <code>,</code> <small>(comma)</small>.</li>
- * <li>Numbers may have the <code>0x-</code> <small>(hex)</small> prefix.</li>
- * </ul>
- *
- * @author JSON.org
- * @version 2011-08-25
- */
-public class JSONArray implements Serializable {
-
- /**
- * The arrayList where the JSONArray's properties are kept.
- */
- private ArrayList myArrayList;
-
- /**
- * Construct an empty JSONArray.
- */
- public JSONArray() {
- myArrayList = new ArrayList();
- }
-
- /**
- * Construct a JSONArray from a JSONTokener.
- *
- * @param x
- * A JSONTokener
- * @throws JSONException
- * If there is a syntax error.
- */
- public JSONArray(JSONTokener x) throws JSONException {
- this();
- if (x.nextClean() != '[') {
- throw x.syntaxError("A JSONArray text must start with '['");
- }
- if (x.nextClean() != ']') {
- x.back();
- for (;;) {
- if (x.nextClean() == ',') {
- x.back();
- myArrayList.add(JSONObject.NULL);
- } else {
- x.back();
- myArrayList.add(x.nextValue());
- }
- switch (x.nextClean()) {
- case ';':
- case ',':
- if (x.nextClean() == ']') {
- return;
- }
- x.back();
- break;
- case ']':
- return;
- default:
- throw x.syntaxError("Expected a ',' or ']'");
- }
- }
- }
- }
-
- /**
- * Construct a JSONArray from a source JSON text.
- *
- * @param source
- * A string that begins with <code>[</code>&nbsp;<small>(left
- * bracket)</small> and ends with <code>]</code>
- * &nbsp;<small>(right bracket)</small>.
- * @throws JSONException
- * If there is a syntax error.
- */
- public JSONArray(String source) throws JSONException {
- this(new JSONTokener(source));
- }
-
- /**
- * Construct a JSONArray from a Collection.
- *
- * @param collection
- * A Collection.
- */
- public JSONArray(Collection collection) {
- myArrayList = new ArrayList();
- if (collection != null) {
- Iterator iter = collection.iterator();
- while (iter.hasNext()) {
- myArrayList.add(JSONObject.wrap(iter.next()));
- }
- }
- }
-
- /**
- * Construct a JSONArray from an array
- *
- * @throws JSONException
- * If not an array.
- */
- public JSONArray(Object array) throws JSONException {
- this();
- if (array.getClass().isArray()) {
- int length = Array.getLength(array);
- for (int i = 0; i < length; i += 1) {
- this.put(JSONObject.wrap(Array.get(array, i)));
- }
- } else {
- throw new JSONException(
- "JSONArray initial value should be a string or collection or array.");
- }
- }
-
- /**
- * Get the object value associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return An object value.
- * @throws JSONException
- * If there is no value for the index.
- */
- public Object get(int index) throws JSONException {
- Object object = opt(index);
- if (object == null) {
- throw new JSONException("JSONArray[" + index + "] not found.");
- }
- return object;
- }
-
- /**
- * Get the boolean value associated with an index. The string values "true"
- * and "false" are converted to boolean.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The truth.
- * @throws JSONException
- * If there is no value for the index or if the value is not
- * convertible to boolean.
- */
- public boolean getBoolean(int index) throws JSONException {
- Object object = get(index);
- if (object.equals(Boolean.FALSE)
- || (object instanceof String && ((String) object)
- .equalsIgnoreCase("false"))) {
- return false;
- } else if (object.equals(Boolean.TRUE)
- || (object instanceof String && ((String) object)
- .equalsIgnoreCase("true"))) {
- return true;
- }
- throw new JSONException("JSONArray[" + index + "] is not a boolean.");
- }
-
- /**
- * Get the double value associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- * @throws JSONException
- * If the key is not found or if the value cannot be converted
- * to a number.
- */
- public double getDouble(int index) throws JSONException {
- Object object = get(index);
- try {
- return object instanceof Number ? ((Number) object).doubleValue()
- : Double.parseDouble((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONArray[" + index + "] is not a number.");
- }
- }
-
- /**
- * Get the int value associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- * @throws JSONException
- * If the key is not found or if the value is not a number.
- */
- public int getInt(int index) throws JSONException {
- Object object = get(index);
- try {
- return object instanceof Number ? ((Number) object).intValue()
- : Integer.parseInt((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONArray[" + index + "] is not a number.");
- }
- }
-
- /**
- * Get the JSONArray associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return A JSONArray value.
- * @throws JSONException
- * If there is no value for the index. or if the value is not a
- * JSONArray
- */
- public JSONArray getJSONArray(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONArray) {
- return (JSONArray) object;
- }
- throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
- }
-
- /**
- * Get the JSONObject associated with an index.
- *
- * @param index
- * subscript
- * @return A JSONObject value.
- * @throws JSONException
- * If there is no value for the index or if the value is not a
- * JSONObject
- */
- public JSONObject getJSONObject(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof JSONObject) {
- return (JSONObject) object;
- }
- throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
- }
-
- /**
- * Get the long value associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- * @throws JSONException
- * If the key is not found or if the value cannot be converted
- * to a number.
- */
- public long getLong(int index) throws JSONException {
- Object object = get(index);
- try {
- return object instanceof Number ? ((Number) object).longValue()
- : Long.parseLong((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONArray[" + index + "] is not a number.");
- }
- }
-
- /**
- * Get the string associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return A string value.
- * @throws JSONException
- * If there is no string value for the index.
- */
- public String getString(int index) throws JSONException {
- Object object = get(index);
- if (object instanceof String) {
- return (String) object;
- }
- throw new JSONException("JSONArray[" + index + "] not a string.");
- }
-
- /**
- * Determine if the value is null.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return true if the value at the index is null, or if there is no value.
- */
- public boolean isNull(int index) {
- return JSONObject.NULL.equals(opt(index));
- }
-
- /**
- * Make a string from the contents of this JSONArray. The
- * <code>separator</code> string is inserted between each element. Warning:
- * This method assumes that the data structure is acyclical.
- *
- * @param separator
- * A string that will be inserted between the elements.
- * @return a string.
- * @throws JSONException
- * If the array contains an invalid number.
- */
- public String join(String separator) throws JSONException {
- int len = length();
- StringBuffer sb = new StringBuffer();
-
- for (int i = 0; i < len; i += 1) {
- if (i > 0) {
- sb.append(separator);
- }
- sb.append(JSONObject.valueToString(myArrayList.get(i)));
- }
- return sb.toString();
- }
-
- /**
- * Get the number of elements in the JSONArray, included nulls.
- *
- * @return The length (or size).
- */
- public int length() {
- return myArrayList.size();
- }
-
- /**
- * Get the optional object value associated with an index.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return An object value, or null if there is no object at that index.
- */
- public Object opt(int index) {
- return (index < 0 || index >= length()) ? null : myArrayList.get(index);
- }
-
- /**
- * Get the optional boolean value associated with an index. It returns false
- * if there is no value at that index, or if the value is not Boolean.TRUE
- * or the String "true".
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The truth.
- */
- public boolean optBoolean(int index) {
- return optBoolean(index, false);
- }
-
- /**
- * Get the optional boolean value associated with an index. It returns the
- * defaultValue if there is no value at that index or if it is not a Boolean
- * or the String "true" or "false" (case insensitive).
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @param defaultValue
- * A boolean default.
- * @return The truth.
- */
- public boolean optBoolean(int index, boolean defaultValue) {
- try {
- return getBoolean(index);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get the optional double value associated with an index. NaN is returned
- * if there is no value for the index, or if the value is not a number and
- * cannot be converted to a number.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- */
- public double optDouble(int index) {
- return optDouble(index, Double.NaN);
- }
-
- /**
- * Get the optional double value associated with an index. The defaultValue
- * is returned if there is no value for the index, or if the value is not a
- * number and cannot be converted to a number.
- *
- * @param index
- * subscript
- * @param defaultValue
- * The default value.
- * @return The value.
- */
- public double optDouble(int index, double defaultValue) {
- try {
- return getDouble(index);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get the optional int value associated with an index. Zero is returned if
- * there is no value for the index, or if the value is not a number and
- * cannot be converted to a number.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- */
- public int optInt(int index) {
- return optInt(index, 0);
- }
-
- /**
- * Get the optional int value associated with an index. The defaultValue is
- * returned if there is no value for the index, or if the value is not a
- * number and cannot be converted to a number.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @param defaultValue
- * The default value.
- * @return The value.
- */
- public int optInt(int index, int defaultValue) {
- try {
- return getInt(index);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get the optional JSONArray associated with an index.
- *
- * @param index
- * subscript
- * @return A JSONArray value, or null if the index has no value, or if the
- * value is not a JSONArray.
- */
- public JSONArray optJSONArray(int index) {
- Object o = opt(index);
- return o instanceof JSONArray ? (JSONArray) o : null;
- }
-
- /**
- * Get the optional JSONObject associated with an index. Null is returned if
- * the key is not found, or null if the index has no value, or if the value
- * is not a JSONObject.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return A JSONObject value.
- */
- public JSONObject optJSONObject(int index) {
- Object o = opt(index);
- return o instanceof JSONObject ? (JSONObject) o : null;
- }
-
- /**
- * Get the optional long value associated with an index. Zero is returned if
- * there is no value for the index, or if the value is not a number and
- * cannot be converted to a number.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return The value.
- */
- public long optLong(int index) {
- return optLong(index, 0);
- }
-
- /**
- * Get the optional long value associated with an index. The defaultValue is
- * returned if there is no value for the index, or if the value is not a
- * number and cannot be converted to a number.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @param defaultValue
- * The default value.
- * @return The value.
- */
- public long optLong(int index, long defaultValue) {
- try {
- return getLong(index);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get the optional string value associated with an index. It returns an
- * empty string if there is no value at that index. If the value is not a
- * string and is not null, then it is coverted to a string.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @return A String value.
- */
- public String optString(int index) {
- return optString(index, "");
- }
-
- /**
- * Get the optional string associated with an index. The defaultValue is
- * returned if the key is not found.
- *
- * @param index
- * The index must be between 0 and length() - 1.
- * @param defaultValue
- * The default value.
- * @return A String value.
- */
- public String optString(int index, String defaultValue) {
- Object object = opt(index);
- return JSONObject.NULL.equals(object) ? object.toString()
- : defaultValue;
- }
-
- /**
- * Append a boolean value. This increases the array's length by one.
- *
- * @param value
- * A boolean value.
- * @return this.
- */
- public JSONArray put(boolean value) {
- put(value ? Boolean.TRUE : Boolean.FALSE);
- return this;
- }
-
- /**
- * Put a value in the JSONArray, where the value will be a JSONArray which
- * is produced from a Collection.
- *
- * @param value
- * A Collection value.
- * @return this.
- */
- public JSONArray put(Collection value) {
- put(new JSONArray(value));
- return this;
- }
-
- /**
- * Append a double value. This increases the array's length by one.
- *
- * @param value
- * A double value.
- * @throws JSONException
- * if the value is not finite.
- * @return this.
- */
- public JSONArray put(double value) throws JSONException {
- Double d = new Double(value);
- JSONObject.testValidity(d);
- put(d);
- return this;
- }
-
- /**
- * Append an int value. This increases the array's length by one.
- *
- * @param value
- * An int value.
- * @return this.
- */
- public JSONArray put(int value) {
- put(new Integer(value));
- return this;
- }
-
- /**
- * Append an long value. This increases the array's length by one.
- *
- * @param value
- * A long value.
- * @return this.
- */
- public JSONArray put(long value) {
- put(new Long(value));
- return this;
- }
-
- /**
- * Put a value in the JSONArray, where the value will be a JSONObject which
- * is produced from a Map.
- *
- * @param value
- * A Map value.
- * @return this.
- */
- public JSONArray put(Map value) {
- put(new JSONObject(value));
- return this;
- }
-
- /**
- * Append an object value. This increases the array's length by one.
- *
- * @param value
- * An object value. The value should be a Boolean, Double,
- * Integer, JSONArray, JSONObject, Long, or String, or the
- * JSONObject.NULL object.
- * @return this.
- */
- public JSONArray put(Object value) {
- myArrayList.add(value);
- return this;
- }
-
- /**
- * Put or replace a boolean value in the JSONArray. If the index is greater
- * than the length of the JSONArray, then null elements will be added as
- * necessary to pad it out.
- *
- * @param index
- * The subscript.
- * @param value
- * A boolean value.
- * @return this.
- * @throws JSONException
- * If the index is negative.
- */
- public JSONArray put(int index, boolean value) throws JSONException {
- put(index, value ? Boolean.TRUE : Boolean.FALSE);
- return this;
- }
-
- /**
- * Put a value in the JSONArray, where the value will be a JSONArray which
- * is produced from a Collection.
- *
- * @param index
- * The subscript.
- * @param value
- * A Collection value.
- * @return this.
- * @throws JSONException
- * If the index is negative or if the value is not finite.
- */
- public JSONArray put(int index, Collection value) throws JSONException {
- put(index, new JSONArray(value));
- return this;
- }
-
- /**
- * Put or replace a double value. If the index is greater than the length of
- * the JSONArray, then null elements will be added as necessary to pad it
- * out.
- *
- * @param index
- * The subscript.
- * @param value
- * A double value.
- * @return this.
- * @throws JSONException
- * If the index is negative or if the value is not finite.
- */
- public JSONArray put(int index, double value) throws JSONException {
- put(index, new Double(value));
- return this;
- }
-
- /**
- * Put or replace an int value. If the index is greater than the length of
- * the JSONArray, then null elements will be added as necessary to pad it
- * out.
- *
- * @param index
- * The subscript.
- * @param value
- * An int value.
- * @return this.
- * @throws JSONException
- * If the index is negative.
- */
- public JSONArray put(int index, int value) throws JSONException {
- put(index, new Integer(value));
- return this;
- }
-
- /**
- * Put or replace a long value. If the index is greater than the length of
- * the JSONArray, then null elements will be added as necessary to pad it
- * out.
- *
- * @param index
- * The subscript.
- * @param value
- * A long value.
- * @return this.
- * @throws JSONException
- * If the index is negative.
- */
- public JSONArray put(int index, long value) throws JSONException {
- put(index, new Long(value));
- return this;
- }
-
- /**
- * Put a value in the JSONArray, where the value will be a JSONObject that
- * is produced from a Map.
- *
- * @param index
- * The subscript.
- * @param value
- * The Map value.
- * @return this.
- * @throws JSONException
- * If the index is negative or if the the value is an invalid
- * number.
- */
- public JSONArray put(int index, Map value) throws JSONException {
- put(index, new JSONObject(value));
- return this;
- }
-
- /**
- * Put or replace an object value in the JSONArray. If the index is greater
- * than the length of the JSONArray, then null elements will be added as
- * necessary to pad it out.
- *
- * @param index
- * The subscript.
- * @param value
- * The value to put into the array. The value should be a
- * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
- * String, or the JSONObject.NULL object.
- * @return this.
- * @throws JSONException
- * If the index is negative or if the the value is an invalid
- * number.
- */
- public JSONArray put(int index, Object value) throws JSONException {
- JSONObject.testValidity(value);
- if (index < 0) {
- throw new JSONException("JSONArray[" + index + "] not found.");
- }
- if (index < length()) {
- myArrayList.set(index, value);
- } else {
- while (index != length()) {
- put(JSONObject.NULL);
- }
- put(value);
- }
- return this;
- }
-
- /**
- * Remove an index and close the hole.
- *
- * @param index
- * The index of the element to be removed.
- * @return The value that was associated with the index, or null if there
- * was no value.
- */
- public Object remove(int index) {
- Object o = opt(index);
- myArrayList.remove(index);
- return o;
- }
-
- /**
- * Produce a JSONObject by combining a JSONArray of names with the values of
- * this JSONArray.
- *
- * @param names
- * A JSONArray containing a list of key strings. These will be
- * paired with the values.
- * @return A JSONObject, or null if there are no names or if this JSONArray
- * has no values.
- * @throws JSONException
- * If any of the names are null.
- */
- public JSONObject toJSONObject(JSONArray names) throws JSONException {
- if (names == null || names.length() == 0 || length() == 0) {
- return null;
- }
- JSONObject jo = new JSONObject();
- for (int i = 0; i < names.length(); i += 1) {
- jo.put(names.getString(i), opt(i));
- }
- return jo;
- }
-
- /**
- * Make a JSON text of this JSONArray. For compactness, no unnecessary
- * whitespace is added. If it is not possible to produce a syntactically
- * correct JSON text then null will be returned instead. This could occur if
- * the array contains an invalid number.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @return a printable, displayable, transmittable representation of the
- * array.
- */
- @Override
- public String toString() {
- try {
- return '[' + join(",") + ']';
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * Make a prettyprinted JSON text of this JSONArray. Warning: This method
- * assumes that the data structure is acyclical.
- *
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @return a printable, displayable, transmittable representation of the
- * object, beginning with <code>[</code>&nbsp;<small>(left
- * bracket)</small> and ending with <code>]</code>
- * &nbsp;<small>(right bracket)</small>.
- * @throws JSONException
- */
- public String toString(int indentFactor) throws JSONException {
- return toString(indentFactor, 0);
- }
-
- /**
- * Make a prettyprinted JSON text of this JSONArray. Warning: This method
- * assumes that the data structure is acyclical.
- *
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @param indent
- * The indention of the top level.
- * @return a printable, displayable, transmittable representation of the
- * array.
- * @throws JSONException
- */
- String toString(int indentFactor, int indent) throws JSONException {
- int len = length();
- if (len == 0) {
- return "[]";
- }
- int i;
- StringBuffer sb = new StringBuffer("[");
- if (len == 1) {
- sb.append(JSONObject.valueToString(myArrayList.get(0),
- indentFactor, indent));
- } else {
- int newindent = indent + indentFactor;
- sb.append('\n');
- for (i = 0; i < len; i += 1) {
- if (i > 0) {
- sb.append(",\n");
- }
- for (int j = 0; j < newindent; j += 1) {
- sb.append(' ');
- }
- sb.append(JSONObject.valueToString(myArrayList.get(i),
- indentFactor, newindent));
- }
- sb.append('\n');
- for (i = 0; i < indent; i += 1) {
- sb.append(' ');
- }
- }
- sb.append(']');
- return sb.toString();
- }
-
- /**
- * Write the contents of the JSONArray as JSON text to a writer. For
- * compactness, no whitespace is added.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @return The writer.
- * @throws JSONException
- */
- public Writer write(Writer writer) throws JSONException {
- try {
- boolean b = false;
- int len = length();
-
- writer.write('[');
-
- for (int i = 0; i < len; i += 1) {
- if (b) {
- writer.write(',');
- }
- Object v = myArrayList.get(i);
- if (v instanceof JSONObject) {
- ((JSONObject) v).write(writer);
- } else if (v instanceof JSONArray) {
- ((JSONArray) v).write(writer);
- } else {
- writer.write(JSONObject.valueToString(v));
- }
- b = true;
- }
- writer.write(']');
- return writer;
- } catch (IOException e) {
- throw new JSONException(e);
- }
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/external/json/JSONException.java b/src/com/vaadin/external/json/JSONException.java
deleted file mode 100644
index 895ffcb457..0000000000
--- a/src/com/vaadin/external/json/JSONException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.vaadin.external.json;
-
-/**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
- *
- * @author JSON.org
- * @version 2010-12-24
- */
-public class JSONException extends Exception {
- private static final long serialVersionUID = 0;
- private Throwable cause;
-
- /**
- * Constructs a JSONException with an explanatory message.
- *
- * @param message
- * Detail about the reason for the exception.
- */
- public JSONException(String message) {
- super(message);
- }
-
- public JSONException(Throwable cause) {
- super(cause.getMessage());
- this.cause = cause;
- }
-
- @Override
- public Throwable getCause() {
- return this.cause;
- }
-}
diff --git a/src/com/vaadin/external/json/JSONObject.java b/src/com/vaadin/external/json/JSONObject.java
deleted file mode 100644
index ba772933be..0000000000
--- a/src/com/vaadin/external/json/JSONObject.java
+++ /dev/null
@@ -1,1693 +0,0 @@
-package com.vaadin.external.json;
-
-/*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-/**
- * A JSONObject is an unordered collection of name/value pairs. Its external
- * form is a string wrapped in curly braces with colons between the names and
- * values, and commas between the values and names. The internal form is an
- * object having <code>get</code> and <code>opt</code> methods for accessing the
- * values by name, and <code>put</code> methods for adding or replacing values
- * by name. The values can be any of these types: <code>Boolean</code>,
- * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
- * <code>String</code>, or the <code>JSONObject.NULL</code> object. A JSONObject
- * constructor can be used to convert an external form JSON text into an
- * internal form whose values can be retrieved with the <code>get</code> and
- * <code>opt</code> methods, or to convert values into a JSON text using the
- * <code>put</code> and <code>toString</code> methods. A <code>get</code> method
- * returns a value if one can be found, and throws an exception if one cannot be
- * found. An <code>opt</code> method returns a default value instead of throwing
- * an exception, and so is useful for obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an
- * object, which you can cast or query for type. There are also typed
- * <code>get</code> and <code>opt</code> methods that do type checking and type
- * coercion for you. The opt methods differ from the get methods in that they do
- * not throw. Instead, they return a specified value, such as null.
- * <p>
- * The <code>put</code> methods add or replace values in an object. For example,
- *
- * <pre>
- * myString = new JSONObject().put(&quot;JSON&quot;, &quot;Hello, World!&quot;).toString();
- * </pre>
- *
- * produces the string <code>{"JSON": "Hello, World"}</code>.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to
- * the JSON syntax rules. The constructors are more forgiving in the texts they
- * will accept:
- * <ul>
- * <li>An extra <code>,</code>&nbsp;<small>(comma)</small> may appear just
- * before the closing brace.</li>
- * <li>Strings may be quoted with <code>'</code>&nbsp;<small>(single
- * quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a quote
- * or single quote, and if they do not contain leading or trailing spaces, and
- * if they do not contain any of these characters:
- * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and
- * if they are not the reserved words <code>true</code>, <code>false</code>, or
- * <code>null</code>.</li>
- * <li>Keys can be followed by <code>=</code> or <code>=></code> as well as by
- * <code>:</code>.</li>
- * <li>Values can be followed by <code>;</code> <small>(semicolon)</small> as
- * well as by <code>,</code> <small>(comma)</small>.</li>
- * <li>Numbers may have the <code>0x-</code> <small>(hex)</small> prefix.</li>
- * </ul>
- *
- * @author JSON.org
- * @version 2011-10-16
- */
-public class JSONObject implements Serializable {
-
- /**
- * JSONObject.NULL is equivalent to the value that JavaScript calls null,
- * whilst Java's null is equivalent to the value that JavaScript calls
- * undefined.
- */
- private static final class Null implements Serializable {
-
- /**
- * There is only intended to be a single instance of the NULL object, so
- * the clone method returns itself.
- *
- * @return NULL.
- */
- @Override
- protected final Object clone() {
- return this;
- }
-
- /**
- * A Null object is equal to the null value and to itself.
- *
- * @param object
- * An object to test for nullness.
- * @return true if the object parameter is the JSONObject.NULL object or
- * null.
- */
- @Override
- public boolean equals(Object object) {
- return object == null || object == this;
- }
-
- /**
- * Get the "null" string value.
- *
- * @return The string "null".
- */
- @Override
- public String toString() {
- return "null";
- }
- }
-
- /**
- * The map where the JSONObject's properties are kept.
- */
- private Map map;
-
- /**
- * It is sometimes more convenient and less ambiguous to have a
- * <code>NULL</code> object than to use Java's <code>null</code> value.
- * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
- * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
- */
- public static final Object NULL = new Null();
-
- /**
- * Construct an empty JSONObject.
- */
- public JSONObject() {
- map = new HashMap();
- }
-
- /**
- * Construct a JSONObject from a subset of another JSONObject. An array of
- * strings is used to identify the keys that should be copied. Missing keys
- * are ignored.
- *
- * @param jo
- * A JSONObject.
- * @param names
- * An array of strings.
- * @throws JSONException
- * @exception JSONException
- * If a value is a non-finite number or if a name is
- * duplicated.
- */
- public JSONObject(JSONObject jo, String[] names) {
- this();
- for (int i = 0; i < names.length; i += 1) {
- try {
- putOnce(names[i], jo.opt(names[i]));
- } catch (Exception ignore) {
- }
- }
- }
-
- /**
- * Construct a JSONObject from a JSONTokener.
- *
- * @param x
- * A JSONTokener object containing the source string.
- * @throws JSONException
- * If there is a syntax error in the source string or a
- * duplicated key.
- */
- public JSONObject(JSONTokener x) throws JSONException {
- this();
- char c;
- String key;
-
- if (x.nextClean() != '{') {
- throw x.syntaxError("A JSONObject text must begin with '{'");
- }
- for (;;) {
- c = x.nextClean();
- switch (c) {
- case 0:
- throw x.syntaxError("A JSONObject text must end with '}'");
- case '}':
- return;
- default:
- x.back();
- key = x.nextValue().toString();
- }
-
- // The key is followed by ':'. We will also tolerate '=' or '=>'.
-
- c = x.nextClean();
- if (c == '=') {
- if (x.next() != '>') {
- x.back();
- }
- } else if (c != ':') {
- throw x.syntaxError("Expected a ':' after a key");
- }
- putOnce(key, x.nextValue());
-
- // Pairs are separated by ','. We will also tolerate ';'.
-
- switch (x.nextClean()) {
- case ';':
- case ',':
- if (x.nextClean() == '}') {
- return;
- }
- x.back();
- break;
- case '}':
- return;
- default:
- throw x.syntaxError("Expected a ',' or '}'");
- }
- }
- }
-
- /**
- * Construct a JSONObject from a Map.
- *
- * @param map
- * A map object that can be used to initialize the contents of
- * the JSONObject.
- * @throws JSONException
- */
- public JSONObject(Map map) {
- this.map = new HashMap();
- if (map != null) {
- Iterator i = map.entrySet().iterator();
- while (i.hasNext()) {
- Map.Entry e = (Map.Entry) i.next();
- Object value = e.getValue();
- if (value != null) {
- this.map.put(e.getKey(), wrap(value));
- }
- }
- }
- }
-
- /**
- * Construct a JSONObject from an Object using bean getters. It reflects on
- * all of the public methods of the object. For each of the methods with no
- * parameters and a name starting with <code>"get"</code> or
- * <code>"is"</code> followed by an uppercase letter, the method is invoked,
- * and a key and the value returned from the getter method are put into the
- * new JSONObject.
- *
- * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
- * prefix. If the second remaining character is not upper case, then the
- * first character is converted to lower case.
- *
- * For example, if an object has a method named <code>"getName"</code>, and
- * if the result of calling <code>object.getName()</code> is
- * <code>"Larry Fine"</code>, then the JSONObject will contain
- * <code>"name": "Larry Fine"</code>.
- *
- * @param bean
- * An object that has getter methods that should be used to make
- * a JSONObject.
- */
- public JSONObject(Object bean) {
- this();
- populateMap(bean);
- }
-
- /**
- * Construct a JSONObject from an Object, using reflection to find the
- * public members. The resulting JSONObject's keys will be the strings from
- * the names array, and the values will be the field values associated with
- * those keys in the object. If a key is not found or not visible, then it
- * will not be copied into the new JSONObject.
- *
- * @param object
- * An object that has fields that should be used to make a
- * JSONObject.
- * @param names
- * An array of strings, the names of the fields to be obtained
- * from the object.
- */
- public JSONObject(Object object, String names[]) {
- this();
- Class c = object.getClass();
- for (int i = 0; i < names.length; i += 1) {
- String name = names[i];
- try {
- putOpt(name, c.getField(name).get(object));
- } catch (Exception ignore) {
- }
- }
- }
-
- /**
- * Construct a JSONObject from a source JSON text string. This is the most
- * commonly used JSONObject constructor.
- *
- * @param source
- * A string beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>
- * &nbsp;<small>(right brace)</small>.
- * @exception JSONException
- * If there is a syntax error in the source string or a
- * duplicated key.
- */
- public JSONObject(String source) throws JSONException {
- this(new JSONTokener(source));
- }
-
- /**
- * Construct a JSONObject from a ResourceBundle.
- *
- * @param baseName
- * The ResourceBundle base name.
- * @param locale
- * The Locale to load the ResourceBundle for.
- * @throws JSONException
- * If any JSONExceptions are detected.
- */
- public JSONObject(String baseName, Locale locale) throws JSONException {
- this();
- ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
- Thread.currentThread().getContextClassLoader());
-
- // Iterate through the keys in the bundle.
-
- Enumeration keys = bundle.getKeys();
- while (keys.hasMoreElements()) {
- Object key = keys.nextElement();
- if (key instanceof String) {
-
- // Go through the path, ensuring that there is a nested
- // JSONObject for each
- // segment except the last. Add the value using the last
- // segment's name into
- // the deepest nested JSONObject.
-
- String[] path = ((String) key).split("\\.");
- int last = path.length - 1;
- JSONObject target = this;
- for (int i = 0; i < last; i += 1) {
- String segment = path[i];
- JSONObject nextTarget = target.optJSONObject(segment);
- if (nextTarget == null) {
- nextTarget = new JSONObject();
- target.put(segment, nextTarget);
- }
- target = nextTarget;
- }
- target.put(path[last], bundle.getString((String) key));
- }
- }
- }
-
- /**
- * Accumulate values under a key. It is similar to the put method except
- * that if there is already an object stored under the key then a JSONArray
- * is stored under the key to hold all of the accumulated values. If there
- * is already a JSONArray, then the new value is appended to it. In
- * contrast, the put method replaces the previous value.
- *
- * If only one value is accumulated that is not a JSONArray, then the result
- * will be the same as using put. But if multiple values are accumulated,
- * then the result will be like append.
- *
- * @param key
- * A key string.
- * @param value
- * An object to be accumulated under the key.
- * @return this.
- * @throws JSONException
- * If the value is an invalid number or if the key is null.
- */
- public JSONObject accumulate(String key, Object value) throws JSONException {
- testValidity(value);
- Object object = opt(key);
- if (object == null) {
- put(key, value instanceof JSONArray ? new JSONArray().put(value)
- : value);
- } else if (object instanceof JSONArray) {
- ((JSONArray) object).put(value);
- } else {
- put(key, new JSONArray().put(object).put(value));
- }
- return this;
- }
-
- /**
- * Append values to the array under a key. If the key does not exist in the
- * JSONObject, then the key is put in the JSONObject with its value being a
- * JSONArray containing the value parameter. If the key was already
- * associated with a JSONArray, then the value parameter is appended to it.
- *
- * @param key
- * A key string.
- * @param value
- * An object to be accumulated under the key.
- * @return this.
- * @throws JSONException
- * If the key is null or if the current value associated with
- * the key is not a JSONArray.
- */
- public JSONObject append(String key, Object value) throws JSONException {
- testValidity(value);
- Object object = opt(key);
- if (object == null) {
- put(key, new JSONArray().put(value));
- } else if (object instanceof JSONArray) {
- put(key, ((JSONArray) object).put(value));
- } else {
- throw new JSONException("JSONObject[" + key
- + "] is not a JSONArray.");
- }
- return this;
- }
-
- /**
- * Produce a string from a double. The string "null" will be returned if the
- * number is not finite.
- *
- * @param d
- * A double.
- * @return A String.
- */
- public static String doubleToString(double d) {
- if (Double.isInfinite(d) || Double.isNaN(d)) {
- return "null";
- }
-
- // Shave off trailing zeros and decimal point, if possible.
-
- String string = Double.toString(d);
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0
- && string.indexOf('E') < 0) {
- while (string.endsWith("0")) {
- string = string.substring(0, string.length() - 1);
- }
- if (string.endsWith(".")) {
- string = string.substring(0, string.length() - 1);
- }
- }
- return string;
- }
-
- /**
- * Get the value object associated with a key.
- *
- * @param key
- * A key string.
- * @return The object associated with the key.
- * @throws JSONException
- * if the key is not found.
- */
- public Object get(String key) throws JSONException {
- if (key == null) {
- throw new JSONException("Null key.");
- }
- Object object = opt(key);
- if (object == null) {
- throw new JSONException("JSONObject[" + quote(key) + "] not found.");
- }
- return object;
- }
-
- /**
- * Get the boolean value associated with a key.
- *
- * @param key
- * A key string.
- * @return The truth.
- * @throws JSONException
- * if the value is not a Boolean or the String "true" or
- * "false".
- */
- public boolean getBoolean(String key) throws JSONException {
- Object object = get(key);
- if (object.equals(Boolean.FALSE)
- || (object instanceof String && ((String) object)
- .equalsIgnoreCase("false"))) {
- return false;
- } else if (object.equals(Boolean.TRUE)
- || (object instanceof String && ((String) object)
- .equalsIgnoreCase("true"))) {
- return true;
- }
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not a Boolean.");
- }
-
- /**
- * Get the double value associated with a key.
- *
- * @param key
- * A key string.
- * @return The numeric value.
- * @throws JSONException
- * if the key is not found or if the value is not a Number
- * object and cannot be converted to a number.
- */
- public double getDouble(String key) throws JSONException {
- Object object = get(key);
- try {
- return object instanceof Number ? ((Number) object).doubleValue()
- : Double.parseDouble((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not a number.");
- }
- }
-
- /**
- * Get the int value associated with a key.
- *
- * @param key
- * A key string.
- * @return The integer value.
- * @throws JSONException
- * if the key is not found or if the value cannot be converted
- * to an integer.
- */
- public int getInt(String key) throws JSONException {
- Object object = get(key);
- try {
- return object instanceof Number ? ((Number) object).intValue()
- : Integer.parseInt((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not an int.");
- }
- }
-
- /**
- * Get the JSONArray value associated with a key.
- *
- * @param key
- * A key string.
- * @return A JSONArray which is the value.
- * @throws JSONException
- * if the key is not found or if the value is not a JSONArray.
- */
- public JSONArray getJSONArray(String key) throws JSONException {
- Object object = get(key);
- if (object instanceof JSONArray) {
- return (JSONArray) object;
- }
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not a JSONArray.");
- }
-
- /**
- * Get the JSONObject value associated with a key.
- *
- * @param key
- * A key string.
- * @return A JSONObject which is the value.
- * @throws JSONException
- * if the key is not found or if the value is not a JSONObject.
- */
- public JSONObject getJSONObject(String key) throws JSONException {
- Object object = get(key);
- if (object instanceof JSONObject) {
- return (JSONObject) object;
- }
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not a JSONObject.");
- }
-
- /**
- * Get the long value associated with a key.
- *
- * @param key
- * A key string.
- * @return The long value.
- * @throws JSONException
- * if the key is not found or if the value cannot be converted
- * to a long.
- */
- public long getLong(String key) throws JSONException {
- Object object = get(key);
- try {
- return object instanceof Number ? ((Number) object).longValue()
- : Long.parseLong((String) object);
- } catch (Exception e) {
- throw new JSONException("JSONObject[" + quote(key)
- + "] is not a long.");
- }
- }
-
- /**
- * Get an array of field names from a JSONObject.
- *
- * @return An array of field names, or null if there are no names.
- */
- public static String[] getNames(JSONObject jo) {
- int length = jo.length();
- if (length == 0) {
- return null;
- }
- Iterator iterator = jo.keys();
- String[] names = new String[length];
- int i = 0;
- while (iterator.hasNext()) {
- names[i] = (String) iterator.next();
- i += 1;
- }
- return names;
- }
-
- /**
- * Get an array of field names from an Object.
- *
- * @return An array of field names, or null if there are no names.
- */
- public static String[] getNames(Object object) {
- if (object == null) {
- return null;
- }
- Class klass = object.getClass();
- Field[] fields = klass.getFields();
- int length = fields.length;
- if (length == 0) {
- return null;
- }
- String[] names = new String[length];
- for (int i = 0; i < length; i += 1) {
- names[i] = fields[i].getName();
- }
- return names;
- }
-
- /**
- * Get the string associated with a key.
- *
- * @param key
- * A key string.
- * @return A string which is the value.
- * @throws JSONException
- * if there is no string value for the key.
- */
- public String getString(String key) throws JSONException {
- Object object = get(key);
- if (object instanceof String) {
- return (String) object;
- }
- throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
- }
-
- /**
- * Determine if the JSONObject contains a specific key.
- *
- * @param key
- * A key string.
- * @return true if the key exists in the JSONObject.
- */
- public boolean has(String key) {
- return map.containsKey(key);
- }
-
- /**
- * Increment a property of a JSONObject. If there is no such property,
- * create one with a value of 1. If there is such a property, and if it is
- * an Integer, Long, Double, or Float, then add one to it.
- *
- * @param key
- * A key string.
- * @return this.
- * @throws JSONException
- * If there is already a property with this name that is not an
- * Integer, Long, Double, or Float.
- */
- public JSONObject increment(String key) throws JSONException {
- Object value = opt(key);
- if (value == null) {
- put(key, 1);
- } else if (value instanceof Integer) {
- put(key, ((Integer) value).intValue() + 1);
- } else if (value instanceof Long) {
- put(key, ((Long) value).longValue() + 1);
- } else if (value instanceof Double) {
- put(key, ((Double) value).doubleValue() + 1);
- } else if (value instanceof Float) {
- put(key, ((Float) value).floatValue() + 1);
- } else {
- throw new JSONException("Unable to increment [" + quote(key) + "].");
- }
- return this;
- }
-
- /**
- * Determine if the value associated with the key is null or if there is no
- * value.
- *
- * @param key
- * A key string.
- * @return true if there is no value associated with the key or if the value
- * is the JSONObject.NULL object.
- */
- public boolean isNull(String key) {
- return JSONObject.NULL.equals(opt(key));
- }
-
- /**
- * Get an enumeration of the keys of the JSONObject.
- *
- * @return An iterator of the keys.
- */
- public Iterator keys() {
- return map.keySet().iterator();
- }
-
- /**
- * Get the number of keys stored in the JSONObject.
- *
- * @return The number of keys in the JSONObject.
- */
- public int length() {
- return map.size();
- }
-
- /**
- * Produce a JSONArray containing the names of the elements of this
- * JSONObject.
- *
- * @return A JSONArray containing the key strings, or null if the JSONObject
- * is empty.
- */
- public JSONArray names() {
- JSONArray ja = new JSONArray();
- Iterator keys = keys();
- while (keys.hasNext()) {
- ja.put(keys.next());
- }
- return ja.length() == 0 ? null : ja;
- }
-
- /**
- * Produce a string from a Number.
- *
- * @param number
- * A Number
- * @return A String.
- * @throws JSONException
- * If n is a non-finite number.
- */
- public static String numberToString(Number number) throws JSONException {
- if (number == null) {
- throw new JSONException("Null pointer");
- }
- testValidity(number);
-
- // Shave off trailing zeros and decimal point, if possible.
-
- String string = number.toString();
- if (string.indexOf('.') > 0 && string.indexOf('e') < 0
- && string.indexOf('E') < 0) {
- while (string.endsWith("0")) {
- string = string.substring(0, string.length() - 1);
- }
- if (string.endsWith(".")) {
- string = string.substring(0, string.length() - 1);
- }
- }
- return string;
- }
-
- /**
- * Get an optional value associated with a key.
- *
- * @param key
- * A key string.
- * @return An object which is the value, or null if there is no value.
- */
- public Object opt(String key) {
- return key == null ? null : map.get(key);
- }
-
- /**
- * Get an optional boolean associated with a key. It returns false if there
- * is no such key, or if the value is not Boolean.TRUE or the String "true".
- *
- * @param key
- * A key string.
- * @return The truth.
- */
- public boolean optBoolean(String key) {
- return optBoolean(key, false);
- }
-
- /**
- * Get an optional boolean associated with a key. It returns the
- * defaultValue if there is no such key, or if it is not a Boolean or the
- * String "true" or "false" (case insensitive).
- *
- * @param key
- * A key string.
- * @param defaultValue
- * The default.
- * @return The truth.
- */
- public boolean optBoolean(String key, boolean defaultValue) {
- try {
- return getBoolean(key);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get an optional double associated with a key, or NaN if there is no such
- * key or if its value is not a number. If the value is a string, an attempt
- * will be made to evaluate it as a number.
- *
- * @param key
- * A string which is the key.
- * @return An object which is the value.
- */
- public double optDouble(String key) {
- return optDouble(key, Double.NaN);
- }
-
- /**
- * Get an optional double associated with a key, or the defaultValue if
- * there is no such key or if its value is not a number. If the value is a
- * string, an attempt will be made to evaluate it as a number.
- *
- * @param key
- * A key string.
- * @param defaultValue
- * The default.
- * @return An object which is the value.
- */
- public double optDouble(String key, double defaultValue) {
- try {
- return getDouble(key);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get an optional int value associated with a key, or zero if there is no
- * such key or if the value is not a number. If the value is a string, an
- * attempt will be made to evaluate it as a number.
- *
- * @param key
- * A key string.
- * @return An object which is the value.
- */
- public int optInt(String key) {
- return optInt(key, 0);
- }
-
- /**
- * Get an optional int value associated with a key, or the default if there
- * is no such key or if the value is not a number. If the value is a string,
- * an attempt will be made to evaluate it as a number.
- *
- * @param key
- * A key string.
- * @param defaultValue
- * The default.
- * @return An object which is the value.
- */
- public int optInt(String key, int defaultValue) {
- try {
- return getInt(key);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get an optional JSONArray associated with a key. It returns null if there
- * is no such key, or if its value is not a JSONArray.
- *
- * @param key
- * A key string.
- * @return A JSONArray which is the value.
- */
- public JSONArray optJSONArray(String key) {
- Object o = opt(key);
- return o instanceof JSONArray ? (JSONArray) o : null;
- }
-
- /**
- * Get an optional JSONObject associated with a key. It returns null if
- * there is no such key, or if its value is not a JSONObject.
- *
- * @param key
- * A key string.
- * @return A JSONObject which is the value.
- */
- public JSONObject optJSONObject(String key) {
- Object object = opt(key);
- return object instanceof JSONObject ? (JSONObject) object : null;
- }
-
- /**
- * Get an optional long value associated with a key, or zero if there is no
- * such key or if the value is not a number. If the value is a string, an
- * attempt will be made to evaluate it as a number.
- *
- * @param key
- * A key string.
- * @return An object which is the value.
- */
- public long optLong(String key) {
- return optLong(key, 0);
- }
-
- /**
- * Get an optional long value associated with a key, or the default if there
- * is no such key or if the value is not a number. If the value is a string,
- * an attempt will be made to evaluate it as a number.
- *
- * @param key
- * A key string.
- * @param defaultValue
- * The default.
- * @return An object which is the value.
- */
- public long optLong(String key, long defaultValue) {
- try {
- return getLong(key);
- } catch (Exception e) {
- return defaultValue;
- }
- }
-
- /**
- * Get an optional string associated with a key. It returns an empty string
- * if there is no such key. If the value is not a string and is not null,
- * then it is converted to a string.
- *
- * @param key
- * A key string.
- * @return A string which is the value.
- */
- public String optString(String key) {
- return optString(key, "");
- }
-
- /**
- * Get an optional string associated with a key. It returns the defaultValue
- * if there is no such key.
- *
- * @param key
- * A key string.
- * @param defaultValue
- * The default.
- * @return A string which is the value.
- */
- public String optString(String key, String defaultValue) {
- Object object = opt(key);
- return NULL.equals(object) ? defaultValue : object.toString();
- }
-
- private void populateMap(Object bean) {
- Class klass = bean.getClass();
-
- // If klass is a System class then set includeSuperClass to false.
-
- boolean includeSuperClass = klass.getClassLoader() != null;
-
- Method[] methods = (includeSuperClass) ? klass.getMethods() : klass
- .getDeclaredMethods();
- for (int i = 0; i < methods.length; i += 1) {
- try {
- Method method = methods[i];
- if (Modifier.isPublic(method.getModifiers())) {
- String name = method.getName();
- String key = "";
- if (name.startsWith("get")) {
- if (name.equals("getClass")
- || name.equals("getDeclaringClass")) {
- key = "";
- } else {
- key = name.substring(3);
- }
- } else if (name.startsWith("is")) {
- key = name.substring(2);
- }
- if (key.length() > 0
- && Character.isUpperCase(key.charAt(0))
- && method.getParameterTypes().length == 0) {
- if (key.length() == 1) {
- key = key.toLowerCase();
- } else if (!Character.isUpperCase(key.charAt(1))) {
- key = key.substring(0, 1).toLowerCase()
- + key.substring(1);
- }
-
- Object result = method.invoke(bean, (Object[]) null);
- if (result != null) {
- map.put(key, wrap(result));
- }
- }
- }
- } catch (Exception ignore) {
- }
- }
- }
-
- /**
- * Put a key/boolean pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A boolean which is the value.
- * @return this.
- * @throws JSONException
- * If the key is null.
- */
- public JSONObject put(String key, boolean value) throws JSONException {
- put(key, value ? Boolean.TRUE : Boolean.FALSE);
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject, where the value will be a
- * JSONArray which is produced from a Collection.
- *
- * @param key
- * A key string.
- * @param value
- * A Collection value.
- * @return this.
- * @throws JSONException
- */
- public JSONObject put(String key, Collection value) throws JSONException {
- put(key, new JSONArray(value));
- return this;
- }
-
- /**
- * Put a key/double pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A double which is the value.
- * @return this.
- * @throws JSONException
- * If the key is null or if the number is invalid.
- */
- public JSONObject put(String key, double value) throws JSONException {
- put(key, new Double(value));
- return this;
- }
-
- /**
- * Put a key/int pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * An int which is the value.
- * @return this.
- * @throws JSONException
- * If the key is null.
- */
- public JSONObject put(String key, int value) throws JSONException {
- put(key, new Integer(value));
- return this;
- }
-
- /**
- * Put a key/long pair in the JSONObject.
- *
- * @param key
- * A key string.
- * @param value
- * A long which is the value.
- * @return this.
- * @throws JSONException
- * If the key is null.
- */
- public JSONObject put(String key, long value) throws JSONException {
- put(key, new Long(value));
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject, where the value will be a
- * JSONObject which is produced from a Map.
- *
- * @param key
- * A key string.
- * @param value
- * A Map value.
- * @return this.
- * @throws JSONException
- */
- public JSONObject put(String key, Map value) throws JSONException {
- put(key, new JSONObject(value));
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject. If the value is null, then the
- * key will be removed from the JSONObject if it is present.
- *
- * @param key
- * A key string.
- * @param value
- * An object which is the value. It should be of one of these
- * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
- * String, or the JSONObject.NULL object.
- * @return this.
- * @throws JSONException
- * If the value is non-finite number or if the key is null.
- */
- public JSONObject put(String key, Object value) throws JSONException {
- if (key == null) {
- throw new JSONException("Null key.");
- }
- if (value != null) {
- testValidity(value);
- map.put(key, value);
- } else {
- remove(key);
- }
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject, but only if the key and the value
- * are both non-null, and only if there is not already a member with that
- * name.
- *
- * @param key
- * @param value
- * @return his.
- * @throws JSONException
- * if the key is a duplicate
- */
- public JSONObject putOnce(String key, Object value) throws JSONException {
- if (key != null && value != null) {
- if (opt(key) != null) {
- throw new JSONException("Duplicate key \"" + key + "\"");
- }
- put(key, value);
- }
- return this;
- }
-
- /**
- * Put a key/value pair in the JSONObject, but only if the key and the value
- * are both non-null.
- *
- * @param key
- * A key string.
- * @param value
- * An object which is the value. It should be of one of these
- * types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
- * String, or the JSONObject.NULL object.
- * @return this.
- * @throws JSONException
- * If the value is a non-finite number.
- */
- public JSONObject putOpt(String key, Object value) throws JSONException {
- if (key != null && value != null) {
- put(key, value);
- }
- return this;
- }
-
- /**
- * Produce a string in double quotes with backslash sequences in all the
- * right places. A backslash will be inserted within </, producing <\/,
- * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
- * contain a control character or an unescaped quote or backslash.
- *
- * @param string
- * A String
- * @return A String correctly formatted for insertion in a JSON text.
- */
- public static String quote(String string) {
- if (string == null || string.length() == 0) {
- return "\"\"";
- }
-
- char b;
- char c = 0;
- String hhhh;
- int i;
- int len = string.length();
- StringBuffer sb = new StringBuffer(len + 4);
-
- sb.append('"');
- for (i = 0; i < len; i += 1) {
- b = c;
- c = string.charAt(i);
- switch (c) {
- case '\\':
- case '"':
- sb.append('\\');
- sb.append(c);
- break;
- case '/':
- if (b == '<') {
- sb.append('\\');
- }
- sb.append(c);
- break;
- case '\b':
- sb.append("\\b");
- break;
- case '\t':
- sb.append("\\t");
- break;
- case '\n':
- sb.append("\\n");
- break;
- case '\f':
- sb.append("\\f");
- break;
- case '\r':
- sb.append("\\r");
- break;
- default:
- if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
- || (c >= '\u2000' && c < '\u2100')) {
- hhhh = "000" + Integer.toHexString(c);
- sb.append("\\u" + hhhh.substring(hhhh.length() - 4));
- } else {
- sb.append(c);
- }
- }
- }
- sb.append('"');
- return sb.toString();
- }
-
- /**
- * Remove a name and its value, if present.
- *
- * @param key
- * The name to be removed.
- * @return The value that was associated with the name, or null if there was
- * no value.
- */
- public Object remove(String key) {
- return map.remove(key);
- }
-
- /**
- * Try to convert a string into a number, boolean, or null. If the string
- * can't be converted, return the string.
- *
- * @param string
- * A String.
- * @return A simple JSON value.
- */
- public static Object stringToValue(String string) {
- Double d;
- if (string.equals("")) {
- return string;
- }
- if (string.equalsIgnoreCase("true")) {
- return Boolean.TRUE;
- }
- if (string.equalsIgnoreCase("false")) {
- return Boolean.FALSE;
- }
- if (string.equalsIgnoreCase("null")) {
- return JSONObject.NULL;
- }
-
- /*
- * If it might be a number, try converting it. We support the
- * non-standard 0x- convention. If a number cannot be produced, then the
- * value will just be a string. Note that the 0x-, plus, and implied
- * string conventions are non-standard. A JSON parser may accept
- * non-JSON forms as long as it accepts all correct JSON forms.
- */
-
- char b = string.charAt(0);
- if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
- if (b == '0' && string.length() > 2
- && (string.charAt(1) == 'x' || string.charAt(1) == 'X')) {
- try {
- return new Integer(
- Integer.parseInt(string.substring(2), 16));
- } catch (Exception ignore) {
- }
- }
- try {
- if (string.indexOf('.') > -1 || string.indexOf('e') > -1
- || string.indexOf('E') > -1) {
- d = Double.valueOf(string);
- if (!d.isInfinite() && !d.isNaN()) {
- return d;
- }
- } else {
- Long myLong = new Long(string);
- if (myLong.longValue() == myLong.intValue()) {
- return new Integer(myLong.intValue());
- } else {
- return myLong;
- }
- }
- } catch (Exception ignore) {
- }
- }
- return string;
- }
-
- /**
- * Throw an exception if the object is a NaN or infinite number.
- *
- * @param o
- * The object to test.
- * @throws JSONException
- * If o is a non-finite number.
- */
- public static void testValidity(Object o) throws JSONException {
- if (o != null) {
- if (o instanceof Double) {
- if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
- throw new JSONException(
- "JSON does not allow non-finite numbers.");
- }
- } else if (o instanceof Float) {
- if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
- throw new JSONException(
- "JSON does not allow non-finite numbers.");
- }
- }
- }
- }
-
- /**
- * Produce a JSONArray containing the values of the members of this
- * JSONObject.
- *
- * @param names
- * A JSONArray containing a list of key strings. This determines
- * the sequence of the values in the result.
- * @return A JSONArray of values.
- * @throws JSONException
- * If any of the values are non-finite numbers.
- */
- public JSONArray toJSONArray(JSONArray names) throws JSONException {
- if (names == null || names.length() == 0) {
- return null;
- }
- JSONArray ja = new JSONArray();
- for (int i = 0; i < names.length(); i += 1) {
- ja.put(opt(names.getString(i)));
- }
- return ja;
- }
-
- /**
- * Make a JSON text of this JSONObject. For compactness, no whitespace is
- * added. If this would not result in a syntactically correct JSON text,
- * then null will be returned instead.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @return a printable, displayable, portable, transmittable representation
- * of the object, beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
- * brace)</small>.
- */
- @Override
- public String toString() {
- try {
- Iterator keys = keys();
- StringBuffer sb = new StringBuffer("{");
-
- while (keys.hasNext()) {
- if (sb.length() > 1) {
- sb.append(',');
- }
- Object o = keys.next();
- sb.append(quote(o.toString()));
- sb.append(':');
- sb.append(valueToString(map.get(o)));
- }
- sb.append('}');
- return sb.toString();
- } catch (Exception e) {
- return null;
- }
- }
-
- /**
- * Make a prettyprinted JSON text of this JSONObject.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @return a printable, displayable, portable, transmittable representation
- * of the object, beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
- * brace)</small>.
- * @throws JSONException
- * If the object contains an invalid number.
- */
- public String toString(int indentFactor) throws JSONException {
- return toString(indentFactor, 0);
- }
-
- /**
- * Make a prettyprinted JSON text of this JSONObject.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @param indent
- * The indentation of the top level.
- * @return a printable, displayable, transmittable representation of the
- * object, beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
- * brace)</small>.
- * @throws JSONException
- * If the object contains an invalid number.
- */
- String toString(int indentFactor, int indent) throws JSONException {
- int i;
- int length = length();
- if (length == 0) {
- return "{}";
- }
- Iterator keys = keys();
- int newindent = indent + indentFactor;
- Object object;
- StringBuffer sb = new StringBuffer("{");
- if (length == 1) {
- object = keys.next();
- sb.append(quote(object.toString()));
- sb.append(": ");
- sb.append(valueToString(map.get(object), indentFactor, indent));
- } else {
- while (keys.hasNext()) {
- object = keys.next();
- if (sb.length() > 1) {
- sb.append(",\n");
- } else {
- sb.append('\n');
- }
- for (i = 0; i < newindent; i += 1) {
- sb.append(' ');
- }
- sb.append(quote(object.toString()));
- sb.append(": ");
- sb.append(valueToString(map.get(object), indentFactor,
- newindent));
- }
- if (sb.length() > 1) {
- sb.append('\n');
- for (i = 0; i < indent; i += 1) {
- sb.append(' ');
- }
- }
- }
- sb.append('}');
- return sb.toString();
- }
-
- /**
- * Make a JSON text of an Object value. If the object has an
- * value.toJSONString() method, then that method will be used to produce the
- * JSON text. The method is required to produce a strictly conforming text.
- * If the object does not contain a toJSONString method (which is the most
- * common case), then a text will be produced by other means. If the value
- * is an array or Collection, then a JSONArray will be made from it and its
- * toJSONString method will be called. If the value is a MAP, then a
- * JSONObject will be made from it and its toJSONString method will be
- * called. Otherwise, the value's toString method will be called, and the
- * result will be quoted.
- *
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @param value
- * The value to be serialized.
- * @return a printable, displayable, transmittable representation of the
- * object, beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
- * brace)</small>.
- * @throws JSONException
- * If the value is or contains an invalid number.
- */
- public static String valueToString(Object value) throws JSONException {
- if (value == null || value.equals(null)) {
- return "null";
- }
- if (value instanceof JSONString) {
- Object object;
- try {
- object = ((JSONString) value).toJSONString();
- } catch (Exception e) {
- throw new JSONException(e);
- }
- if (object instanceof String) {
- return (String) object;
- }
- throw new JSONException("Bad value from toJSONString: " + object);
- }
- if (value instanceof Number) {
- return numberToString((Number) value);
- }
- if (value instanceof Boolean || value instanceof JSONObject
- || value instanceof JSONArray) {
- return value.toString();
- }
- if (value instanceof Map) {
- return new JSONObject((Map) value).toString();
- }
- if (value instanceof Collection) {
- return new JSONArray((Collection) value).toString();
- }
- if (value.getClass().isArray()) {
- return new JSONArray(value).toString();
- }
- return quote(value.toString());
- }
-
- /**
- * Make a prettyprinted JSON text of an object value.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @param value
- * The value to be serialized.
- * @param indentFactor
- * The number of spaces to add to each level of indentation.
- * @param indent
- * The indentation of the top level.
- * @return a printable, displayable, transmittable representation of the
- * object, beginning with <code>{</code>&nbsp;<small>(left
- * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
- * brace)</small>.
- * @throws JSONException
- * If the object contains an invalid number.
- */
- static String valueToString(Object value, int indentFactor, int indent)
- throws JSONException {
- if (value == null || value.equals(null)) {
- return "null";
- }
- try {
- if (value instanceof JSONString) {
- Object o = ((JSONString) value).toJSONString();
- if (o instanceof String) {
- return (String) o;
- }
- }
- } catch (Exception ignore) {
- }
- if (value instanceof Number) {
- return numberToString((Number) value);
- }
- if (value instanceof Boolean) {
- return value.toString();
- }
- if (value instanceof JSONObject) {
- return ((JSONObject) value).toString(indentFactor, indent);
- }
- if (value instanceof JSONArray) {
- return ((JSONArray) value).toString(indentFactor, indent);
- }
- if (value instanceof Map) {
- return new JSONObject((Map) value).toString(indentFactor, indent);
- }
- if (value instanceof Collection) {
- return new JSONArray((Collection) value).toString(indentFactor,
- indent);
- }
- if (value.getClass().isArray()) {
- return new JSONArray(value).toString(indentFactor, indent);
- }
- return quote(value.toString());
- }
-
- /**
- * Wrap an object, if necessary. If the object is null, return the NULL
- * object. If it is an array or collection, wrap it in a JSONArray. If it is
- * a map, wrap it in a JSONObject. If it is a standard property (Double,
- * String, et al) then it is already wrapped. Otherwise, if it comes from
- * one of the java packages, turn it into a string. And if it doesn't, try
- * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
- *
- * @param object
- * The object to wrap
- * @return The wrapped value
- */
- public static Object wrap(Object object) {
- try {
- if (object == null) {
- return NULL;
- }
- if (object instanceof JSONObject || object instanceof JSONArray
- || NULL.equals(object) || object instanceof JSONString
- || object instanceof Byte || object instanceof Character
- || object instanceof Short || object instanceof Integer
- || object instanceof Long || object instanceof Boolean
- || object instanceof Float || object instanceof Double
- || object instanceof String) {
- return object;
- }
-
- if (object instanceof Collection) {
- return new JSONArray((Collection) object);
- }
- if (object.getClass().isArray()) {
- return new JSONArray(object);
- }
- if (object instanceof Map) {
- return new JSONObject((Map) object);
- }
- Package objectPackage = object.getClass().getPackage();
- String objectPackageName = objectPackage != null ? objectPackage
- .getName() : "";
- if (objectPackageName.startsWith("java.")
- || objectPackageName.startsWith("javax.")
- || object.getClass().getClassLoader() == null) {
- return object.toString();
- }
- return new JSONObject(object);
- } catch (Exception exception) {
- return null;
- }
- }
-
- /**
- * Write the contents of the JSONObject as JSON text to a writer. For
- * compactness, no whitespace is added.
- * <p>
- * Warning: This method assumes that the data structure is acyclical.
- *
- * @return The writer.
- * @throws JSONException
- */
- public Writer write(Writer writer) throws JSONException {
- try {
- boolean commanate = false;
- Iterator keys = keys();
- writer.write('{');
-
- while (keys.hasNext()) {
- if (commanate) {
- writer.write(',');
- }
- Object key = keys.next();
- writer.write(quote(key.toString()));
- writer.write(':');
- Object value = map.get(key);
- if (value instanceof JSONObject) {
- ((JSONObject) value).write(writer);
- } else if (value instanceof JSONArray) {
- ((JSONArray) value).write(writer);
- } else {
- writer.write(valueToString(value));
- }
- commanate = true;
- }
- writer.write('}');
- return writer;
- } catch (IOException exception) {
- throw new JSONException(exception);
- }
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/external/json/JSONString.java b/src/com/vaadin/external/json/JSONString.java
deleted file mode 100644
index cc7e4d8c07..0000000000
--- a/src/com/vaadin/external/json/JSONString.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.vaadin.external.json;
-
-import java.io.Serializable;
-
-/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
- * method so that a class can change the behavior of
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>, and
- * <code>JSONWriter.value(</code>Object<code>)</code>. The
- * <code>toJSONString</code> method will be used instead of the default behavior
- * of using the Object's <code>toString()</code> method and quoting the result.
- */
-public interface JSONString extends Serializable {
- /**
- * The <code>toJSONString</code> method allows a class to produce its own
- * JSON serialization.
- *
- * @return A strictly syntactically correct JSON text.
- */
- public String toJSONString();
-}
diff --git a/src/com/vaadin/external/json/JSONStringer.java b/src/com/vaadin/external/json/JSONStringer.java
deleted file mode 100644
index ae905cb15f..0000000000
--- a/src/com/vaadin/external/json/JSONStringer.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.vaadin.external.json;
-
-/*
- Copyright (c) 2006 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-import java.io.StringWriter;
-
-/**
- * JSONStringer provides a quick and convenient way of producing JSON text. The
- * texts produced strictly conform to JSON syntax rules. No whitespace is added,
- * so the results are ready for transmission or storage. Each instance of
- * JSONStringer can produce one JSON text.
- * <p>
- * A JSONStringer instance provides a <code>value</code> method for appending
- * values to the text, and a <code>key</code> method for adding keys before
- * values in objects. There are <code>array</code> and <code>endArray</code>
- * methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting cascade style. For
- * example,
- *
- * <pre>
- * myString = new JSONStringer().object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
- * .endObject().toString();
- * </pre>
- *
- * which produces the string
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONStringer adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- *
- * @author JSON.org
- * @version 2008-09-18
- */
-public class JSONStringer extends JSONWriter {
- /**
- * Make a fresh JSONStringer. It can be used to build one JSON text.
- */
- public JSONStringer() {
- super(new StringWriter());
- }
-
- /**
- * Return the JSON text. This method is used to obtain the product of the
- * JSONStringer instance. It will return <code>null</code> if there was a
- * problem in the construction of the JSON text (such as the calls to
- * <code>array</code> were not properly balanced with calls to
- * <code>endArray</code>).
- *
- * @return The JSON text.
- */
- @Override
- public String toString() {
- return this.mode == 'd' ? this.writer.toString() : null;
- }
-}
diff --git a/src/com/vaadin/external/json/JSONTokener.java b/src/com/vaadin/external/json/JSONTokener.java
deleted file mode 100644
index c3531cae1d..0000000000
--- a/src/com/vaadin/external/json/JSONTokener.java
+++ /dev/null
@@ -1,451 +0,0 @@
-package com.vaadin.external.json;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.Serializable;
-import java.io.StringReader;
-
-/*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * A JSONTokener takes a source string and extracts characters and tokens from
- * it. It is used by the JSONObject and JSONArray constructors to parse JSON
- * source strings.
- *
- * @author JSON.org
- * @version 2010-12-24
- */
-public class JSONTokener implements Serializable {
-
- private int character;
- private boolean eof;
- private int index;
- private int line;
- private char previous;
- private Reader reader;
- private boolean usePrevious;
-
- /**
- * Construct a JSONTokener from a Reader.
- *
- * @param reader
- * A reader.
- */
- public JSONTokener(Reader reader) {
- this.reader = reader.markSupported() ? reader : new BufferedReader(
- reader);
- eof = false;
- usePrevious = false;
- previous = 0;
- index = 0;
- character = 1;
- line = 1;
- }
-
- /**
- * Construct a JSONTokener from an InputStream.
- */
- public JSONTokener(InputStream inputStream) throws JSONException {
- this(new InputStreamReader(inputStream));
- }
-
- /**
- * Construct a JSONTokener from a string.
- *
- * @param s
- * A source string.
- */
- public JSONTokener(String s) {
- this(new StringReader(s));
- }
-
- /**
- * Back up one character. This provides a sort of lookahead capability, so
- * that you can test for a digit or letter before attempting to parse the
- * next number or identifier.
- */
- public void back() throws JSONException {
- if (usePrevious || index <= 0) {
- throw new JSONException("Stepping back two steps is not supported");
- }
- index -= 1;
- character -= 1;
- usePrevious = true;
- eof = false;
- }
-
- /**
- * Get the hex value of a character (base16).
- *
- * @param c
- * A character between '0' and '9' or between 'A' and 'F' or
- * between 'a' and 'f'.
- * @return An int between 0 and 15, or -1 if c was not a hex digit.
- */
- public static int dehexchar(char c) {
- if (c >= '0' && c <= '9') {
- return c - '0';
- }
- if (c >= 'A' && c <= 'F') {
- return c - ('A' - 10);
- }
- if (c >= 'a' && c <= 'f') {
- return c - ('a' - 10);
- }
- return -1;
- }
-
- public boolean end() {
- return eof && !usePrevious;
- }
-
- /**
- * Determine if the source string still contains characters that next() can
- * consume.
- *
- * @return true if not yet at the end of the source.
- */
- public boolean more() throws JSONException {
- next();
- if (end()) {
- return false;
- }
- back();
- return true;
- }
-
- /**
- * Get the next character in the source string.
- *
- * @return The next character, or 0 if past the end of the source string.
- */
- public char next() throws JSONException {
- int c;
- if (usePrevious) {
- usePrevious = false;
- c = previous;
- } else {
- try {
- c = reader.read();
- } catch (IOException exception) {
- throw new JSONException(exception);
- }
-
- if (c <= 0) { // End of stream
- eof = true;
- c = 0;
- }
- }
- index += 1;
- if (previous == '\r') {
- line += 1;
- character = c == '\n' ? 0 : 1;
- } else if (c == '\n') {
- line += 1;
- character = 0;
- } else {
- character += 1;
- }
- previous = (char) c;
- return previous;
- }
-
- /**
- * Consume the next character, and check that it matches a specified
- * character.
- *
- * @param c
- * The character to match.
- * @return The character.
- * @throws JSONException
- * if the character does not match.
- */
- public char next(char c) throws JSONException {
- char n = next();
- if (n != c) {
- throw syntaxError("Expected '" + c + "' and instead saw '" + n
- + "'");
- }
- return n;
- }
-
- /**
- * Get the next n characters.
- *
- * @param n
- * The number of characters to take.
- * @return A string of n characters.
- * @throws JSONException
- * Substring bounds error if there are not n characters
- * remaining in the source string.
- */
- public String next(int n) throws JSONException {
- if (n == 0) {
- return "";
- }
-
- char[] chars = new char[n];
- int pos = 0;
-
- while (pos < n) {
- chars[pos] = next();
- if (end()) {
- throw syntaxError("Substring bounds error");
- }
- pos += 1;
- }
- return new String(chars);
- }
-
- /**
- * Get the next char in the string, skipping whitespace.
- *
- * @throws JSONException
- * @return A character, or 0 if there are no more characters.
- */
- public char nextClean() throws JSONException {
- for (;;) {
- char c = next();
- if (c == 0 || c > ' ') {
- return c;
- }
- }
- }
-
- /**
- * Return the characters up to the next close quote character. Backslash
- * processing is done. The formal JSON format does not allow strings in
- * single quotes, but an implementation is allowed to accept them.
- *
- * @param quote
- * The quoting character, either <code>"</code>
- * &nbsp;<small>(double quote)</small> or <code>'</code>
- * &nbsp;<small>(single quote)</small>.
- * @return A String.
- * @throws JSONException
- * Unterminated string.
- */
- public String nextString(char quote) throws JSONException {
- char c;
- StringBuffer sb = new StringBuffer();
- for (;;) {
- c = next();
- switch (c) {
- case 0:
- case '\n':
- case '\r':
- throw syntaxError("Unterminated string");
- case '\\':
- c = next();
- switch (c) {
- case 'b':
- sb.append('\b');
- break;
- case 't':
- sb.append('\t');
- break;
- case 'n':
- sb.append('\n');
- break;
- case 'f':
- sb.append('\f');
- break;
- case 'r':
- sb.append('\r');
- break;
- case 'u':
- sb.append((char) Integer.parseInt(next(4), 16));
- break;
- case '"':
- case '\'':
- case '\\':
- case '/':
- sb.append(c);
- break;
- default:
- throw syntaxError("Illegal escape.");
- }
- break;
- default:
- if (c == quote) {
- return sb.toString();
- }
- sb.append(c);
- }
- }
- }
-
- /**
- * Get the text up but not including the specified character or the end of
- * line, whichever comes first.
- *
- * @param delimiter
- * A delimiter character.
- * @return A string.
- */
- public String nextTo(char delimiter) throws JSONException {
- StringBuffer sb = new StringBuffer();
- for (;;) {
- char c = next();
- if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
- if (c != 0) {
- back();
- }
- return sb.toString().trim();
- }
- sb.append(c);
- }
- }
-
- /**
- * Get the text up but not including one of the specified delimiter
- * characters or the end of line, whichever comes first.
- *
- * @param delimiters
- * A set of delimiter characters.
- * @return A string, trimmed.
- */
- public String nextTo(String delimiters) throws JSONException {
- char c;
- StringBuffer sb = new StringBuffer();
- for (;;) {
- c = next();
- if (delimiters.indexOf(c) >= 0 || c == 0 || c == '\n' || c == '\r') {
- if (c != 0) {
- back();
- }
- return sb.toString().trim();
- }
- sb.append(c);
- }
- }
-
- /**
- * Get the next value. The value can be a Boolean, Double, Integer,
- * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
- *
- * @throws JSONException
- * If syntax error.
- *
- * @return An object.
- */
- public Object nextValue() throws JSONException {
- char c = nextClean();
- String string;
-
- switch (c) {
- case '"':
- case '\'':
- return nextString(c);
- case '{':
- back();
- return new JSONObject(this);
- case '[':
- back();
- return new JSONArray(this);
- }
-
- /*
- * Handle unquoted text. This could be the values true, false, or null,
- * or it can be a number. An implementation (such as this one) is
- * allowed to also accept non-standard forms.
- *
- * Accumulate characters until we reach the end of the text or a
- * formatting character.
- */
-
- StringBuffer sb = new StringBuffer();
- while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
- sb.append(c);
- c = next();
- }
- back();
-
- string = sb.toString().trim();
- if (string.equals("")) {
- throw syntaxError("Missing value");
- }
- return JSONObject.stringToValue(string);
- }
-
- /**
- * Skip characters until the next character is the requested character. If
- * the requested character is not found, no characters are skipped.
- *
- * @param to
- * A character to skip to.
- * @return The requested character, or zero if the requested character is
- * not found.
- */
- public char skipTo(char to) throws JSONException {
- char c;
- try {
- int startIndex = index;
- int startCharacter = character;
- int startLine = line;
- reader.mark(Integer.MAX_VALUE);
- do {
- c = next();
- if (c == 0) {
- reader.reset();
- index = startIndex;
- character = startCharacter;
- line = startLine;
- return c;
- }
- } while (c != to);
- } catch (IOException exc) {
- throw new JSONException(exc);
- }
-
- back();
- return c;
- }
-
- /**
- * Make a JSONException to signal a syntax error.
- *
- * @param message
- * The error message.
- * @return A JSONException object, suitable for throwing
- */
- public JSONException syntaxError(String message) {
- return new JSONException(message + toString());
- }
-
- /**
- * Make a printable string of this JSONTokener.
- *
- * @return " at {index} [character {character} line {line}]"
- */
- @Override
- public String toString() {
- return " at " + index + " [character " + character + " line " + line
- + "]";
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/external/json/JSONWriter.java b/src/com/vaadin/external/json/JSONWriter.java
deleted file mode 100644
index 5f9ddeeae2..0000000000
--- a/src/com/vaadin/external/json/JSONWriter.java
+++ /dev/null
@@ -1,355 +0,0 @@
-package com.vaadin.external.json;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-
-/*
- Copyright (c) 2006 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONWriter provides a quick and convenient way of producing JSON text. The
- * texts produced strictly conform to JSON syntax rules. No whitespace is added,
- * so the results are ready for transmission or storage. Each instance of
- * JSONWriter can produce one JSON text.
- * <p>
- * A JSONWriter instance provides a <code>value</code> method for appending
- * values to the text, and a <code>key</code> method for adding keys before
- * values in objects. There are <code>array</code> and <code>endArray</code>
- * methods that make and bound array values, and <code>object</code> and
- * <code>endObject</code> methods which make and bound object values. All of
- * these methods return the JSONWriter instance, permitting a cascade style. For
- * example,
- *
- * <pre>
- * new JSONWriter(myWriter).object().key(&quot;JSON&quot;).value(&quot;Hello, World!&quot;)
- * .endObject();
- * </pre>
- *
- * which writes
- *
- * <pre>
- * {"JSON":"Hello, World!"}
- * </pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONWriter adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- *
- * @author JSON.org
- * @version 2011-11-14
- */
-public class JSONWriter implements Serializable {
- private static final int maxdepth = 200;
-
- /**
- * The comma flag determines if a comma should be output before the next
- * value.
- */
- private boolean comma;
-
- /**
- * The current mode. Values: 'a' (array), 'd' (done), 'i' (initial), 'k'
- * (key), 'o' (object).
- */
- protected char mode;
-
- /**
- * The object/array stack.
- */
- private final JSONObject stack[];
-
- /**
- * The stack top index. A value of 0 indicates that the stack is empty.
- */
- private int top;
-
- /**
- * The writer that will receive the output.
- */
- protected Writer writer;
-
- /**
- * Make a fresh JSONWriter. It can be used to build one JSON text.
- */
- public JSONWriter(Writer w) {
- comma = false;
- mode = 'i';
- stack = new JSONObject[maxdepth];
- top = 0;
- writer = w;
- }
-
- /**
- * Append a value.
- *
- * @param string
- * A string value.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- private JSONWriter append(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null pointer");
- }
- if (mode == 'o' || mode == 'a') {
- try {
- if (comma && mode == 'a') {
- writer.write(',');
- }
- writer.write(string);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- if (mode == 'o') {
- mode = 'k';
- }
- comma = true;
- return this;
- }
- throw new JSONException("Value out of sequence.");
- }
-
- /**
- * Begin appending a new array. All values until the balancing
- * <code>endArray</code> will be appended to this array. The
- * <code>endArray</code> method must be called to mark the array's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter array() throws JSONException {
- if (mode == 'i' || mode == 'o' || mode == 'a') {
- push(null);
- append("[");
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced array.");
- }
-
- /**
- * End something.
- *
- * @param mode
- * Mode
- * @param c
- * Closing character
- * @return this
- * @throws JSONException
- * If unbalanced.
- */
- private JSONWriter end(char mode, char c) throws JSONException {
- if (this.mode != mode) {
- throw new JSONException(mode == 'a' ? "Misplaced endArray."
- : "Misplaced endObject.");
- }
- pop(mode);
- try {
- writer.write(c);
- } catch (IOException e) {
- throw new JSONException(e);
- }
- comma = true;
- return this;
- }
-
- /**
- * End an array. This method most be called to balance calls to
- * <code>array</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endArray() throws JSONException {
- return end('a', ']');
- }
-
- /**
- * End an object. This method most be called to balance calls to
- * <code>object</code>.
- *
- * @return this
- * @throws JSONException
- * If incorrectly nested.
- */
- public JSONWriter endObject() throws JSONException {
- return end('k', '}');
- }
-
- /**
- * Append a key. The key will be associated with the next value. In an
- * object, every value must be preceded by a key.
- *
- * @param string
- * A key string.
- * @return this
- * @throws JSONException
- * If the key is out of place. For example, keys do not belong
- * in arrays or if the key is null.
- */
- public JSONWriter key(String string) throws JSONException {
- if (string == null) {
- throw new JSONException("Null key.");
- }
- if (mode == 'k') {
- try {
- stack[top - 1].putOnce(string, Boolean.TRUE);
- if (comma) {
- writer.write(',');
- }
- writer.write(JSONObject.quote(string));
- writer.write(':');
- comma = false;
- mode = 'o';
- return this;
- } catch (IOException e) {
- throw new JSONException(e);
- }
- }
- throw new JSONException("Misplaced key.");
- }
-
- /**
- * Begin appending a new object. All keys and values until the balancing
- * <code>endObject</code> will be appended to this object. The
- * <code>endObject</code> method must be called to mark the object's end.
- *
- * @return this
- * @throws JSONException
- * If the nesting is too deep, or if the object is started in
- * the wrong place (for example as a key or after the end of the
- * outermost array or object).
- */
- public JSONWriter object() throws JSONException {
- if (mode == 'i') {
- mode = 'o';
- }
- if (mode == 'o' || mode == 'a') {
- append("{");
- push(new JSONObject());
- comma = false;
- return this;
- }
- throw new JSONException("Misplaced object.");
-
- }
-
- /**
- * Pop an array or object scope.
- *
- * @param c
- * The scope to close.
- * @throws JSONException
- * If nesting is wrong.
- */
- private void pop(char c) throws JSONException {
- if (top <= 0) {
- throw new JSONException("Nesting error.");
- }
- char m = stack[top - 1] == null ? 'a' : 'k';
- if (m != c) {
- throw new JSONException("Nesting error.");
- }
- top -= 1;
- mode = top == 0 ? 'd' : stack[top - 1] == null ? 'a' : 'k';
- }
-
- /**
- * Push an array or object scope.
- *
- * @param c
- * The scope to open.
- * @throws JSONException
- * If nesting is too deep.
- */
- private void push(JSONObject jo) throws JSONException {
- if (top >= maxdepth) {
- throw new JSONException("Nesting too deep.");
- }
- stack[top] = jo;
- mode = jo == null ? 'a' : 'k';
- top += 1;
- }
-
- /**
- * Append either the value <code>true</code> or the value <code>false</code>
- * .
- *
- * @param b
- * A boolean.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(boolean b) throws JSONException {
- return append(b ? "true" : "false");
- }
-
- /**
- * Append a double value.
- *
- * @param d
- * A double.
- * @return this
- * @throws JSONException
- * If the number is not finite.
- */
- public JSONWriter value(double d) throws JSONException {
- return this.value(new Double(d));
- }
-
- /**
- * Append a long value.
- *
- * @param l
- * A long.
- * @return this
- * @throws JSONException
- */
- public JSONWriter value(long l) throws JSONException {
- return append(Long.toString(l));
- }
-
- /**
- * Append an object value.
- *
- * @param object
- * The object to append. It can be null, or a Boolean, Number,
- * String, JSONObject, or JSONArray, or an object that implements
- * JSONString.
- * @return this
- * @throws JSONException
- * If the value is out of sequence.
- */
- public JSONWriter value(Object object) throws JSONException {
- return append(JSONObject.valueToString(object));
- }
-}
diff --git a/src/com/vaadin/external/json/README b/src/com/vaadin/external/json/README
deleted file mode 100644
index ca6dc11764..0000000000
--- a/src/com/vaadin/external/json/README
+++ /dev/null
@@ -1,68 +0,0 @@
-JSON in Java [package org.json]
-
-Douglas Crockford
-douglas@crockford.com
-
-2011-02-02
-
-
-JSON is a light-weight, language independent, data interchange format.
-See http://www.JSON.org/
-
-The files in this package implement JSON encoders/decoders in Java.
-It also includes the capability to convert between JSON and XML, HTTP
-headers, Cookies, and CDL.
-
-This is a reference implementation. There is a large number of JSON packages
-in Java. Perhaps someday the Java community will standardize on one. Until
-then, choose carefully.
-
-The license includes this restriction: "The software shall be used for good,
-not evil." If your conscience cannot live with that, then choose a different
-package.
-
-The package compiles on Java 1.2 thru Java 1.4.
-
-
-JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
-to produce a map-like object. The object provides methods for manipulating its
-contents, and for producing a JSON compliant object serialization.
-
-JSONArray.java: The JSONObject can parse text from a String or a JSONTokener
-to produce a vector-like object. The object provides methods for manipulating
-its contents, and for producing a JSON compliant array serialization.
-
-JSONTokener.java: The JSONTokener breaks a text into a sequence of individual
-tokens. It can be constructed from a String, Reader, or InputStream.
-
-JSONException.java: The JSONException is the standard exception type thrown
-by this package.
-
-
-JSONString.java: The JSONString interface requires a toJSONString method,
-allowing an object to provide its own serialization.
-
-JSONStringer.java: The JSONStringer provides a convenient facility for
-building JSON strings.
-
-JSONWriter.java: The JSONWriter provides a convenient facility for building
-JSON text through a writer.
-
-
-CDL.java: CDL provides support for converting between JSON and comma
-delimited lists.
-
-Cookie.java: Cookie provides support for converting between JSON and cookies.
-
-CookieList.java: CookieList provides support for converting between JSON and
-cookie lists.
-
-HTTP.java: HTTP provides support for converting between JSON and HTTP headers.
-
-HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers.
-
-XML.java: XML provides support for converting between JSON and XML.
-
-JSONML.java: JSONML provides support for converting between JSONML and XML.
-
-XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text. \ No newline at end of file
diff --git a/src/com/vaadin/navigator/FragmentManager.java b/src/com/vaadin/navigator/FragmentManager.java
deleted file mode 100644
index f1fd90e569..0000000000
--- a/src/com/vaadin/navigator/FragmentManager.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.navigator;
-
-import java.io.Serializable;
-
-/**
- * Fragment manager that handles interaction between Navigator and URI fragments
- * or other similar view identification and bookmarking system.
- *
- * Alternative implementations can be created for HTML5 pushState, for portlet
- * URL navigation and other similar systems.
- *
- * This interface is mostly for internal use by {@link Navigator}.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public interface FragmentManager extends Serializable {
- /**
- * Return the current fragment (location string) including view name and any
- * optional parameters.
- *
- * @return current view and parameter string, not null
- */
- public String getFragment();
-
- /**
- * Set the current fragment (location string) in the application URL or
- * similar location, including view name and any optional parameters.
- *
- * @param fragment
- * new view and parameter string, not null
- */
- public void setFragment(String fragment);
-} \ No newline at end of file
diff --git a/src/com/vaadin/navigator/Navigator.java b/src/com/vaadin/navigator/Navigator.java
deleted file mode 100644
index 1813301fe6..0000000000
--- a/src/com/vaadin/navigator/Navigator.java
+++ /dev/null
@@ -1,656 +0,0 @@
-package com.vaadin.navigator;
-
-/*
- @VaadinApache2LicenseForJavaFiles@
- */
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
-import com.vaadin.terminal.Page;
-import com.vaadin.terminal.Page.FragmentChangedEvent;
-import com.vaadin.terminal.Page.FragmentChangedListener;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.CssLayout;
-import com.vaadin.ui.CustomComponent;
-
-/**
- * Navigator utility that allows switching of views in a part of an application.
- *
- * The view switching can be based e.g. on URI fragments containing the view
- * name and parameters to the view. There are two types of parameters for views:
- * an optional parameter string that is included in the fragment (may be
- * bookmarkable).
- *
- * Views can be explicitly registered or dynamically generated and listening to
- * view changes is possible.
- *
- * Note that {@link Navigator} is not a component itself but comes with
- * {@link SimpleViewDisplay} which is a component that displays the selected
- * view as its contents.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public class Navigator implements Serializable {
-
- // TODO divert navigation e.g. if no permissions? Or just show another view
- // but keep URL? how best to intercept
- // TODO investigate relationship with TouchKit navigation support
-
- /**
- * Empty view component.
- */
- public static class EmptyView extends CssLayout implements View {
- /**
- * Create minimally sized empty view.
- */
- public EmptyView() {
- setWidth("0px");
- setHeight("0px");
- }
-
- @Override
- public void navigateTo(String fragmentParameters) {
- // nothing to do
- }
- }
-
- /**
- * Fragment manager using URI fragments of a Page to track views and enable
- * listening to view changes.
- *
- * This class is mostly for internal use by Navigator, and is only public
- * and static to enable testing.
- */
- public static class UriFragmentManager implements FragmentManager,
- FragmentChangedListener {
- private final Page page;
- private final Navigator navigator;
-
- /**
- * Create a new URIFragmentManager and attach it to listen to URI
- * fragment changes of a {@link Page}.
- *
- * @param page
- * page whose URI fragment to get and modify
- * @param navigator
- * {@link Navigator} to notify of fragment changes (using
- * {@link Navigator#navigateTo(String)}
- */
- public UriFragmentManager(Page page, Navigator navigator) {
- this.page = page;
- this.navigator = navigator;
-
- page.addListener(this);
- }
-
- @Override
- public String getFragment() {
- return page.getFragment();
- }
-
- @Override
- public void setFragment(String fragment) {
- page.setFragment(fragment, false);
- }
-
- @Override
- public void fragmentChanged(FragmentChangedEvent event) {
- UriFragmentManager.this.navigator.navigateTo(getFragment());
- }
- }
-
- /**
- * View display that is a component itself and replaces its contents with
- * the view.
- *
- * This display only supports views that are {@link Component}s themselves.
- * Attempting to display a view that is not a component causes an exception
- * to be thrown.
- *
- * By default, the view display has full size.
- */
- public static class SimpleViewDisplay extends CustomComponent implements
- ViewDisplay {
-
- /**
- * Create new {@link ViewDisplay} that is itself a component displaying
- * the view.
- */
- public SimpleViewDisplay() {
- setSizeFull();
- }
-
- @Override
- public void showView(View view) {
- if (view instanceof Component) {
- setCompositionRoot((Component) view);
- } else {
- throw new IllegalArgumentException("View is not a component: "
- + view);
- }
- }
- }
-
- /**
- * View display that replaces the contents of a {@link ComponentContainer}
- * with the active {@link View}.
- *
- * All components of the container are removed before adding the new view to
- * it.
- *
- * This display only supports views that are {@link Component}s themselves.
- * Attempting to display a view that is not a component causes an exception
- * to be thrown.
- */
- public static class ComponentContainerViewDisplay implements ViewDisplay {
-
- private final ComponentContainer container;
-
- /**
- * Create new {@link ViewDisplay} that updates a
- * {@link ComponentContainer} to show the view.
- */
- public ComponentContainerViewDisplay(ComponentContainer container) {
- this.container = container;
- }
-
- @Override
- public void showView(View view) {
- if (view instanceof Component) {
- container.removeAllComponents();
- container.addComponent((Component) view);
- } else {
- throw new IllegalArgumentException("View is not a component: "
- + view);
- }
- }
- }
-
- /**
- * View provider which supports mapping a single view name to a single
- * pre-initialized view instance.
- *
- * For most cases, ClassBasedViewProvider should be used instead of this.
- */
- public static class StaticViewProvider implements ViewProvider {
- private final String viewName;
- private final View view;
-
- /**
- * Create a new view provider which returns a pre-created view instance.
- *
- * @param viewName
- * name of the view (not null)
- * @param view
- * view instance to return (not null), reused on every
- * request
- */
- public StaticViewProvider(String viewName, View view) {
- this.viewName = viewName;
- this.view = view;
- }
-
- @Override
- public String getViewName(String viewAndParameters) {
- if (null == viewAndParameters) {
- return null;
- }
- if (viewAndParameters.startsWith(viewName)) {
- return viewName;
- }
- return null;
- }
-
- @Override
- public View getView(String viewName) {
- if (this.viewName.equals(viewName)) {
- return view;
- }
- return null;
- }
-
- /**
- * Get the view name for this provider.
- *
- * @return view name for this provider
- */
- public String getViewName() {
- return viewName;
- }
- }
-
- /**
- * View provider which maps a single view name to a class to instantiate for
- * the view.
- *
- * Note that the view class must be accessible by the class loader used by
- * the provider. This may require its visibility to be public.
- *
- * This class is primarily for internal use by {@link Navigator}.
- */
- public static class ClassBasedViewProvider implements ViewProvider {
-
- private final String viewName;
- private final Class<? extends View> viewClass;
-
- /**
- * Create a new view provider which creates new view instances based on
- * a view class.
- *
- * @param viewName
- * name of the views to create (not null)
- * @param viewClass
- * class to instantiate when a view is requested (not null)
- */
- public ClassBasedViewProvider(String viewName,
- Class<? extends View> viewClass) {
- if (null == viewName || null == viewClass) {
- throw new IllegalArgumentException(
- "View name and class should not be null");
- }
- this.viewName = viewName;
- this.viewClass = viewClass;
- }
-
- @Override
- public String getViewName(String viewAndParameters) {
- if (null == viewAndParameters) {
- return null;
- }
- if (viewAndParameters.equals(viewName)
- || viewAndParameters.startsWith(viewName + "/")) {
- return viewName;
- }
- return null;
- }
-
- @Override
- public View getView(String viewName) {
- if (this.viewName.equals(viewName)) {
- try {
- View view = viewClass.newInstance();
- return view;
- } catch (InstantiationException e) {
- // TODO error handling
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- // TODO error handling
- throw new RuntimeException(e);
- }
- }
- return null;
- }
-
- /**
- * Get the view name for this provider.
- *
- * @return view name for this provider
- */
- public String getViewName() {
- return viewName;
- }
-
- /**
- * Get the view class for this provider.
- *
- * @return {@link View} class
- */
- public Class<? extends View> getViewClass() {
- return viewClass;
- }
- }
-
- private final FragmentManager fragmentManager;
- private final ViewDisplay display;
- private View currentView = null;
- private List<ViewChangeListener> listeners = new LinkedList<ViewChangeListener>();
- private List<ViewProvider> providers = new LinkedList<ViewProvider>();
-
- /**
- * Create a navigator that is tracking the active view using URI fragments
- * of the current {@link Page} and replacing the contents of a
- * {@link ComponentContainer} with the active view.
- *
- * In case the container is not on the current page, use another
- * {@link Navigator#Navigator(Page, ViewDisplay)} with an explicitly created
- * {@link ComponentContainerViewDisplay}.
- *
- * All components of the container are removed each time before adding the
- * active {@link View}. Views must implement {@link Component} when using
- * this constructor.
- *
- * <p>
- * After all {@link View}s and {@link ViewProvider}s have been registered,
- * the application should trigger navigation to the current fragment using
- * e.g.
- *
- * <pre>
- * navigator.navigateTo(Page.getCurrent().getFragment());
- * </pre>
- *
- * @param container
- * ComponentContainer whose contents should be replaced with the
- * active view on view change
- */
- public Navigator(ComponentContainer container) {
- display = new ComponentContainerViewDisplay(container);
- fragmentManager = new UriFragmentManager(Page.getCurrent(), this);
- }
-
- /**
- * Create a navigator that is tracking the active view using URI fragments.
- *
- * <p>
- * After all {@link View}s and {@link ViewProvider}s have been registered,
- * the application should trigger navigation to the current fragment using
- * e.g.
- *
- * <pre>
- * navigator.navigateTo(Page.getCurrent().getFragment());
- * </pre>
- *
- * @param page
- * whose URI fragments are used
- * @param display
- * where to display the views
- */
- public Navigator(Page page, ViewDisplay display) {
- this.display = display;
- fragmentManager = new UriFragmentManager(page, this);
- }
-
- /**
- * Create a navigator.
- *
- * When a custom fragment manager is not needed, use the constructor
- * {@link #Navigator(Page, ViewDisplay)} which uses a URI fragment based
- * fragment manager.
- *
- * Note that navigation to the initial view must be performed explicitly by
- * the application after creating a Navigator using this constructor.
- *
- * @param fragmentManager
- * fragment manager keeping track of the active view and enabling
- * bookmarking and direct navigation
- * @param display
- * where to display the views
- */
- public Navigator(FragmentManager fragmentManager, ViewDisplay display) {
- this.display = display;
- this.fragmentManager = fragmentManager;
- }
-
- /**
- * Navigate to a view and initialize the view with given parameters.
- *
- * The view string consists of a view name optionally followed by a slash
- * and (fragment) parameters. ViewProviders are used to find and create the
- * correct type of view.
- *
- * If multiple providers return a matching view, the view with the longest
- * name is selected. This way, e.g. hierarchies of subviews can be
- * registered like "admin/", "admin/users", "admin/settings" and the longest
- * match is used.
- *
- * If the view being deactivated indicates it wants a confirmation for the
- * navigation operation, the user is asked for the confirmation.
- *
- * Registered {@link ViewChangeListener}s are called upon successful view
- * change.
- *
- * @param viewAndParameters
- * view name and parameters
- */
- public void navigateTo(String viewAndParameters) {
- String longestViewName = null;
- View viewWithLongestName = null;
- for (ViewProvider provider : providers) {
- String viewName = provider.getViewName(viewAndParameters);
- if (null != viewName
- && (longestViewName == null || viewName.length() > longestViewName
- .length())) {
- View view = provider.getView(viewName);
- if (null != view) {
- longestViewName = viewName;
- viewWithLongestName = view;
- }
- }
- }
- if (viewWithLongestName != null) {
- String parameters = null;
- if (viewAndParameters.length() > longestViewName.length() + 1) {
- parameters = viewAndParameters.substring(longestViewName
- .length() + 1);
- }
- navigateTo(viewWithLongestName, longestViewName, parameters);
- }
- // TODO if no view is found, what to do?
- }
-
- /**
- * Internal method activating a view, setting its parameters and calling
- * listeners.
- *
- * This method also verifies that the user is allowed to perform the
- * navigation operation.
- *
- * @param view
- * view to activate
- * @param viewName
- * (optional) name of the view or null not to set the fragment
- * @param fragmentParameters
- * parameters passed in the fragment for the view
- */
- protected void navigateTo(View view, String viewName,
- String fragmentParameters) {
- ViewChangeEvent event = new ViewChangeEvent(this, currentView, view,
- viewName, fragmentParameters);
- if (!isViewChangeAllowed(event)) {
- return;
- }
-
- if (null != viewName && getFragmentManager() != null) {
- String currentFragment = viewName;
- if (fragmentParameters != null) {
- currentFragment += "/" + fragmentParameters;
- }
- if (!currentFragment.equals(getFragmentManager().getFragment())) {
- getFragmentManager().setFragment(currentFragment);
- }
- }
-
- view.navigateTo(fragmentParameters);
- currentView = view;
-
- if (display != null) {
- display.showView(view);
- }
-
- fireViewChange(event);
- }
-
- /**
- * Check whether view change is allowed.
- *
- * All related listeners are called. The view change is blocked if any of
- * them wants to block the navigation operation.
- *
- * The view change listeners may also e.g. open a warning or question dialog
- * and save the parameters to re-initiate the navigation operation upon user
- * action.
- *
- * @param event
- * view change event (not null, view change not yet performed)
- * @return true if the view change should be allowed, false to silently
- * block the navigation operation
- */
- protected boolean isViewChangeAllowed(ViewChangeEvent event) {
- for (ViewChangeListener l : listeners) {
- if (!l.isViewChangeAllowed(event)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Return the fragment manager that is used to get, listen to and manipulate
- * the URI fragment or other source of navigation information.
- *
- * @return fragment manager in use
- */
- protected FragmentManager getFragmentManager() {
- return fragmentManager;
- }
-
- /**
- * Returns the ViewDisplay used by the navigator. Unless another display is
- * specified, a {@link SimpleViewDisplay} (which is a {@link Component}) is
- * used by default.
- *
- * @return current ViewDisplay
- */
- public ViewDisplay getDisplay() {
- return display;
- }
-
- /**
- * Fire an event when the current view has changed.
- *
- * @param event
- * view change event (not null)
- */
- protected void fireViewChange(ViewChangeEvent event) {
- for (ViewChangeListener l : listeners) {
- l.navigatorViewChanged(event);
- }
- }
-
- /**
- * Register a static, pre-initialized view instance for a view name.
- *
- * Registering another view with a name that is already registered
- * overwrites the old registration of the same type.
- *
- * @param viewName
- * String that identifies a view (not null nor empty string)
- * @param view
- * {@link View} instance (not null)
- */
- public void addView(String viewName, View view) {
-
- // Check parameters
- if (viewName == null || view == null) {
- throw new IllegalArgumentException(
- "view and viewName must be non-null");
- }
-
- removeView(viewName);
- registerProvider(new StaticViewProvider(viewName, view));
- }
-
- /**
- * Register for a view name a view class.
- *
- * Registering another view with a name that is already registered
- * overwrites the old registration of the same type.
- *
- * A new view instance is created every time a view is requested.
- *
- * @param viewName
- * String that identifies a view (not null nor empty string)
- * @param viewClass
- * {@link View} class to instantiate when a view is requested
- * (not null)
- */
- public void addView(String viewName, Class<? extends View> viewClass) {
-
- // Check parameters
- if (viewName == null || viewClass == null) {
- throw new IllegalArgumentException(
- "view and viewClass must be non-null");
- }
-
- removeView(viewName);
- registerProvider(new ClassBasedViewProvider(viewName, viewClass));
- }
-
- /**
- * Remove view from navigator.
- *
- * This method only applies to views registered using
- * {@link #addView(String, View)} or {@link #addView(String, Class)}.
- *
- * @param viewName
- * name of the view to remove
- */
- public void removeView(String viewName) {
- Iterator<ViewProvider> it = providers.iterator();
- while (it.hasNext()) {
- ViewProvider provider = it.next();
- if (provider instanceof StaticViewProvider) {
- StaticViewProvider staticProvider = (StaticViewProvider) provider;
- if (staticProvider.getViewName().equals(viewName)) {
- it.remove();
- }
- } else if (provider instanceof ClassBasedViewProvider) {
- ClassBasedViewProvider classBasedProvider = (ClassBasedViewProvider) provider;
- if (classBasedProvider.getViewName().equals(viewName)) {
- it.remove();
- }
- }
- }
- }
-
- /**
- * Register a view provider (factory).
- *
- * Providers are called in order of registration until one that can handle
- * the requested view name is found.
- *
- * @param provider
- * provider to register
- */
- public void registerProvider(ViewProvider provider) {
- providers.add(provider);
- }
-
- /**
- * Unregister a view provider (factory).
- *
- * @param provider
- * provider to unregister
- */
- public void unregisterProvider(ViewProvider provider) {
- providers.remove(provider);
- }
-
- /**
- * Listen to changes of the active view.
- *
- * The listener will get notified after the view has changed.
- *
- * @param listener
- * Listener to invoke after view changes.
- */
- public void addListener(ViewChangeListener listener) {
- listeners.add(listener);
- }
-
- /**
- * Remove a view change listener.
- *
- * @param listener
- * Listener to remove.
- */
- public void removeListener(ViewChangeListener listener) {
- listeners.remove(listener);
- }
-
-}
diff --git a/src/com/vaadin/navigator/View.java b/src/com/vaadin/navigator/View.java
deleted file mode 100644
index 4d135b4c0b..0000000000
--- a/src/com/vaadin/navigator/View.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.navigator;
-
-import java.io.Serializable;
-
-import com.vaadin.ui.Component;
-
-/**
- * Interface for all views controlled by the navigator.
- *
- * Each view added to the navigator must implement this interface. Typically, a
- * view is a {@link Component}.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public interface View extends Serializable {
-
- /**
- * This view is navigated to.
- *
- * This method is always called before the view is shown on screen. If there
- * is any additional id to data what should be shown in the view, it is also
- * optionally passed as parameter.
- *
- * TODO fragmentParameters null if no parameters or empty string?
- *
- * @param fragmentParameters
- * parameters to the view or null if none given. This is the
- * string that appears e.g. in URI after "viewname/"
- */
- public void navigateTo(String fragmentParameters);
-} \ No newline at end of file
diff --git a/src/com/vaadin/navigator/ViewChangeListener.java b/src/com/vaadin/navigator/ViewChangeListener.java
deleted file mode 100644
index 2eb34e6fcf..0000000000
--- a/src/com/vaadin/navigator/ViewChangeListener.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.navigator;
-
-import java.io.Serializable;
-import java.util.EventObject;
-
-/**
- * Interface for listening to View changes before and after they occur.
- *
- * Implementations of this interface can also block navigation between views
- * before it is performed.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public interface ViewChangeListener extends Serializable {
-
- /**
- * Event received by the listener for attempted and executed view changes.
- */
- public static class ViewChangeEvent extends EventObject {
- private final View oldView;
- private final View newView;
- private final String viewName;
- private final String fragmentParameters;
-
- /**
- * Create a new view change event.
- *
- * @param navigator
- * Navigator that triggered the event, not null
- */
- public ViewChangeEvent(Navigator navigator, View oldView, View newView,
- String viewName, String fragmentParameters) {
- super(navigator);
- this.oldView = oldView;
- this.newView = newView;
- this.viewName = viewName;
- this.fragmentParameters = fragmentParameters;
- }
-
- /**
- * Returns the navigator that triggered this event.
- *
- * @return Navigator (not null)
- */
- public Navigator getNavigator() {
- return (Navigator) getSource();
- }
-
- /**
- * Returns the view being deactivated.
- *
- * @return old View
- */
- public View getOldView() {
- return oldView;
- }
-
- /**
- * Returns the view being activated.
- *
- * @return new View
- */
- public View getNewView() {
- return newView;
- }
-
- /**
- * Returns the view name of the view being activated.
- *
- * @return view name of the new View
- */
- public String getViewName() {
- return viewName;
- }
-
- /**
- * Returns the parameters for the view being activated.
- *
- * @return fragment parameters (potentially bookmarkable) for the new
- * view
- */
- public String getFragmentParameters() {
- return fragmentParameters;
- }
- }
-
- /**
- * Check whether changing the view is permissible.
- *
- * This method may also e.g. open a "save" dialog or question about the
- * change, which may re-initiate the navigation operation after user action.
- *
- * If this listener does not want to block the view change (e.g. does not
- * know the view in question), it should return true. If any listener
- * returns false, the view change is not allowed.
- *
- * @param event
- * view change event
- * @return true if the view change should be allowed or this listener does
- * not care about the view change, false to block the change
- */
- public boolean isViewChangeAllowed(ViewChangeEvent event);
-
- /**
- * Invoked after the view has changed. Be careful for deadlocks if you
- * decide to change the view again in the listener.
- *
- * @param event
- * view change event
- */
- public void navigatorViewChanged(ViewChangeEvent event);
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/navigator/ViewDisplay.java b/src/com/vaadin/navigator/ViewDisplay.java
deleted file mode 100644
index 6016951394..0000000000
--- a/src/com/vaadin/navigator/ViewDisplay.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.navigator;
-
-import java.io.Serializable;
-
-/**
- * Interface for displaying a view in an appropriate location.
- *
- * The view display can be a component/layout itself or can modify a separate
- * layout.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public interface ViewDisplay extends Serializable {
- /**
- * Remove previously shown view and show the newly selected view in its
- * place.
- *
- * The parameters for the view have been set before this method is called.
- *
- * @param view
- * new view to show
- */
- public void showView(View view);
-} \ No newline at end of file
diff --git a/src/com/vaadin/navigator/ViewProvider.java b/src/com/vaadin/navigator/ViewProvider.java
deleted file mode 100644
index 4d9d22acab..0000000000
--- a/src/com/vaadin/navigator/ViewProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.navigator;
-
-import java.io.Serializable;
-
-/**
- * A provider for view instances that can return pre-registered views or
- * dynamically create new views.
- *
- * If multiple providers are used, {@link #getViewName(String)} of each is
- * called (in registration order) until one of them returns a non-null value.
- * The {@link #getView(String)} method of that provider is then used.
- *
- * @author Vaadin Ltd
- * @since 7.0
- */
-public interface ViewProvider extends Serializable {
- /**
- * Extract the view name from a combined view name and parameter string.
- * This method should return a view name if and only if this provider
- * handles creation of such views.
- *
- * @param viewAndParameters
- * string with view name and its fragment parameters (if given),
- * not null
- * @return view name if the view is handled by this provider, null otherwise
- */
- public String getViewName(String viewAndParameters);
-
- /**
- * Create or return a pre-created instance of a view.
- *
- * The parameters for the view are set separately by the navigator when the
- * view is activated.
- *
- * @param viewName
- * name of the view, not null
- * @return newly created view (null if none available for the view name)
- */
- public View getView(String viewName);
-} \ No newline at end of file
diff --git a/src/com/vaadin/package.html b/src/com/vaadin/package.html
deleted file mode 100644
index f771019709..0000000000
--- a/src/com/vaadin/package.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-
-<p>The Vaadin base package. Contains the Application class, the
-starting point of any application that uses Vaadin.</p>
-
-<p>Contains all Vaadin core classes. A Vaadin application is based
-on the {@link com.vaadin.Application} class and deployed as a servlet
-using {@link com.vaadin.terminal.gwt.server.ApplicationServlet} or
-{@link com.vaadin.terminal.gwt.server.GAEApplicationServlet} (for Google
-App Engine).</p>
-
-<p>Vaadin applications can also be deployed as portlets using {@link
-com.vaadin.terminal.gwt.server.ApplicationPortlet} (JSR-168) or {@link
-com.vaadin.terminal.gwt.server.ApplicationPortlet2} (JSR-286).</p>
-
-<p>All classes in Vaadin are serializable unless otherwise noted.
-This allows Vaadin applications to run in cluster and cloud
-environments.</p>
-
-
-</body>
-</html>
diff --git a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml b/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
deleted file mode 100644
index bd91d05b02..0000000000
--- a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<module>
- <!-- WS Compiler: manually edited -->
-
- <!-- Inherit the DefaultWidgetSet -->
- <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
-</module>
diff --git a/src/com/vaadin/service/ApplicationContext.java b/src/com/vaadin/service/ApplicationContext.java
deleted file mode 100644
index 71bff7b865..0000000000
--- a/src/com/vaadin/service/ApplicationContext.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.service;
-
-import java.io.File;
-import java.io.Serializable;
-import java.net.URL;
-import java.util.Collection;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.gwt.server.AbstractCommunicationManager;
-
-/**
- * <code>ApplicationContext</code> provides information about the running
- * context of the application. Each context is shared by all applications that
- * are open for one user. In a web-environment this corresponds to a
- * HttpSession.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.1
- */
-public interface ApplicationContext extends Serializable {
-
- /**
- * Returns application context base directory.
- *
- * Typically an application is deployed in a such way that is has an
- * application directory. For web applications this directory is the root
- * directory of the web applications. In some cases applications might not
- * have an application directory (for example web applications running
- * inside a war).
- *
- * @return The application base directory or null if the application has no
- * base directory.
- */
- public File getBaseDirectory();
-
- /**
- * Returns a collection of all the applications in this context.
- *
- * Each application context contains all active applications for one user.
- *
- * @return A collection containing all the applications in this context.
- */
- public Collection<Application> getApplications();
-
- /**
- * Adds a transaction listener to this context. The transaction listener is
- * called before and after each each request related to this session except
- * when serving static resources.
- *
- * The transaction listener must not be null.
- *
- * @see com.vaadin.service.ApplicationContext#addTransactionListener(com.vaadin.service.ApplicationContext.TransactionListener)
- */
- public void addTransactionListener(TransactionListener listener);
-
- /**
- * Removes a transaction listener from this context.
- *
- * @param listener
- * the listener to be removed.
- * @see TransactionListener
- */
- public void removeTransactionListener(TransactionListener listener);
-
- /**
- * Generate a URL that can be used as the relative location of e.g. an
- * {@link ApplicationResource}.
- *
- * This method should only be called from the processing of a UIDL request,
- * not from a background thread. The return value is null if used outside a
- * suitable request.
- *
- * @deprecated this method is intended for terminal implementation only and
- * is subject to change/removal from the interface (to
- * {@link AbstractCommunicationManager})
- *
- * @param resource
- * @param urlKey
- * a key for the resource that can later be extracted from a URL
- * with {@link #getURLKey(URL, String)}
- */
- @Deprecated
- public String generateApplicationResourceURL(ApplicationResource resource,
- String urlKey);
-
- /**
- * Tests if a URL is for an application resource (APP/...).
- *
- * @deprecated this method is intended for terminal implementation only and
- * is subject to change/removal from the interface (to
- * {@link AbstractCommunicationManager})
- *
- * @param context
- * @param relativeUri
- * @return
- */
- @Deprecated
- public boolean isApplicationResourceURL(URL context, String relativeUri);
-
- /**
- * Gets the identifier (key) from an application resource URL. This key is
- * the one that was given to
- * {@link #generateApplicationResourceURL(ApplicationResource, String)} when
- * creating the URL.
- *
- * @deprecated this method is intended for terminal implementation only and
- * is subject to change/removal from the interface (to
- * {@link AbstractCommunicationManager})
- *
- *
- * @param context
- * @param relativeUri
- * @return
- */
- @Deprecated
- public String getURLKey(URL context, String relativeUri);
-
- /**
- * Interface for listening to transaction events. Implement this interface
- * to listen to all transactions between the client and the application.
- *
- */
- public interface TransactionListener extends Serializable {
-
- /**
- * Invoked at the beginning of every transaction.
- *
- * The transaction is linked to the context, not the application so if
- * you have multiple applications running in the same context you need
- * to check that the request is associated with the application you are
- * interested in. This can be done looking at the application parameter.
- *
- * @param application
- * the Application object.
- * @param transactionData
- * the Data identifying the transaction.
- */
- public void transactionStart(Application application,
- Object transactionData);
-
- /**
- * Invoked at the end of every transaction.
- *
- * The transaction is linked to the context, not the application so if
- * you have multiple applications running in the same context you need
- * to check that the request is associated with the application you are
- * interested in. This can be done looking at the application parameter.
- *
- * @param applcation
- * the Application object.
- * @param transactionData
- * the Data identifying the transaction.
- */
- public void transactionEnd(Application application,
- Object transactionData);
-
- }
-}
diff --git a/src/com/vaadin/service/FileTypeResolver.java b/src/com/vaadin/service/FileTypeResolver.java
deleted file mode 100644
index c457c16eb4..0000000000
--- a/src/com/vaadin/service/FileTypeResolver.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.service;
-
-import java.io.File;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.ThemeResource;
-
-/**
- * Utility class that can figure out mime-types and icons related to files.
- * <p>
- * Note : The icons are associated purely to mime-types, so a file may not have
- * a custom icon accessible with this class.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class FileTypeResolver implements Serializable {
-
- /**
- * Default icon given if no icon is specified for a mime-type.
- */
- static public Resource DEFAULT_ICON = new ThemeResource(
- "../runo/icons/16/document.png");
-
- /**
- * Default mime-type.
- */
- static public String DEFAULT_MIME_TYPE = "application/octet-stream";
-
- /**
- * Initial file extension to mime-type mapping.
- */
- static private String initialExtToMIMEMap = "application/cu-seeme csm cu,"
- + "application/dsptype tsp,"
- + "application/futuresplash spl,"
- + "application/mac-binhex40 hqx,"
- + "application/msaccess mdb,"
- + "application/msword doc dot,"
- + "application/octet-stream bin,"
- + "application/oda oda,"
- + "application/pdf pdf,"
- + "application/pgp-signature pgp,"
- + "application/postscript ps ai eps,"
- + "application/rtf rtf,"
- + "application/vnd.ms-excel xls xlb,"
- + "application/vnd.ms-powerpoint ppt pps pot,"
- + "application/vnd.wap.wmlc wmlc,"
- + "application/vnd.wap.wmlscriptc wmlsc,"
- + "application/wordperfect5.1 wp5,"
- + "application/zip zip,"
- + "application/x-123 wk,"
- + "application/x-bcpio bcpio,"
- + "application/x-chess-pgn pgn,"
- + "application/x-cpio cpio,"
- + "application/x-debian-package deb,"
- + "application/x-director dcr dir dxr,"
- + "application/x-dms dms,"
- + "application/x-dvi dvi,"
- + "application/x-xfig fig,"
- + "application/x-font pfa pfb gsf pcf pcf.Z,"
- + "application/x-gnumeric gnumeric,"
- + "application/x-gtar gtar tgz taz,"
- + "application/x-hdf hdf,"
- + "application/x-httpd-php phtml pht php,"
- + "application/x-httpd-php3 php3,"
- + "application/x-httpd-php3-source phps,"
- + "application/x-httpd-php3-preprocessed php3p,"
- + "application/x-httpd-php4 php4,"
- + "application/x-ica ica,"
- + "application/x-java-archive jar,"
- + "application/x-java-serialized-object ser,"
- + "application/x-java-vm class,"
- + "application/x-javascript js,"
- + "application/x-kchart chrt,"
- + "application/x-killustrator kil,"
- + "application/x-kpresenter kpr kpt,"
- + "application/x-kspread ksp,"
- + "application/x-kword kwd kwt,"
- + "application/x-latex latex,"
- + "application/x-lha lha,"
- + "application/x-lzh lzh,"
- + "application/x-lzx lzx,"
- + "application/x-maker frm maker frame fm fb book fbdoc,"
- + "application/x-mif mif,"
- + "application/x-msdos-program com exe bat dll,"
- + "application/x-msi msi,"
- + "application/x-netcdf nc cdf,"
- + "application/x-ns-proxy-autoconfig pac,"
- + "application/x-object o,"
- + "application/x-ogg ogg,"
- + "application/x-oz-application oza,"
- + "application/x-perl pl pm,"
- + "application/x-pkcs7-crl crl,"
- + "application/x-redhat-package-manager rpm,"
- + "application/x-shar shar,"
- + "application/x-shockwave-flash swf swfl,"
- + "application/x-star-office sdd sda,"
- + "application/x-stuffit sit,"
- + "application/x-sv4cpio sv4cpio,"
- + "application/x-sv4crc sv4crc,"
- + "application/x-tar tar,"
- + "application/x-tex-gf gf,"
- + "application/x-tex-pk pk PK,"
- + "application/x-texinfo texinfo texi,"
- + "application/x-trash ~ % bak old sik,"
- + "application/x-troff t tr roff,"
- + "application/x-troff-man man,"
- + "application/x-troff-me me,"
- + "application/x-troff-ms ms,"
- + "application/x-ustar ustar,"
- + "application/x-wais-source src,"
- + "application/x-wingz wz,"
- + "application/x-x509-ca-cert crt,"
- + "audio/basic au snd,"
- + "audio/midi mid midi,"
- + "audio/mpeg mpga mpega mp2 mp3,"
- + "audio/mpegurl m3u,"
- + "audio/prs.sid sid,"
- + "audio/x-aiff aif aiff aifc,"
- + "audio/x-gsm gsm,"
- + "audio/x-pn-realaudio ra rm ram,"
- + "audio/x-scpls pls,"
- + "audio/x-wav wav,"
- + "audio/ogg ogg,"
- + "audio/mp4 m4a,"
- + "audio/x-aac aac,"
- + "image/bitmap bmp,"
- + "image/gif gif,"
- + "image/ief ief,"
- + "image/jpeg jpeg jpg jpe,"
- + "image/pcx pcx,"
- + "image/png png,"
- + "image/svg+xml svg svgz,"
- + "image/tiff tiff tif,"
- + "image/vnd.wap.wbmp wbmp,"
- + "image/x-cmu-raster ras,"
- + "image/x-coreldraw cdr,"
- + "image/x-coreldrawpattern pat,"
- + "image/x-coreldrawtemplate cdt,"
- + "image/x-corelphotopaint cpt,"
- + "image/x-jng jng,"
- + "image/x-portable-anymap pnm,"
- + "image/x-portable-bitmap pbm,"
- + "image/x-portable-graymap pgm,"
- + "image/x-portable-pixmap ppm,"
- + "image/x-rgb rgb,"
- + "image/x-xbitmap xbm,"
- + "image/x-xpixmap xpm,"
- + "image/x-xwindowdump xwd,"
- + "text/comma-separated-values csv,"
- + "text/css css,"
- + "text/html htm html xhtml,"
- + "text/mathml mml,"
- + "text/plain txt text diff,"
- + "text/richtext rtx,"
- + "text/tab-separated-values tsv,"
- + "text/vnd.wap.wml wml,"
- + "text/vnd.wap.wmlscript wmls,"
- + "text/xml xml,"
- + "text/x-c++hdr h++ hpp hxx hh,"
- + "text/x-c++src c++ cpp cxx cc,"
- + "text/x-chdr h,"
- + "text/x-csh csh,"
- + "text/x-csrc c,"
- + "text/x-java java,"
- + "text/x-moc moc,"
- + "text/x-pascal p pas,"
- + "text/x-setext etx,"
- + "text/x-sh sh,"
- + "text/x-tcl tcl tk,"
- + "text/x-tex tex ltx sty cls,"
- + "text/x-vcalendar vcs,"
- + "text/x-vcard vcf,"
- + "video/dl dl,"
- + "video/fli fli,"
- + "video/gl gl,"
- + "video/mpeg mpeg mpg mpe,"
- + "video/quicktime qt mov,"
- + "video/x-mng mng,"
- + "video/x-ms-asf asf asx,"
- + "video/x-msvideo avi,"
- + "video/x-sgi-movie movie,"
- + "video/ogg ogv,"
- + "video/mp4 mp4,"
- + "x-world/x-vrml vrm vrml wrl";
-
- /**
- * File extension to MIME type mapping. All extensions are in lower case.
- */
- static private Hashtable<String, String> extToMIMEMap = new Hashtable<String, String>();
-
- /**
- * MIME type to Icon mapping.
- */
- static private Hashtable<String, Resource> MIMEToIconMap = new Hashtable<String, Resource>();
-
- static {
-
- // Initialize extension to MIME map
- final StringTokenizer lines = new StringTokenizer(initialExtToMIMEMap,
- ",");
- while (lines.hasMoreTokens()) {
- final String line = lines.nextToken();
- final StringTokenizer exts = new StringTokenizer(line);
- final String type = exts.nextToken();
- while (exts.hasMoreTokens()) {
- final String ext = exts.nextToken();
- addExtension(ext, type);
- }
- }
-
- // Initialize Icons
- ThemeResource folder = new ThemeResource("../runo/icons/16/folder.png");
- addIcon("inode/drive", folder);
- addIcon("inode/directory", folder);
- }
-
- /**
- * Gets the mime-type of a file. Currently the mime-type is resolved based
- * only on the file name extension.
- *
- * @param fileName
- * the name of the file whose mime-type is requested.
- * @return mime-type <code>String</code> for the given filename
- */
- public static String getMIMEType(String fileName) {
-
- // Checks for nulls
- if (fileName == null) {
- throw new NullPointerException("Filename can not be null");
- }
-
- // Calculates the extension of the file
- int dotIndex = fileName.indexOf(".");
- while (dotIndex >= 0 && fileName.indexOf(".", dotIndex + 1) >= 0) {
- dotIndex = fileName.indexOf(".", dotIndex + 1);
- }
- dotIndex++;
-
- if (fileName.length() > dotIndex) {
- String ext = fileName.substring(dotIndex);
-
- // Ignore any query parameters
- int queryStringStart = ext.indexOf('?');
- if (queryStringStart > 0) {
- ext = ext.substring(0, queryStringStart);
- }
-
- // Return type from extension map, if found
- final String type = extToMIMEMap.get(ext.toLowerCase());
- if (type != null) {
- return type;
- }
- }
-
- return DEFAULT_MIME_TYPE;
- }
-
- /**
- * Gets the descriptive icon representing file, based on the filename. First
- * the mime-type for the given filename is resolved, and then the
- * corresponding icon is fetched from the internal icon storage. If it is
- * not found the default icon is returned.
- *
- * @param fileName
- * the name of the file whose icon is requested.
- * @return the icon corresponding to the given file
- */
- public static Resource getIcon(String fileName) {
- return getIconByMimeType(getMIMEType(fileName));
- }
-
- private static Resource getIconByMimeType(String mimeType) {
- final Resource icon = MIMEToIconMap.get(mimeType);
- if (icon != null) {
- return icon;
- }
-
- // If nothing is known about the file-type, general file
- // icon is used
- return DEFAULT_ICON;
- }
-
- /**
- * Gets the descriptive icon representing a file. First the mime-type for
- * the given file name is resolved, and then the corresponding icon is
- * fetched from the internal icon storage. If it is not found the default
- * icon is returned.
- *
- * @param file
- * the file whose icon is requested.
- * @return the icon corresponding to the given file
- */
- public static Resource getIcon(File file) {
- return getIconByMimeType(getMIMEType(file));
- }
-
- /**
- * Gets the mime-type for a file. Currently the returned file type is
- * resolved by the filename extension only.
- *
- * @param file
- * the file whose mime-type is requested.
- * @return the files mime-type <code>String</code>
- */
- public static String getMIMEType(File file) {
-
- // Checks for nulls
- if (file == null) {
- throw new NullPointerException("File can not be null");
- }
-
- // Directories
- if (file.isDirectory()) {
- // Drives
- if (file.getParentFile() == null) {
- return "inode/drive";
- } else {
- return "inode/directory";
- }
- }
-
- // Return type from extension
- return getMIMEType(file.getName());
- }
-
- /**
- * Adds a mime-type mapping for the given filename extension. If the
- * extension is already in the internal mapping it is overwritten.
- *
- * @param extension
- * the filename extension to be associated with
- * <code>MIMEType</code>.
- * @param MIMEType
- * the new mime-type for <code>extension</code>.
- */
- public static void addExtension(String extension, String MIMEType) {
- extToMIMEMap.put(extension.toLowerCase(), MIMEType);
- }
-
- /**
- * Adds a icon for the given mime-type. If the mime-type also has a
- * corresponding icon, it is replaced with the new icon.
- *
- * @param MIMEType
- * the mime-type whose icon is to be changed.
- * @param icon
- * the new icon to be associated with <code>MIMEType</code>.
- */
- public static void addIcon(String MIMEType, Resource icon) {
- MIMEToIconMap.put(MIMEType, icon);
- }
-
- /**
- * Gets the internal file extension to mime-type mapping.
- *
- * @return unmodifiable map containing the current file extension to
- * mime-type mapping
- */
- public static Map<String, String> getExtensionToMIMETypeMapping() {
- return Collections.unmodifiableMap(extToMIMEMap);
- }
-
- /**
- * Gets the internal mime-type to icon mapping.
- *
- * @return unmodifiable map containing the current mime-type to icon mapping
- */
- public static Map<String, Resource> getMIMETypeToIconMapping() {
- return Collections.unmodifiableMap(MIMEToIconMap);
- }
-}
diff --git a/src/com/vaadin/service/package.html b/src/com/vaadin/service/package.html
deleted file mode 100644
index ea21139b91..0000000000
--- a/src/com/vaadin/service/package.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-</head>
-
-<body bgcolor="white">
-
-<!-- Package summary here -->
-
-<p>Provides some general service classes used throughout Vaadin
-based applications.</p>
-
-<!-- <h2>Package Specification</h2> -->
-
-<!-- Package spec here -->
-
-<!-- Put @see and @since tags down here. -->
-
-</body>
-</html>
diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java
deleted file mode 100644
index 9c68361382..0000000000
--- a/src/com/vaadin/terminal/AbstractClientConnector.java
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.logging.Logger;
-
-import com.vaadin.Application;
-import com.vaadin.shared.communication.ClientRpc;
-import com.vaadin.shared.communication.ServerRpc;
-import com.vaadin.shared.communication.SharedState;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
-import com.vaadin.terminal.gwt.server.RpcManager;
-import com.vaadin.terminal.gwt.server.RpcTarget;
-import com.vaadin.terminal.gwt.server.ServerRpcManager;
-import com.vaadin.ui.HasComponents;
-import com.vaadin.ui.Root;
-
-/**
- * An abstract base class for ClientConnector implementations. This class
- * provides all the basic functionality required for connectors.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public abstract class AbstractClientConnector implements ClientConnector {
- /**
- * A map from client to server RPC interface class to the RPC call manager
- * that handles incoming RPC calls for that interface.
- */
- private Map<Class<?>, RpcManager> rpcManagerMap = new HashMap<Class<?>, RpcManager>();
-
- /**
- * A map from server to client RPC interface class to the RPC proxy that
- * sends ourgoing RPC calls for that interface.
- */
- private Map<Class<?>, ClientRpc> rpcProxyMap = new HashMap<Class<?>, ClientRpc>();
-
- /**
- * Shared state object to be communicated from the server to the client when
- * modified.
- */
- private SharedState sharedState;
-
- /**
- * Pending RPC method invocations to be sent.
- */
- private ArrayList<ClientMethodInvocation> pendingInvocations = new ArrayList<ClientMethodInvocation>();
-
- private String connectorId;
-
- private ArrayList<Extension> extensions = new ArrayList<Extension>();
-
- private ClientConnector parent;
-
- /* Documentation copied from interface */
- @Override
- public void requestRepaint() {
- Root root = getRoot();
- if (root != null) {
- root.getConnectorTracker().markDirty(this);
- }
- }
-
- /**
- * Registers an RPC interface implementation for this component.
- *
- * A component can listen to multiple RPC interfaces, and subclasses can
- * register additional implementations.
- *
- * @since 7.0
- *
- * @param implementation
- * RPC interface implementation
- * @param rpcInterfaceType
- * RPC interface class for which the implementation should be
- * registered
- */
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
- rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager<T>(
- implementation, rpcInterfaceType));
- }
-
- /**
- * Registers an RPC interface implementation for this component.
- *
- * A component can listen to multiple RPC interfaces, and subclasses can
- * register additional implementations.
- *
- * @since 7.0
- *
- * @param implementation
- * RPC interface implementation. Also used to deduce the type.
- */
- protected <T extends ServerRpc> void registerRpc(T implementation) {
- Class<?> cls = implementation.getClass();
- Class<?>[] interfaces = cls.getInterfaces();
- while (interfaces.length == 0) {
- // Search upwards until an interface is found. It must be found as T
- // extends ServerRpc
- cls = cls.getSuperclass();
- interfaces = cls.getInterfaces();
- }
- if (interfaces.length != 1
- || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) {
- throw new RuntimeException(
- "Use registerRpc(T implementation, Class<T> rpcInterfaceType) if the Rpc implementation implements more than one interface");
- }
- @SuppressWarnings("unchecked")
- Class<T> type = (Class<T>) interfaces[0];
- registerRpc(implementation, type);
- }
-
- @Override
- public SharedState getState() {
- if (null == sharedState) {
- sharedState = createState();
- }
- return sharedState;
- }
-
- /**
- * Creates the shared state bean to be used in server to client
- * communication.
- * <p>
- * By default a state object of the defined return type of
- * {@link #getState()} is created. Subclasses can override this method and
- * return a new instance of the correct state class but this should rarely
- * be necessary.
- * </p>
- * <p>
- * No configuration of the values of the state should be performed in
- * {@link #createState()}.
- *
- * @since 7.0
- *
- * @return new shared state object
- */
- protected SharedState createState() {
- try {
- return getStateType().newInstance();
- } catch (Exception e) {
- throw new RuntimeException(
- "Error creating state of type " + getStateType().getName()
- + " for " + getClass().getName(), e);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.server.ClientConnector#getStateType()
- */
- @Override
- public Class<? extends SharedState> getStateType() {
- try {
- Method m = getClass().getMethod("getState", (Class[]) null);
- Class<?> type = m.getReturnType();
- return type.asSubclass(SharedState.class);
- } catch (Exception e) {
- throw new RuntimeException("Error finding state type for "
- + getClass().getName(), e);
- }
- }
-
- /**
- * Returns an RPC proxy for a given server to client RPC interface for this
- * component.
- *
- * TODO more javadoc, subclasses, ...
- *
- * @param rpcInterface
- * RPC interface type
- *
- * @since 7.0
- */
- public <T extends ClientRpc> T getRpcProxy(final Class<T> rpcInterface) {
- // create, initialize and return a dynamic proxy for RPC
- try {
- if (!rpcProxyMap.containsKey(rpcInterface)) {
- Class<?> proxyClass = Proxy.getProxyClass(
- rpcInterface.getClassLoader(), rpcInterface);
- Constructor<?> constructor = proxyClass
- .getConstructor(InvocationHandler.class);
- T rpcProxy = rpcInterface.cast(constructor
- .newInstance(new RpcInvoicationHandler(rpcInterface)));
- // cache the proxy
- rpcProxyMap.put(rpcInterface, rpcProxy);
- }
- return (T) rpcProxyMap.get(rpcInterface);
- } catch (Exception e) {
- // TODO exception handling?
- throw new RuntimeException(e);
- }
- }
-
- private static final class AllChildrenIterable implements
- Iterable<ClientConnector>, Serializable {
- private final ClientConnector connector;
-
- private AllChildrenIterable(ClientConnector connector) {
- this.connector = connector;
- }
-
- @Override
- public Iterator<ClientConnector> iterator() {
- CombinedIterator<ClientConnector> iterator = new CombinedIterator<ClientConnector>();
- iterator.addIterator(connector.getExtensions().iterator());
-
- if (connector instanceof HasComponents) {
- HasComponents hasComponents = (HasComponents) connector;
- iterator.addIterator(hasComponents.iterator());
- }
-
- return iterator;
- }
- }
-
- private class RpcInvoicationHandler implements InvocationHandler,
- Serializable {
-
- private String rpcInterfaceName;
-
- public RpcInvoicationHandler(Class<?> rpcInterface) {
- rpcInterfaceName = rpcInterface.getName().replaceAll("\\$", ".");
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- addMethodInvocationToQueue(rpcInterfaceName, method, args);
- // TODO no need to do full repaint if only RPC calls
- requestRepaint();
- return null;
- }
-
- }
-
- /**
- * For internal use: adds a method invocation to the pending RPC call queue.
- *
- * @param interfaceName
- * RPC interface name
- * @param method
- * RPC method
- * @param parameters
- * RPC all parameters
- *
- * @since 7.0
- */
- protected void addMethodInvocationToQueue(String interfaceName,
- Method method, Object[] parameters) {
- // add to queue
- pendingInvocations.add(new ClientMethodInvocation(this, interfaceName,
- method, parameters));
- }
-
- /**
- * @see RpcTarget#getRpcManager(Class)
- *
- * @param rpcInterface
- * RPC interface for which a call was made
- * @return RPC Manager handling calls for the interface
- *
- * @since 7.0
- */
- @Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
- return rpcManagerMap.get(rpcInterface);
- }
-
- @Override
- public List<ClientMethodInvocation> retrievePendingRpcCalls() {
- if (pendingInvocations.isEmpty()) {
- return Collections.emptyList();
- } else {
- List<ClientMethodInvocation> result = pendingInvocations;
- pendingInvocations = new ArrayList<ClientMethodInvocation>();
- return Collections.unmodifiableList(result);
- }
- }
-
- @Override
- public String getConnectorId() {
- if (connectorId == null) {
- if (getApplication() == null) {
- throw new RuntimeException(
- "Component must be attached to an application when getConnectorId() is called for the first time");
- }
- connectorId = getApplication().createConnectorId(this);
- }
- return connectorId;
- }
-
- /**
- * Finds the Application to which this connector belongs. If the connector
- * has not been attached, <code>null</code> is returned.
- *
- * @return The connector's application, or <code>null</code> if not attached
- */
- protected Application getApplication() {
- Root root = getRoot();
- if (root == null) {
- return null;
- } else {
- return root.getApplication();
- }
- }
-
- /**
- * Finds a Root ancestor of this connector. <code>null</code> is returned if
- * no Root ancestor is found (typically because the connector is not
- * attached to a proper hierarchy).
- *
- * @return the Root ancestor of this connector, or <code>null</code> if none
- * is found.
- */
- @Override
- public Root getRoot() {
- ClientConnector connector = this;
- while (connector != null) {
- if (connector instanceof Root) {
- return (Root) connector;
- }
- connector = connector.getParent();
- }
- return null;
- }
-
- private static Logger getLogger() {
- return Logger.getLogger(AbstractClientConnector.class.getName());
- }
-
- @Override
- public void requestRepaintAll() {
- requestRepaint();
-
- for (ClientConnector connector : getAllChildrenIterable(this)) {
- connector.requestRepaintAll();
- }
- }
-
- private static final class CombinedIterator<T> implements Iterator<T>,
- Serializable {
-
- private final Collection<Iterator<? extends T>> iterators = new ArrayList<Iterator<? extends T>>();
-
- public void addIterator(Iterator<? extends T> iterator) {
- iterators.add(iterator);
- }
-
- @Override
- public boolean hasNext() {
- for (Iterator<? extends T> i : iterators) {
- if (i.hasNext()) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public T next() {
- for (Iterator<? extends T> i : iterators) {
- if (i.hasNext()) {
- return i.next();
- }
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Get an Iterable for iterating over all child connectors, including both
- * extensions and child components.
- *
- * @param connector
- * the connector to get children for
- * @return an Iterable giving all child connectors.
- */
- public static Iterable<ClientConnector> getAllChildrenIterable(
- final ClientConnector connector) {
- return new AllChildrenIterable(connector);
- }
-
- @Override
- public Collection<Extension> getExtensions() {
- return Collections.unmodifiableCollection(extensions);
- }
-
- /**
- * Add an extension to this connector. This method is protected to allow
- * extensions to select which targets they can extend.
- *
- * @param extension
- * the extension to add
- */
- protected void addExtension(Extension extension) {
- ClientConnector previousParent = extension.getParent();
- if (previousParent == this) {
- // Nothing to do, already attached
- return;
- } else if (previousParent != null) {
- throw new IllegalStateException(
- "Moving an extension from one parent to another is not supported");
- }
-
- extensions.add(extension);
- extension.setParent(this);
- requestRepaint();
- }
-
- @Override
- public void removeExtension(Extension extension) {
- extension.setParent(null);
- extensions.remove(extension);
- requestRepaint();
- }
-
- @Override
- public void setParent(ClientConnector parent) {
-
- // If the parent is not changed, don't do anything
- if (parent == this.parent) {
- return;
- }
-
- if (parent != null && this.parent != null) {
- throw new IllegalStateException(getClass().getName()
- + " already has a parent.");
- }
-
- // Send detach event if the component have been connected to a window
- if (getApplication() != null) {
- detach();
- }
-
- // Connect to new parent
- this.parent = parent;
-
- // Send attach event if connected to an application
- if (getApplication() != null) {
- attach();
- }
- }
-
- @Override
- public ClientConnector getParent() {
- return parent;
- }
-
- @Override
- public void attach() {
- requestRepaint();
-
- getRoot().getConnectorTracker().registerConnector(this);
-
- for (ClientConnector connector : getAllChildrenIterable(this)) {
- connector.attach();
- }
-
- }
-
- /**
- * {@inheritDoc}
- *
- * <p>
- * The {@link #getApplication()} and {@link #getRoot()} methods might return
- * <code>null</code> after this method is called.
- * </p>
- */
- @Override
- public void detach() {
- for (ClientConnector connector : getAllChildrenIterable(this)) {
- connector.detach();
- }
-
- getRoot().getConnectorTracker().unregisterConnector(this);
- }
-
- @Override
- public boolean isConnectorEnabled() {
- if (getParent() == null) {
- // No parent -> the component cannot receive updates from the client
- return false;
- } else {
- return getParent().isConnectorEnabled();
- }
- }
-}
diff --git a/src/com/vaadin/terminal/AbstractErrorMessage.java b/src/com/vaadin/terminal/AbstractErrorMessage.java
deleted file mode 100644
index f7cd0e6aad..0000000000
--- a/src/com/vaadin/terminal/AbstractErrorMessage.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.data.Buffered;
-import com.vaadin.data.Validator;
-import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-
-/**
- * Base class for component error messages.
- *
- * This class is used on the server side to construct the error messages to send
- * to the client.
- *
- * @since 7.0
- */
-public abstract class AbstractErrorMessage implements ErrorMessage {
-
- public enum ContentMode {
- /**
- * Content mode, where the error contains only plain text.
- */
- TEXT,
- /**
- * Content mode, where the error contains preformatted text.
- */
- PREFORMATTED,
- /**
- * Content mode, where the error contains XHTML.
- */
- XHTML;
- }
-
- /**
- * Content mode.
- */
- private ContentMode mode = ContentMode.TEXT;
-
- /**
- * Message in content mode.
- */
- private String message;
-
- /**
- * Error level.
- */
- private ErrorLevel level = ErrorLevel.ERROR;
-
- private List<ErrorMessage> causes = new ArrayList<ErrorMessage>();
-
- protected AbstractErrorMessage(String message) {
- this.message = message;
- }
-
- public String getMessage() {
- return message;
- }
-
- protected void setMessage(String message) {
- this.message = message;
- }
-
- /* Documented in interface */
- @Override
- public ErrorLevel getErrorLevel() {
- return level;
- }
-
- protected void setErrorLevel(ErrorLevel level) {
- this.level = level;
- }
-
- protected ContentMode getMode() {
- return mode;
- }
-
- protected void setMode(ContentMode mode) {
- this.mode = mode;
- }
-
- protected List<ErrorMessage> getCauses() {
- return causes;
- }
-
- protected void addCause(ErrorMessage cause) {
- causes.add(cause);
- }
-
- @Override
- public String getFormattedHtmlMessage() {
- String result = null;
- switch (getMode()) {
- case TEXT:
- result = AbstractApplicationServlet.safeEscapeForHtml(getMessage());
- break;
- case PREFORMATTED:
- result = "<pre>"
- + AbstractApplicationServlet
- .safeEscapeForHtml(getMessage()) + "</pre>";
- break;
- case XHTML:
- result = getMessage();
- break;
- }
- // if no message, combine the messages of all children
- if (null == result && null != getCauses() && getCauses().size() > 0) {
- StringBuilder sb = new StringBuilder();
- for (ErrorMessage cause : getCauses()) {
- String childMessage = cause.getFormattedHtmlMessage();
- if (null != childMessage) {
- sb.append("<div>");
- sb.append(childMessage);
- sb.append("</div>\n");
- }
- }
- if (sb.length() > 0) {
- result = sb.toString();
- }
- }
- // still no message? use an empty string for backwards compatibility
- if (null == result) {
- result = "";
- }
- return result;
- }
-
- // TODO replace this with a helper method elsewhere?
- public static ErrorMessage getErrorMessageForException(Throwable t) {
- if (null == t) {
- return null;
- } else if (t instanceof ErrorMessage) {
- // legacy case for custom error messages
- return (ErrorMessage) t;
- } else if (t instanceof Validator.InvalidValueException) {
- UserError error = new UserError(
- ((Validator.InvalidValueException) t).getHtmlMessage(),
- ContentMode.XHTML, ErrorLevel.ERROR);
- for (Validator.InvalidValueException nestedException : ((Validator.InvalidValueException) t)
- .getCauses()) {
- error.addCause(getErrorMessageForException(nestedException));
- }
- return error;
- } else if (t instanceof Buffered.SourceException) {
- // no message, only the causes to be painted
- UserError error = new UserError(null);
- // in practice, this was always ERROR in Vaadin 6 unless tweaked in
- // custom exceptions implementing ErrorMessage
- error.setErrorLevel(ErrorLevel.ERROR);
- // causes
- for (Throwable nestedException : ((Buffered.SourceException) t)
- .getCauses()) {
- error.addCause(getErrorMessageForException(nestedException));
- }
- return error;
- } else {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- return new SystemError(sw.toString());
- }
- }
-
- /* Documented in superclass */
- @Override
- public String toString() {
- return getMessage();
- }
-
-}
diff --git a/src/com/vaadin/terminal/AbstractExtension.java b/src/com/vaadin/terminal/AbstractExtension.java
deleted file mode 100644
index 33a60e39ef..0000000000
--- a/src/com/vaadin/terminal/AbstractExtension.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * An extension is an entity that is attached to a Component or another
- * Extension and independently communicates between client and server.
- * <p>
- * Extensions can use shared state and RPC in the same way as components.
- * <p>
- * AbstractExtension adds a mechanism for adding the extension to any Connector
- * (extend). To let the Extension determine what kind target it can be added to,
- * the extend method is declared as protected.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public abstract class AbstractExtension extends AbstractClientConnector
- implements Extension {
- private boolean previouslyAttached = false;
-
- /**
- * Gets a type that the parent must be an instance of. Override this if the
- * extension only support certain targets, e.g. if only TextFields can be
- * extended.
- *
- * @return a type that the parent must be an instance of
- */
- protected Class<? extends ClientConnector> getSupportedParentType() {
- return ClientConnector.class;
- }
-
- /**
- * Add this extension to the target connector. This method is protected to
- * allow subclasses to require a more specific type of target.
- *
- * @param target
- * the connector to attach this extension to
- */
- protected void extend(AbstractClientConnector target) {
- target.addExtension(this);
- }
-
- /**
- * Remove this extension from its target. After an extension has been
- * removed, it can not be attached again.
- */
- public void removeFromTarget() {
- getParent().removeExtension(this);
- }
-
- @Override
- public void setParent(ClientConnector parent) {
- if (previouslyAttached && parent != null) {
- throw new IllegalStateException(
- "An extension can not be set to extend a new target after getting detached from the previous.");
- }
-
- Class<? extends ClientConnector> supportedParentType = getSupportedParentType();
- if (parent == null || supportedParentType.isInstance(parent)) {
- super.setParent(parent);
- previouslyAttached = true;
- } else {
- throw new IllegalArgumentException(getClass().getName()
- + " can only be attached to targets of type "
- + supportedParentType.getName() + " but attach to "
- + parent.getClass().getName() + " was attempted.");
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java
deleted file mode 100644
index 7bafb6d2b3..0000000000
--- a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import com.vaadin.shared.JavaScriptExtensionState;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.ui.JavaScriptFunction;
-
-/**
- * Base class for Extensions with all client-side logic implemented using
- * JavaScript.
- * <p>
- * When a new JavaScript extension is initialized in the browser, the framework
- * will look for a globally defined JavaScript function that will initialize the
- * extension. The name of the initialization function is formed by replacing .
- * with _ in the name of the server-side class. If no such function is defined,
- * each super class is used in turn until a match is found. The framework will
- * thus first attempt with <code>com_example_MyExtension</code> for the
- * server-side
- * <code>com.example.MyExtension extends AbstractJavaScriptExtension</code>
- * class. If MyExtension instead extends <code>com.example.SuperExtension</code>
- * , then <code>com_example_SuperExtension</code> will also be attempted if
- * <code>com_example_MyExtension</code> has not been defined.
- * <p>
- *
- * The initialization function will be called with <code>this</code> pointing to
- * a connector wrapper object providing integration to Vaadin with the following
- * functions:
- * <ul>
- * <li><code>getConnectorId()</code> - returns a string with the id of the
- * connector.</li>
- * <li><code>getParentId([connectorId])</code> - returns a string with the id of
- * the connector's parent. If <code>connectorId</code> is provided, the id of
- * the parent of the corresponding connector with the passed id is returned
- * instead.</li>
- * <li><code>getElement([connectorId])</code> - returns the DOM Element that is
- * the root of a connector's widget. <code>null</code> is returned if the
- * connector can not be found or if the connector doesn't have a widget. If
- * <code>connectorId</code> is not provided, the connector id of the current
- * connector will be used.</li>
- * <li><code>getState()</code> - returns an object corresponding to the shared
- * state defined on the server. The scheme for conversion between Java and
- * JavaScript types is described bellow.</li>
- * <li><code>registerRpc([name, ] rpcObject)</code> - registers the
- * <code>rpcObject</code> as a RPC handler. <code>rpcObject</code> should be an
- * object with field containing functions for all eligible RPC functions. If
- * <code>name</code> is provided, the RPC handler will only used for RPC calls
- * for the RPC interface with the same fully qualified Java name. If no
- * <code>name</code> is provided, the RPC handler will be used for all incoming
- * RPC invocations where the RPC method name is defined as a function field in
- * the handler. The scheme for conversion between Java types in the RPC
- * interface definition and the JavaScript values passed as arguments to the
- * handler functions is described bellow.</li>
- * <li><code>getRpcProxy([name])</code> - returns an RPC proxy object. If
- * <code>name</code> is provided, the proxy object will contain functions for
- * all methods in the RPC interface with the same fully qualified name, provided
- * a RPC handler has been registered by the server-side code. If no
- * <code>name</code> is provided, the returned RPC proxy object will contain
- * functions for all methods in all RPC interfaces registered for the connector
- * on the server. If the same method name is present in multiple registered RPC
- * interfaces, the corresponding function in the RPC proxy object will throw an
- * exception when called. The scheme for conversion between Java types in the
- * RPC interface and the JavaScript values that should be passed to the
- * functions is described bellow.</li>
- * <li><code>translateVaadinUri(uri)</code> - Translates a Vaadin URI to a URL
- * that can be used in the browser. This is just way of accessing
- * {@link ApplicationConnection#translateVaadinUri(String)}</li>
- * </ul>
- * The connector wrapper also supports these special functions:
- * <ul>
- * <li><code>onStateChange</code> - If the JavaScript code assigns a function to
- * the field, that function is called whenever the contents of the shared state
- * is changed.</li>
- * <li>Any field name corresponding to a call to
- * {@link #addFunction(String, JavaScriptFunction)} on the server will
- * automatically be present as a function that triggers the registered function
- * on the server.</li>
- * <li>Any field name referred to using
- * {@link #callFunction(String, Object...)} on the server will be called if a
- * function has been assigned to the field.</li>
- * </ul>
- * <p>
- *
- * Values in the Shared State and in RPC calls are converted between Java and
- * JavaScript using the following conventions:
- * <ul>
- * <li>Primitive Java numbers (byte, char, int, long, float, double) and their
- * boxed types (Byte, Character, Integer, Long, Float, Double) are represented
- * by JavaScript numbers.</li>
- * <li>The primitive Java boolean and the boxed Boolean are represented by
- * JavaScript booleans.</li>
- * <li>Java Strings are represented by JavaScript strings.</li>
- * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li>
- * <li>Map<String, ?> in Java is represented by JavaScript object with fields
- * corresponding to the map keys.</li>
- * <li>Any other Java Map is represented by a JavaScript array containing two
- * arrays, the first contains the keys and the second contains the values in the
- * same order.</li>
- * <li>A Java Bean is represented by a JavaScript object with fields
- * corresponding to the bean's properties.</li>
- * <li>A Java Connector is represented by a JavaScript string containing the
- * connector's id.</li>
- * <li>A pluggable serialization mechanism is provided for types not described
- * here. Please refer to the documentation for specific types for serialization
- * information.</li>
- * </ul>
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public abstract class AbstractJavaScriptExtension extends AbstractExtension {
- private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper(
- this);
-
- @Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
- super.registerRpc(implementation, rpcInterfaceType);
- callbackHelper.registerRpc(rpcInterfaceType);
- }
-
- /**
- * Register a {@link JavaScriptFunction} that can be called from the
- * JavaScript using the provided name. A JavaScript function with the
- * provided name will be added to the connector wrapper object (initially
- * available as <code>this</code>). Calling that JavaScript function will
- * cause the call method in the registered {@link JavaScriptFunction} to be
- * invoked with the same arguments.
- *
- * @param functionName
- * the name that should be used for client-side callback
- * @param function
- * the {@link JavaScriptFunction} object that will be invoked
- * when the JavaScript function is called
- */
- protected void addFunction(String functionName, JavaScriptFunction function) {
- callbackHelper.registerCallback(functionName, function);
- }
-
- /**
- * Invoke a named function that the connector JavaScript has added to the
- * JavaScript connector wrapper object. The arguments should only contain
- * data types that can be represented in JavaScript including primitives,
- * their boxed types, arrays, String, List, Set, Map, Connector and
- * JavaBeans.
- *
- * @param name
- * the name of the function
- * @param arguments
- * function arguments
- */
- protected void callFunction(String name, Object... arguments) {
- callbackHelper.invokeCallback(name, arguments);
- }
-
- @Override
- public JavaScriptExtensionState getState() {
- return (JavaScriptExtensionState) super.getState();
- }
-}
diff --git a/src/com/vaadin/terminal/ApplicationResource.java b/src/com/vaadin/terminal/ApplicationResource.java
deleted file mode 100644
index da92642d02..0000000000
--- a/src/com/vaadin/terminal/ApplicationResource.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-import com.vaadin.Application;
-
-/**
- * This interface must be implemented by classes wishing to provide Application
- * resources.
- * <p>
- * <code>ApplicationResource</code> are a set of named resources (pictures,
- * sounds, etc) associated with some specific application. Having named
- * application resources provides a convenient method for having inter-theme
- * common resources for an application.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface ApplicationResource extends Resource, Serializable {
-
- /**
- * Default cache time.
- */
- public static final long DEFAULT_CACHETIME = 1000 * 60 * 60 * 24;
-
- /**
- * Gets resource as stream.
- */
- public DownloadStream getStream();
-
- /**
- * Gets the application of the resource.
- */
- public Application getApplication();
-
- /**
- * Gets the virtual filename for this resource.
- *
- * @return the file name associated to this resource.
- */
- public String getFilename();
-
- /**
- * Gets the length of cache expiration time.
- *
- * <p>
- * This gives the adapter the possibility cache streams sent to the client.
- * The caching may be made in adapter or at the client if the client
- * supports caching. Default is <code>DEFAULT_CACHETIME</code>.
- * </p>
- *
- * @return Cache time in milliseconds
- */
- public long getCacheTime();
-
- /**
- * Gets the size of the download buffer used for this resource.
- *
- * <p>
- * If the buffer size is 0, the buffer size is decided by the terminal
- * adapter. The default value is 0.
- * </p>
- *
- * @return int the size of the buffer in bytes.
- */
- public int getBufferSize();
-
-}
diff --git a/src/com/vaadin/terminal/ClassResource.java b/src/com/vaadin/terminal/ClassResource.java
deleted file mode 100644
index b74c8e7bb7..0000000000
--- a/src/com/vaadin/terminal/ClassResource.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-import com.vaadin.Application;
-import com.vaadin.service.FileTypeResolver;
-
-/**
- * <code>ClassResource</code> is a named resource accessed with the class
- * loader.
- *
- * This can be used to access resources such as icons, files, etc.
- *
- * @see java.lang.Class#getResource(java.lang.String)
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ClassResource implements ApplicationResource, Serializable {
-
- /**
- * Default buffer size for this stream resource.
- */
- private int bufferSize = 0;
-
- /**
- * Default cache time for this stream resource.
- */
- private long cacheTime = DEFAULT_CACHETIME;
-
- /**
- * Associated class used for indetifying the source of the resource.
- */
- private final Class<?> associatedClass;
-
- /**
- * Name of the resource is relative to the associated class.
- */
- private final String resourceName;
-
- /**
- * Application used for serving the class.
- */
- private final Application application;
-
- /**
- * Creates a new application resource instance. The resource id is relative
- * to the location of the application class.
- *
- * @param resourceName
- * the Unique identifier of the resource within the application.
- * @param application
- * the application this resource will be added to.
- */
- public ClassResource(String resourceName, Application application) {
- this(application.getClass(), resourceName, application);
- }
-
- /**
- * Creates a new application resource instance.
- *
- * @param associatedClass
- * the class of the which the resource is associated.
- * @param resourceName
- * the Unique identifier of the resource within the application.
- * @param application
- * the application this resource will be added to.
- */
- public ClassResource(Class<?> associatedClass, String resourceName,
- Application application) {
- this.associatedClass = associatedClass;
- this.resourceName = resourceName;
- this.application = application;
- if (resourceName == null || associatedClass == null) {
- throw new NullPointerException();
- }
- application.addResource(this);
- }
-
- /**
- * Gets the MIME type of this resource.
- *
- * @see com.vaadin.terminal.Resource#getMIMEType()
- */
- @Override
- public String getMIMEType() {
- return FileTypeResolver.getMIMEType(resourceName);
- }
-
- /**
- * Gets the application of this resource.
- *
- * @see com.vaadin.terminal.ApplicationResource#getApplication()
- */
- @Override
- public Application getApplication() {
- return application;
- }
-
- /**
- * Gets the virtual filename for this resource.
- *
- * @return the file name associated to this resource.
- * @see com.vaadin.terminal.ApplicationResource#getFilename()
- */
- @Override
- public String getFilename() {
- int index = 0;
- int next = 0;
- while ((next = resourceName.indexOf('/', index)) > 0
- && next + 1 < resourceName.length()) {
- index = next + 1;
- }
- return resourceName.substring(index);
- }
-
- /**
- * Gets resource as stream.
- *
- * @see com.vaadin.terminal.ApplicationResource#getStream()
- */
- @Override
- public DownloadStream getStream() {
- final DownloadStream ds = new DownloadStream(
- associatedClass.getResourceAsStream(resourceName),
- getMIMEType(), getFilename());
- ds.setBufferSize(getBufferSize());
- ds.setCacheTime(cacheTime);
- return ds;
- }
-
- /* documented in superclass */
- @Override
- public int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Sets the size of the download buffer used for this resource.
- *
- * @param bufferSize
- * the size of the buffer in bytes.
- */
- public void setBufferSize(int bufferSize) {
- this.bufferSize = bufferSize;
- }
-
- /* documented in superclass */
- @Override
- public long getCacheTime() {
- return cacheTime;
- }
-
- /**
- * Sets the length of cache expiration time.
- *
- * <p>
- * This gives the adapter the possibility cache streams sent to the client.
- * The caching may be made in adapter or at the client if the client
- * supports caching. Zero or negavive value disbales the caching of this
- * stream.
- * </p>
- *
- * @param cacheTime
- * the cache time in milliseconds.
- *
- */
- public void setCacheTime(long cacheTime) {
- this.cacheTime = cacheTime;
- }
-}
diff --git a/src/com/vaadin/terminal/CombinedRequest.java b/src/com/vaadin/terminal/CombinedRequest.java
deleted file mode 100644
index 5b92feb39a..0000000000
--- a/src/com/vaadin/terminal/CombinedRequest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-
-import com.vaadin.Application;
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.external.json.JSONObject;
-import com.vaadin.terminal.gwt.server.WebApplicationContext;
-import com.vaadin.terminal.gwt.server.WebBrowser;
-
-/**
- * A {@link WrappedRequest} with path and parameters from one request and
- * {@link WrappedRequest.BrowserDetails} extracted from another request.
- *
- * This class is intended to be used for a two request initialization where the
- * first request fetches the actual application page and the second request
- * contains information extracted from the browser using javascript.
- *
- */
-public class CombinedRequest implements WrappedRequest {
-
- private final WrappedRequest secondRequest;
- private Map<String, String[]> parameterMap;
-
- /**
- * Creates a new combined request based on the second request and some
- * details from the first request.
- *
- * @param secondRequest
- * the second request which will be used as the foundation of the
- * combined request
- * @throws JSONException
- * if the initialParams parameter can not be decoded
- */
- public CombinedRequest(WrappedRequest secondRequest) throws JSONException {
- this.secondRequest = secondRequest;
-
- HashMap<String, String[]> map = new HashMap<String, String[]>();
- JSONObject initialParams = new JSONObject(
- secondRequest.getParameter("initialParams"));
- for (Iterator<?> keys = initialParams.keys(); keys.hasNext();) {
- String name = (String) keys.next();
- JSONArray jsonValues = initialParams.getJSONArray(name);
- String[] values = new String[jsonValues.length()];
- for (int i = 0; i < values.length; i++) {
- values[i] = jsonValues.getString(i);
- }
- map.put(name, values);
- }
-
- parameterMap = Collections.unmodifiableMap(map);
-
- }
-
- @Override
- public String getParameter(String parameter) {
- String[] strings = getParameterMap().get(parameter);
- if (strings == null || strings.length == 0) {
- return null;
- } else {
- return strings[0];
- }
- }
-
- @Override
- public Map<String, String[]> getParameterMap() {
- return parameterMap;
- }
-
- @Override
- public int getContentLength() {
- return secondRequest.getContentLength();
- }
-
- @Override
- public InputStream getInputStream() throws IOException {
- return secondRequest.getInputStream();
- }
-
- @Override
- public Object getAttribute(String name) {
- return secondRequest.getAttribute(name);
- }
-
- @Override
- public void setAttribute(String name, Object value) {
- secondRequest.setAttribute(name, value);
- }
-
- @Override
- public String getRequestPathInfo() {
- return secondRequest.getParameter("initialPath");
- }
-
- @Override
- public int getSessionMaxInactiveInterval() {
- return secondRequest.getSessionMaxInactiveInterval();
- }
-
- @Override
- public Object getSessionAttribute(String name) {
- return secondRequest.getSessionAttribute(name);
- }
-
- @Override
- public void setSessionAttribute(String name, Object attribute) {
- secondRequest.setSessionAttribute(name, attribute);
- }
-
- @Override
- public String getContentType() {
- return secondRequest.getContentType();
- }
-
- @Override
- public BrowserDetails getBrowserDetails() {
- return new BrowserDetails() {
- @Override
- public String getUriFragment() {
- String fragment = secondRequest.getParameter("fr");
- if (fragment == null) {
- return "";
- } else {
- return fragment;
- }
- }
-
- @Override
- public String getWindowName() {
- return secondRequest.getParameter("wn");
- }
-
- @Override
- public WebBrowser getWebBrowser() {
- WebApplicationContext context = (WebApplicationContext) Application
- .getCurrent().getContext();
- return context.getBrowser();
- }
- };
- }
-
- /**
- * Gets the original second request. This can be used e.g. if a request
- * parameter from the second request is required.
- *
- * @return the original second wrapped request
- */
- public WrappedRequest getSecondRequest() {
- return secondRequest;
- }
-
- @Override
- public Locale getLocale() {
- return secondRequest.getLocale();
- }
-
- @Override
- public String getRemoteAddr() {
- return secondRequest.getRemoteAddr();
- }
-
- @Override
- public boolean isSecure() {
- return secondRequest.isSecure();
- }
-
- @Override
- public String getHeader(String name) {
- return secondRequest.getHeader(name);
- }
-
- @Override
- public DeploymentConfiguration getDeploymentConfiguration() {
- return secondRequest.getDeploymentConfiguration();
- }
-}
diff --git a/src/com/vaadin/terminal/CompositeErrorMessage.java b/src/com/vaadin/terminal/CompositeErrorMessage.java
deleted file mode 100644
index b82b622f54..0000000000
--- a/src/com/vaadin/terminal/CompositeErrorMessage.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Class for combining multiple error messages together.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class CompositeErrorMessage extends AbstractErrorMessage {
-
- /**
- * Constructor for CompositeErrorMessage.
- *
- * @param errorMessages
- * the Array of error messages that are listed togeter. Nulls are
- * ignored, but at least one message is required.
- */
- public CompositeErrorMessage(ErrorMessage[] errorMessages) {
- super(null);
- setErrorLevel(ErrorLevel.INFORMATION);
-
- for (int i = 0; i < errorMessages.length; i++) {
- addErrorMessage(errorMessages[i]);
- }
-
- if (getCauses().size() == 0) {
- throw new IllegalArgumentException(
- "Composite error message must have at least one error");
- }
-
- }
-
- /**
- * Constructor for CompositeErrorMessage.
- *
- * @param errorMessages
- * the Collection of error messages that are listed together. At
- * least one message is required.
- */
- public CompositeErrorMessage(
- Collection<? extends ErrorMessage> errorMessages) {
- super(null);
- setErrorLevel(ErrorLevel.INFORMATION);
-
- for (final Iterator<? extends ErrorMessage> i = errorMessages
- .iterator(); i.hasNext();) {
- addErrorMessage(i.next());
- }
-
- if (getCauses().size() == 0) {
- throw new IllegalArgumentException(
- "Composite error message must have at least one error");
- }
- }
-
- /**
- * Adds a error message into this composite message. Updates the level
- * field.
- *
- * @param error
- * the error message to be added. Duplicate errors are ignored.
- */
- private void addErrorMessage(ErrorMessage error) {
- if (error != null && !getCauses().contains(error)) {
- addCause(error);
- if (error.getErrorLevel().intValue() > getErrorLevel().intValue()) {
- setErrorLevel(error.getErrorLevel());
- }
- }
- }
-
- /**
- * Gets Error Iterator.
- *
- * @return the error iterator.
- */
- public Iterator<ErrorMessage> iterator() {
- return getCauses().iterator();
- }
-
- /**
- * Returns a comma separated list of the error messages.
- *
- * @return String, comma separated list of error messages.
- */
- @Override
- public String toString() {
- String retval = "[";
- int pos = 0;
- for (final Iterator<ErrorMessage> i = getCauses().iterator(); i
- .hasNext();) {
- if (pos > 0) {
- retval += ",";
- }
- pos++;
- retval += i.next().toString();
- }
- retval += "]";
-
- return retval;
- }
-}
diff --git a/src/com/vaadin/terminal/DeploymentConfiguration.java b/src/com/vaadin/terminal/DeploymentConfiguration.java
deleted file mode 100644
index ae96dcaec5..0000000000
--- a/src/com/vaadin/terminal/DeploymentConfiguration.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Properties;
-
-import javax.portlet.PortletContext;
-import javax.servlet.ServletContext;
-
-import com.vaadin.terminal.gwt.server.AddonContext;
-import com.vaadin.terminal.gwt.server.AddonContextListener;
-
-/**
- * Provide deployment specific settings that are required outside terminal
- * specific code.
- *
- * @author Vaadin Ltd.
- *
- * @since 7.0
- */
-public interface DeploymentConfiguration extends Serializable {
-
- /**
- * Gets the base URL of the location of Vaadin's static files.
- *
- * @param request
- * the request for which the location should be determined
- *
- * @return a string with the base URL for static files
- */
- public String getStaticFileLocation(WrappedRequest request);
-
- /**
- * Gets the widgetset that is configured for this deployment, e.g. from a
- * parameter in web.xml.
- *
- * @param request
- * the request for which a widgetset is required
- * @return the name of the widgetset
- */
- public String getConfiguredWidgetset(WrappedRequest request);
-
- /**
- * Gets the theme that is configured for this deployment, e.g. from a portal
- * parameter or just some sensible default value.
- *
- * @param request
- * the request for which a theme is required
- * @return the name of the theme
- */
- public String getConfiguredTheme(WrappedRequest request);
-
- /**
- * Checks whether the Vaadin application will be rendered on its own in the
- * browser or whether it will be included into some other context. A
- * standalone application may do things that might interfere with other
- * parts of a page, e.g. changing the page title and requesting focus upon
- * loading.
- *
- * @param request
- * the request for which the application is loaded
- * @return a boolean indicating whether the application should be standalone
- */
- public boolean isStandalone(WrappedRequest request);
-
- /**
- * Gets a configured property. The properties are typically read from e.g.
- * web.xml or from system properties of the JVM.
- *
- * @param propertyName
- * The simple of the property, in some contexts, lookup might be
- * performed using variations of the provided name.
- * @param defaultValue
- * the default value that should be used if no value has been
- * defined
- * @return the property value, or the passed default value if no property
- * value is found
- */
- public String getApplicationOrSystemProperty(String propertyName,
- String defaultValue);
-
- /**
- * Get the class loader to use for loading classes loaded by name, e.g.
- * custom Root classes. <code>null</code> indicates that the default class
- * loader should be used.
- *
- * @return the class loader to use, or <code>null</code>
- */
- public ClassLoader getClassLoader();
-
- /**
- * Returns the MIME type of the specified file, or null if the MIME type is
- * not known. The MIME type is determined by the configuration of the
- * container, and may be specified in a deployment descriptor. Common MIME
- * types are "text/html" and "image/gif".
- *
- * @param resourceName
- * a String specifying the name of a file
- * @return a String specifying the file's MIME type
- *
- * @see ServletContext#getMimeType(String)
- * @see PortletContext#getMimeType(String)
- */
- public String getMimeType(String resourceName);
-
- /**
- * Gets the properties configured for the deployment, e.g. as init
- * parameters to the servlet or portlet.
- *
- * @return properties for the application.
- */
- public Properties getInitParameters();
-
- public Iterator<AddonContextListener> getAddonContextListeners();
-
- public AddonContext getAddonContext();
-
- public void setAddonContext(AddonContext vaadinContext);
-}
diff --git a/src/com/vaadin/terminal/DownloadStream.java b/src/com/vaadin/terminal/DownloadStream.java
deleted file mode 100644
index 9853b0eee2..0000000000
--- a/src/com/vaadin/terminal/DownloadStream.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
-import com.vaadin.terminal.gwt.server.Constants;
-
-/**
- * Downloadable stream.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class DownloadStream implements Serializable {
-
- /**
- * Maximum cache time.
- */
- public static final long MAX_CACHETIME = Long.MAX_VALUE;
-
- /**
- * Default cache time.
- */
- public static final long DEFAULT_CACHETIME = 1000 * 60 * 60 * 24;
-
- private InputStream stream;
-
- private String contentType;
-
- private String fileName;
-
- private Map<String, String> params;
-
- private long cacheTime = DEFAULT_CACHETIME;
-
- private int bufferSize = 0;
-
- /**
- * Creates a new instance of DownloadStream.
- */
- public DownloadStream(InputStream stream, String contentType,
- String fileName) {
- setStream(stream);
- setContentType(contentType);
- setFileName(fileName);
- }
-
- /**
- * Gets downloadable stream.
- *
- * @return output stream.
- */
- public InputStream getStream() {
- return stream;
- }
-
- /**
- * Sets the stream.
- *
- * @param stream
- * The stream to set
- */
- public void setStream(InputStream stream) {
- this.stream = stream;
- }
-
- /**
- * Gets stream content type.
- *
- * @return type of the stream content.
- */
- public String getContentType() {
- return contentType;
- }
-
- /**
- * Sets stream content type.
- *
- * @param contentType
- * the contentType to set
- */
- public void setContentType(String contentType) {
- this.contentType = contentType;
- }
-
- /**
- * Returns the file name.
- *
- * @return the name of the file.
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * Sets the file name.
- *
- * @param fileName
- * the file name to set.
- */
- public void setFileName(String fileName) {
- this.fileName = fileName;
- }
-
- /**
- * Sets a paramater for download stream. Parameters are optional information
- * about the downloadable stream and their meaning depends on the used
- * adapter. For example in WebAdapter they are interpreted as HTTP response
- * headers.
- *
- * If the parameters by this name exists, the old value is replaced.
- *
- * @param name
- * the Name of the parameter to set.
- * @param value
- * the Value of the parameter to set.
- */
- public void setParameter(String name, String value) {
- if (params == null) {
- params = new HashMap<String, String>();
- }
- params.put(name, value);
- }
-
- /**
- * Gets a paramater for download stream. Parameters are optional information
- * about the downloadable stream and their meaning depends on the used
- * adapter. For example in WebAdapter they are interpreted as HTTP response
- * headers.
- *
- * @param name
- * the Name of the parameter to set.
- * @return Value of the parameter or null if the parameter does not exist.
- */
- public String getParameter(String name) {
- if (params != null) {
- return params.get(name);
- }
- return null;
- }
-
- /**
- * Gets the names of the parameters.
- *
- * @return Iterator of names or null if no parameters are set.
- */
- public Iterator<String> getParameterNames() {
- if (params != null) {
- return params.keySet().iterator();
- }
- return null;
- }
-
- /**
- * Gets length of cache expiration time. This gives the adapter the
- * possibility cache streams sent to the client. The caching may be made in
- * adapter or at the client if the client supports caching. Default is
- * <code>DEFAULT_CACHETIME</code>.
- *
- * @return Cache time in milliseconds
- */
- public long getCacheTime() {
- return cacheTime;
- }
-
- /**
- * Sets length of cache expiration time. This gives the adapter the
- * possibility cache streams sent to the client. The caching may be made in
- * adapter or at the client if the client supports caching. Zero or negavive
- * value disbales the caching of this stream.
- *
- * @param cacheTime
- * the cache time in milliseconds.
- */
- public void setCacheTime(long cacheTime) {
- this.cacheTime = cacheTime;
- }
-
- /**
- * Gets the size of the download buffer.
- *
- * @return int The size of the buffer in bytes.
- */
- public int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Sets the size of the download buffer.
- *
- * @param bufferSize
- * the size of the buffer in bytes.
- *
- * @since 7.0
- */
- public void setBufferSize(int bufferSize) {
- this.bufferSize = bufferSize;
- }
-
- /**
- * Writes this download stream to a wrapped response. This takes care of
- * setting response headers according to what is defined in this download
- * stream ({@link #getContentType()}, {@link #getCacheTime()},
- * {@link #getFileName()}) and transferring the data from the stream (
- * {@link #getStream()}) to the response. Defined parameters (
- * {@link #getParameterNames()}) are also included as headers in the
- * response. If there's is a parameter named <code>Location</code>, a
- * redirect (302 Moved temporarily) is sent instead of the contents of this
- * stream.
- *
- * @param response
- * the wrapped response to write this download stream to
- * @throws IOException
- * passed through from the wrapped response
- *
- * @since 7.0
- */
- public void writeTo(WrappedResponse response) throws IOException {
- if (getParameter("Location") != null) {
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", getParameter("Location"));
- return;
- }
-
- // Download from given stream
- final InputStream data = getStream();
- if (data != null) {
-
- OutputStream out = null;
- try {
- // Sets content type
- response.setContentType(getContentType());
-
- // Sets cache headers
- response.setCacheTime(getCacheTime());
-
- // Copy download stream parameters directly
- // to HTTP headers.
- final Iterator<String> i = getParameterNames();
- if (i != null) {
- while (i.hasNext()) {
- final String param = i.next();
- response.setHeader(param, getParameter(param));
- }
- }
-
- // suggest local filename from DownloadStream if
- // Content-Disposition
- // not explicitly set
- String contentDispositionValue = getParameter("Content-Disposition");
- if (contentDispositionValue == null) {
- contentDispositionValue = "filename=\"" + getFileName()
- + "\"";
- response.setHeader("Content-Disposition",
- contentDispositionValue);
- }
-
- int bufferSize = getBufferSize();
- if (bufferSize <= 0 || bufferSize > Constants.MAX_BUFFER_SIZE) {
- bufferSize = Constants.DEFAULT_BUFFER_SIZE;
- }
- final byte[] buffer = new byte[bufferSize];
- int bytesRead = 0;
-
- out = response.getOutputStream();
-
- long totalWritten = 0;
- while ((bytesRead = data.read(buffer)) > 0) {
- out.write(buffer, 0, bytesRead);
-
- totalWritten += bytesRead;
- if (totalWritten >= buffer.length) {
- // Avoid chunked encoding for small resources
- out.flush();
- }
- }
- } finally {
- tryToCloseStream(out);
- tryToCloseStream(data);
- }
- }
- }
-
- /**
- * Helper method that tries to close an output stream and ignores any
- * exceptions.
- *
- * @param out
- * the output stream to close, <code>null</code> is also
- * supported
- */
- static void tryToCloseStream(OutputStream out) {
- try {
- // try to close output stream (e.g. file handle)
- if (out != null) {
- out.close();
- }
- } catch (IOException e1) {
- // NOP
- }
- }
-
- /**
- * Helper method that tries to close an input stream and ignores any
- * exceptions.
- *
- * @param in
- * the input stream to close, <code>null</code> is also supported
- */
- static void tryToCloseStream(InputStream in) {
- try {
- // try to close output stream (e.g. file handle)
- if (in != null) {
- in.close();
- }
- } catch (IOException e1) {
- // NOP
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/ErrorMessage.java b/src/com/vaadin/terminal/ErrorMessage.java
deleted file mode 100644
index 60a0780a72..0000000000
--- a/src/com/vaadin/terminal/ErrorMessage.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-/**
- * Interface for rendering error messages to terminal. All the visible errors
- * shown to user must implement this interface.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface ErrorMessage extends Serializable {
-
- public enum ErrorLevel {
- /**
- * Error code for informational messages.
- */
- INFORMATION("info", 0),
- /**
- * Error code for warning messages.
- */
- WARNING("warning", 1),
- /**
- * Error code for regular error messages.
- */
- ERROR("error", 2),
- /**
- * Error code for critical error messages.
- */
- CRITICAL("critical", 3),
- /**
- * Error code for system errors and bugs.
- */
- SYSTEMERROR("system", 4);
-
- String text;
- int errorLevel;
-
- private ErrorLevel(String text, int errorLevel) {
- this.text = text;
- this.errorLevel = errorLevel;
- }
-
- /**
- * Textual representation for server-client communication of level
- *
- * @return String for error severity
- */
- public String getText() {
- return text;
- }
-
- /**
- * Integer representation of error severity for comparison
- *
- * @return integer for error severity
- */
- public int intValue() {
- return errorLevel;
- }
-
- @Override
- public String toString() {
- return text;
- }
-
- }
-
- /**
- * @deprecated from 7.0, use {@link ErrorLevel#SYSTEMERROR} instead    
- */
- @Deprecated
- public static final ErrorLevel SYSTEMERROR = ErrorLevel.SYSTEMERROR;
-
- /**
- * @deprecated from 7.0, use {@link ErrorLevel#CRITICAL} instead    
- */
- @Deprecated
- public static final ErrorLevel CRITICAL = ErrorLevel.CRITICAL;
-
- /**
- * @deprecated from 7.0, use {@link ErrorLevel#ERROR} instead    
- */
-
- @Deprecated
- public static final ErrorLevel ERROR = ErrorLevel.ERROR;
-
- /**
- * @deprecated from 7.0, use {@link ErrorLevel#WARNING} instead    
- */
- @Deprecated
- public static final ErrorLevel WARNING = ErrorLevel.WARNING;
-
- /**
- * @deprecated from 7.0, use {@link ErrorLevel#INFORMATION} instead    
- */
- @Deprecated
- public static final ErrorLevel INFORMATION = ErrorLevel.INFORMATION;
-
- /**
- * Gets the errors level.
- *
- * @return the level of error as an integer.
- */
- public ErrorLevel getErrorLevel();
-
- /**
- * Returns the HTML formatted message to show in as the error message on the
- * client.
- *
- * This method should perform any necessary escaping to avoid XSS attacks.
- *
- * TODO this API may still change to use a separate data transfer object
- *
- * @return HTML formatted string for the error message
- * @since 7.0
- */
- public String getFormattedHtmlMessage();
-
-}
diff --git a/src/com/vaadin/terminal/Extension.java b/src/com/vaadin/terminal/Extension.java
deleted file mode 100644
index ef5bb4cf8d..0000000000
--- a/src/com/vaadin/terminal/Extension.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * An extension is an entity that is attached to a Component or another
- * Extension and independently communicates between client and server.
- * <p>
- * An extension can only be attached once. It is not supported to move an
- * extension from one target to another.
- * <p>
- * Extensions can use shared state and RPC in the same way as components.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public interface Extension extends ClientConnector {
- /*
- * Currently just an empty marker interface to distinguish between
- * extensions and other connectors, e.g. components
- */
-}
diff --git a/src/com/vaadin/terminal/ExternalResource.java b/src/com/vaadin/terminal/ExternalResource.java
deleted file mode 100644
index 84fcc65a44..0000000000
--- a/src/com/vaadin/terminal/ExternalResource.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.net.URL;
-
-import com.vaadin.service.FileTypeResolver;
-
-/**
- * <code>ExternalResource</code> implements source for resources fetched from
- * location specified by URL:s. The resources are fetched directly by the client
- * terminal and are not fetched trough the terminal adapter.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ExternalResource implements Resource, Serializable {
-
- /**
- * Url of the download.
- */
- private String sourceURL = null;
-
- /**
- * MIME Type for the resource
- */
- private String mimeType = null;
-
- /**
- * Creates a new download component for downloading directly from given URL.
- *
- * @param sourceURL
- * the source URL.
- */
- public ExternalResource(URL sourceURL) {
- if (sourceURL == null) {
- throw new RuntimeException("Source must be non-null");
- }
-
- this.sourceURL = sourceURL.toString();
- }
-
- /**
- * Creates a new download component for downloading directly from given URL.
- *
- * @param sourceURL
- * the source URL.
- * @param mimeType
- * the MIME Type
- */
- public ExternalResource(URL sourceURL, String mimeType) {
- this(sourceURL);
- this.mimeType = mimeType;
- }
-
- /**
- * Creates a new download component for downloading directly from given URL.
- *
- * @param sourceURL
- * the source URL.
- */
- public ExternalResource(String sourceURL) {
- if (sourceURL == null) {
- throw new RuntimeException("Source must be non-null");
- }
-
- this.sourceURL = sourceURL.toString();
- }
-
- /**
- * Creates a new download component for downloading directly from given URL.
- *
- * @param sourceURL
- * the source URL.
- * @param mimeType
- * the MIME Type
- */
- public ExternalResource(String sourceURL, String mimeType) {
- this(sourceURL);
- this.mimeType = mimeType;
- }
-
- /**
- * Gets the URL of the external resource.
- *
- * @return the URL of the external resource.
- */
- public String getURL() {
- return sourceURL;
- }
-
- /**
- * Gets the MIME type of the resource.
- *
- * @see com.vaadin.terminal.Resource#getMIMEType()
- */
- @Override
- public String getMIMEType() {
- if (mimeType == null) {
- mimeType = FileTypeResolver.getMIMEType(getURL().toString());
- }
- return mimeType;
- }
-
- /**
- * Sets the MIME type of the resource.
- */
- public void setMIMEType(String mimeType) {
- this.mimeType = mimeType;
- }
-
-}
diff --git a/src/com/vaadin/terminal/FileResource.java b/src/com/vaadin/terminal/FileResource.java
deleted file mode 100644
index e3c9f0172a..0000000000
--- a/src/com/vaadin/terminal/FileResource.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
-import com.vaadin.Application;
-import com.vaadin.service.FileTypeResolver;
-import com.vaadin.terminal.Terminal.ErrorEvent;
-
-/**
- * <code>FileResources</code> are files or directories on local filesystem. The
- * files and directories are served through URI:s to the client terminal and
- * thus must be registered to an URI context before they can be used. The
- * resource is automatically registered to the application when it is created.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class FileResource implements ApplicationResource {
-
- /**
- * Default buffer size for this stream resource.
- */
- private int bufferSize = 0;
-
- /**
- * File where the downloaded content is fetched from.
- */
- private File sourceFile;
-
- /**
- * Application.
- */
- private final Application application;
-
- /**
- * Default cache time for this stream resource.
- */
- private long cacheTime = DownloadStream.DEFAULT_CACHETIME;
-
- /**
- * Creates a new file resource for providing given file for client
- * terminals.
- */
- public FileResource(File sourceFile, Application application) {
- this.application = application;
- setSourceFile(sourceFile);
- application.addResource(this);
- }
-
- /**
- * Gets the resource as stream.
- *
- * @see com.vaadin.terminal.ApplicationResource#getStream()
- */
- @Override
- public DownloadStream getStream() {
- try {
- final DownloadStream ds = new DownloadStream(new FileInputStream(
- sourceFile), getMIMEType(), getFilename());
- ds.setParameter("Content-Length",
- String.valueOf(sourceFile.length()));
-
- ds.setCacheTime(cacheTime);
- return ds;
- } catch (final FileNotFoundException e) {
- // Log the exception using the application error handler
- getApplication().getErrorHandler().terminalError(new ErrorEvent() {
-
- @Override
- public Throwable getThrowable() {
- return e;
- }
-
- });
-
- return null;
- }
- }
-
- /**
- * Gets the source file.
- *
- * @return the source File.
- */
- public File getSourceFile() {
- return sourceFile;
- }
-
- /**
- * Sets the source file.
- *
- * @param sourceFile
- * the source file to set.
- */
- public void setSourceFile(File sourceFile) {
- this.sourceFile = sourceFile;
- }
-
- /**
- * @see com.vaadin.terminal.ApplicationResource#getApplication()
- */
- @Override
- public Application getApplication() {
- return application;
- }
-
- /**
- * @see com.vaadin.terminal.ApplicationResource#getFilename()
- */
- @Override
- public String getFilename() {
- return sourceFile.getName();
- }
-
- /**
- * @see com.vaadin.terminal.Resource#getMIMEType()
- */
- @Override
- public String getMIMEType() {
- return FileTypeResolver.getMIMEType(sourceFile);
- }
-
- /**
- * Gets the length of cache expiration time. This gives the adapter the
- * possibility cache streams sent to the client. The caching may be made in
- * adapter or at the client if the client supports caching. Default is
- * <code>DownloadStream.DEFAULT_CACHETIME</code>.
- *
- * @return Cache time in milliseconds.
- */
- @Override
- public long getCacheTime() {
- return cacheTime;
- }
-
- /**
- * Sets the length of cache expiration time. This gives the adapter the
- * possibility cache streams sent to the client. The caching may be made in
- * adapter or at the client if the client supports caching. Zero or negavive
- * value disbales the caching of this stream.
- *
- * @param cacheTime
- * the cache time in milliseconds.
- */
- public void setCacheTime(long cacheTime) {
- this.cacheTime = cacheTime;
- }
-
- /* documented in superclass */
- @Override
- public int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Sets the size of the download buffer used for this resource.
- *
- * @param bufferSize
- * the size of the buffer in bytes.
- */
- public void setBufferSize(int bufferSize) {
- this.bufferSize = bufferSize;
- }
-
-}
diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java
deleted file mode 100644
index 265e578c6d..0000000000
--- a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.shared.JavaScriptConnectorState;
-import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.AbstractJavaScriptComponent;
-import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc;
-import com.vaadin.ui.JavaScriptFunction;
-
-/**
- * Internal helper class used to implement functionality common to
- * {@link AbstractJavaScriptComponent} and {@link AbstractJavaScriptExtension}.
- * Corresponding support in client-side code is in
- * {@link JavaScriptConnectorHelper}.
- * <p>
- * You should most likely no use this class directly.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public class JavaScriptCallbackHelper implements Serializable {
-
- private static final Method CALL_METHOD = ReflectTools.findMethod(
- JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class);
- private AbstractClientConnector connector;
-
- private Map<String, JavaScriptFunction> callbacks = new HashMap<String, JavaScriptFunction>();
- private JavaScriptCallbackRpc javascriptCallbackRpc;
-
- public JavaScriptCallbackHelper(AbstractClientConnector connector) {
- this.connector = connector;
- }
-
- public void registerCallback(String functionName,
- JavaScriptFunction javaScriptCallback) {
- callbacks.put(functionName, javaScriptCallback);
- JavaScriptConnectorState state = getConnectorState();
- if (state.getCallbackNames().add(functionName)) {
- connector.requestRepaint();
- }
- ensureRpc();
- }
-
- private JavaScriptConnectorState getConnectorState() {
- JavaScriptConnectorState state = (JavaScriptConnectorState) connector
- .getState();
- return state;
- }
-
- private void ensureRpc() {
- if (javascriptCallbackRpc == null) {
- javascriptCallbackRpc = new JavaScriptCallbackRpc() {
- @Override
- public void call(String name, JSONArray arguments) {
- JavaScriptFunction callback = callbacks.get(name);
- try {
- callback.call(arguments);
- } catch (JSONException e) {
- throw new IllegalArgumentException(e);
- }
- }
- };
- connector.registerRpc(javascriptCallbackRpc);
- }
- }
-
- public void invokeCallback(String name, Object... arguments) {
- if (callbacks.containsKey(name)) {
- throw new IllegalStateException(
- "Can't call callback "
- + name
- + " on the client because a callback with the same name is registered on the server.");
- }
- JSONArray args = new JSONArray(Arrays.asList(arguments));
- connector.addMethodInvocationToQueue(
- JavaScriptCallbackRpc.class.getName(), CALL_METHOD,
- new Object[] { name, args });
- connector.requestRepaint();
- }
-
- public void registerRpc(Class<?> rpcInterfaceType) {
- if (rpcInterfaceType == JavaScriptCallbackRpc.class) {
- // Ignore
- return;
- }
- Map<String, Set<String>> rpcInterfaces = getConnectorState()
- .getRpcInterfaces();
- String interfaceName = rpcInterfaceType.getName();
- if (!rpcInterfaces.containsKey(interfaceName)) {
- Set<String> methodNames = new HashSet<String>();
-
- for (Method method : rpcInterfaceType.getMethods()) {
- methodNames.add(method.getName());
- }
-
- rpcInterfaces.put(interfaceName, methodNames);
- connector.requestRepaint();
- }
- }
-
-}
diff --git a/src/com/vaadin/terminal/KeyMapper.java b/src/com/vaadin/terminal/KeyMapper.java
deleted file mode 100644
index 3f19692ef1..0000000000
--- a/src/com/vaadin/terminal/KeyMapper.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-/**
- * <code>KeyMapper</code> is the simple two-way map for generating textual keys
- * for objects and retrieving the objects later with the key.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public class KeyMapper<V> implements Serializable {
-
- private int lastKey = 0;
-
- private final HashMap<V, String> objectKeyMap = new HashMap<V, String>();
-
- private final HashMap<String, V> keyObjectMap = new HashMap<String, V>();
-
- /**
- * Gets key for an object.
- *
- * @param o
- * the object.
- */
- public String key(V o) {
-
- if (o == null) {
- return "null";
- }
-
- // If the object is already mapped, use existing key
- String key = objectKeyMap.get(o);
- if (key != null) {
- return key;
- }
-
- // If the object is not yet mapped, map it
- key = String.valueOf(++lastKey);
- objectKeyMap.put(o, key);
- keyObjectMap.put(key, o);
-
- return key;
- }
-
- /**
- * Retrieves object with the key.
- *
- * @param key
- * the name with the desired value.
- * @return the object with the key.
- */
- public V get(String key) {
- return keyObjectMap.get(key);
- }
-
- /**
- * Removes object from the mapper.
- *
- * @param removeobj
- * the object to be removed.
- */
- public void remove(V removeobj) {
- final String key = objectKeyMap.get(removeobj);
-
- if (key != null) {
- objectKeyMap.remove(removeobj);
- keyObjectMap.remove(key);
- }
- }
-
- /**
- * Removes all objects from the mapper.
- */
- public void removeAll() {
- objectKeyMap.clear();
- keyObjectMap.clear();
- }
-}
diff --git a/src/com/vaadin/terminal/LegacyPaint.java b/src/com/vaadin/terminal/LegacyPaint.java
deleted file mode 100644
index ea93e3db7f..0000000000
--- a/src/com/vaadin/terminal/LegacyPaint.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.PaintTarget.PaintStatus;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.HasComponents;
-
-public class LegacyPaint implements Serializable {
- /**
- *
- * <p>
- * Paints the Paintable into a UIDL stream. This method creates the UIDL
- * sequence describing it and outputs it to the given UIDL stream.
- * </p>
- *
- * <p>
- * It is called when the contents of the component should be painted in
- * response to the component first being shown or having been altered so
- * that its visual representation is changed.
- * </p>
- *
- * <p>
- * <b>Do not override this to paint your component.</b> Override
- * {@link #paintContent(PaintTarget)} instead.
- * </p>
- *
- *
- * @param target
- * the target UIDL stream where the component should paint itself
- * to.
- * @throws PaintException
- * if the paint operation failed.
- */
- public static void paint(Component component, PaintTarget target)
- throws PaintException {
- // Only paint content of visible components.
- if (!isVisibleInContext(component)) {
- return;
- }
-
- final String tag = target.getTag(component);
- final PaintStatus status = target.startPaintable(component, tag);
- if (PaintStatus.CACHED == status) {
- // nothing to do but flag as cached and close the paintable tag
- target.addAttribute("cached", true);
- } else {
- // Paint the contents of the component
- if (component instanceof Vaadin6Component) {
- ((Vaadin6Component) component).paintContent(target);
- }
-
- }
- target.endPaintable(component);
-
- }
-
- /**
- * Checks if the component is visible and its parent is visible,
- * recursively.
- * <p>
- * This is only a helper until paint is moved away from this class.
- *
- * @return
- */
- protected static boolean isVisibleInContext(Component c) {
- HasComponents p = c.getParent();
- while (p != null) {
- if (!p.isVisible()) {
- return false;
- }
- p = p.getParent();
- }
- if (c.getParent() != null && !c.getParent().isComponentVisible(c)) {
- return false;
- }
-
- // All parents visible, return this state
- return c.isVisible();
- }
-
-}
diff --git a/src/com/vaadin/terminal/Page.java b/src/com/vaadin/terminal/Page.java
deleted file mode 100644
index a068e7573e..0000000000
--- a/src/com/vaadin/terminal/Page.java
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.EventObject;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.vaadin.event.EventRouter;
-import com.vaadin.shared.ui.root.PageClientRpc;
-import com.vaadin.terminal.WrappedRequest.BrowserDetails;
-import com.vaadin.terminal.gwt.client.ui.notification.VNotification;
-import com.vaadin.terminal.gwt.client.ui.root.VRoot;
-import com.vaadin.terminal.gwt.server.WebApplicationContext;
-import com.vaadin.terminal.gwt.server.WebBrowser;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.JavaScript;
-import com.vaadin.ui.Notification;
-import com.vaadin.ui.Root;
-
-public class Page implements Serializable {
-
- /**
- * Listener that gets notified when the size of the browser window
- * containing the root has changed.
- *
- * @see Root#addListener(BrowserWindowResizeListener)
- */
- public interface BrowserWindowResizeListener extends Serializable {
- /**
- * Invoked when the browser window containing a Root has been resized.
- *
- * @param event
- * a browser window resize event
- */
- public void browserWindowResized(BrowserWindowResizeEvent event);
- }
-
- /**
- * Event that is fired when a browser window containing a root is resized.
- */
- public class BrowserWindowResizeEvent extends EventObject {
-
- private final int width;
- private final int height;
-
- /**
- * Creates a new event
- *
- * @param source
- * the root for which the browser window has been resized
- * @param width
- * the new width of the browser window
- * @param height
- * the new height of the browser window
- */
- public BrowserWindowResizeEvent(Page source, int width, int height) {
- super(source);
- this.width = width;
- this.height = height;
- }
-
- @Override
- public Page getSource() {
- return (Page) super.getSource();
- }
-
- /**
- * Gets the new browser window height
- *
- * @return an integer with the new pixel height of the browser window
- */
- public int getHeight() {
- return height;
- }
-
- /**
- * Gets the new browser window width
- *
- * @return an integer with the new pixel width of the browser window
- */
- public int getWidth() {
- return width;
- }
- }
-
- /**
- * Private class for storing properties related to opening resources.
- */
- private class OpenResource implements Serializable {
-
- /**
- * The resource to open
- */
- private final Resource resource;
-
- /**
- * The name of the target window
- */
- private final String name;
-
- /**
- * The width of the target window
- */
- private final int width;
-
- /**
- * The height of the target window
- */
- private final int height;
-
- /**
- * The border style of the target window
- */
- private final int border;
-
- /**
- * Creates a new open resource.
- *
- * @param resource
- * The resource to open
- * @param name
- * The name of the target window
- * @param width
- * The width of the target window
- * @param height
- * The height of the target window
- * @param border
- * The border style of the target window
- */
- private OpenResource(Resource resource, String name, int width,
- int height, int border) {
- this.resource = resource;
- this.name = name;
- this.width = width;
- this.height = height;
- this.border = border;
- }
-
- /**
- * Paints the open request. Should be painted inside the window.
- *
- * @param target
- * the paint target
- * @throws PaintException
- * if the paint operation fails
- */
- private void paintContent(PaintTarget target) throws PaintException {
- target.startTag("open");
- target.addAttribute("src", resource);
- if (name != null && name.length() > 0) {
- target.addAttribute("name", name);
- }
- if (width >= 0) {
- target.addAttribute("width", width);
- }
- if (height >= 0) {
- target.addAttribute("height", height);
- }
- switch (border) {
- case BORDER_MINIMAL:
- target.addAttribute("border", "minimal");
- break;
- case BORDER_NONE:
- target.addAttribute("border", "none");
- break;
- }
-
- target.endTag("open");
- }
- }
-
- private static final Method BROWSWER_RESIZE_METHOD = ReflectTools
- .findMethod(BrowserWindowResizeListener.class,
- "browserWindowResized", BrowserWindowResizeEvent.class);
-
- /**
- * A border style used for opening resources in a window without a border.
- */
- public static final int BORDER_NONE = 0;
-
- /**
- * A border style used for opening resources in a window with a minimal
- * border.
- */
- public static final int BORDER_MINIMAL = 1;
-
- /**
- * A border style that indicates that the default border style should be
- * used when opening resources.
- */
- public static final int BORDER_DEFAULT = 2;
-
- /**
- * Listener that listens changes in URI fragment.
- */
- public interface FragmentChangedListener extends Serializable {
- public void fragmentChanged(FragmentChangedEvent event);
- }
-
- private static final Method FRAGMENT_CHANGED_METHOD = ReflectTools
- .findMethod(Page.FragmentChangedListener.class, "fragmentChanged",
- FragmentChangedEvent.class);
-
- /**
- * Resources to be opened automatically on next repaint. The list is
- * automatically cleared when it has been sent to the client.
- */
- private final LinkedList<OpenResource> openList = new LinkedList<OpenResource>();
-
- /**
- * A list of notifications that are waiting to be sent to the client.
- * Cleared (set to null) when the notifications have been sent.
- */
- private List<Notification> notifications;
-
- /**
- * Event fired when uri fragment changes.
- */
- public class FragmentChangedEvent extends EventObject {
-
- /**
- * The new uri fragment
- */
- private final String fragment;
-
- /**
- * Creates a new instance of UriFragmentReader change event.
- *
- * @param source
- * the Source of the event.
- */
- public FragmentChangedEvent(Page source, String fragment) {
- super(source);
- this.fragment = fragment;
- }
-
- /**
- * Gets the root in which the fragment has changed.
- *
- * @return the root in which the fragment has changed
- */
- public Page getPage() {
- return (Page) getSource();
- }
-
- /**
- * Get the new fragment
- *
- * @return the new fragment
- */
- public String getFragment() {
- return fragment;
- }
- }
-
- private EventRouter eventRouter;
-
- /**
- * The current URI fragment.
- */
- private String fragment;
-
- private final Root root;
-
- private int browserWindowWidth = -1;
- private int browserWindowHeight = -1;
-
- private JavaScript javaScript;
-
- public Page(Root root) {
- this.root = root;
- }
-
- private void addListener(Class<?> eventType, Object target, Method method) {
- if (eventRouter == null) {
- eventRouter = new EventRouter();
- }
- eventRouter.addListener(eventType, target, method);
- }
-
- private void removeListener(Class<?> eventType, Object target, Method method) {
- if (eventRouter != null) {
- eventRouter.removeListener(eventType, target, method);
- }
- }
-
- public void addListener(Page.FragmentChangedListener listener) {
- addListener(FragmentChangedEvent.class, listener,
- FRAGMENT_CHANGED_METHOD);
- }
-
- public void removeListener(Page.FragmentChangedListener listener) {
- removeListener(FragmentChangedEvent.class, listener,
- FRAGMENT_CHANGED_METHOD);
- }
-
- /**
- * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent}
- *
- * @param newFragment
- * id of the new fragment
- * @param fireEvent
- * true to fire event
- * @see FragmentChangedEvent
- * @see Page.FragmentChangedListener
- */
- public void setFragment(String newFragment, boolean fireEvents) {
- if (newFragment == null) {
- throw new NullPointerException("The fragment may not be null");
- }
- if (!newFragment.equals(fragment)) {
- fragment = newFragment;
- if (fireEvents) {
- fireEvent(new FragmentChangedEvent(this, newFragment));
- }
- root.requestRepaint();
- }
- }
-
- private void fireEvent(EventObject event) {
- if (eventRouter != null) {
- eventRouter.fireEvent(event);
- }
- }
-
- /**
- * Sets URI fragment. This method fires a {@link FragmentChangedEvent}
- *
- * @param newFragment
- * id of the new fragment
- * @see FragmentChangedEvent
- * @see Page.FragmentChangedListener
- */
- public void setFragment(String newFragment) {
- setFragment(newFragment, true);
- }
-
- /**
- * Gets currently set URI fragment.
- * <p>
- * To listen changes in fragment, hook a
- * {@link Page.FragmentChangedListener}.
- *
- * @return the current fragment in browser uri or null if not known
- */
- public String getFragment() {
- return fragment;
- }
-
- public void init(WrappedRequest request) {
- BrowserDetails browserDetails = request.getBrowserDetails();
- if (browserDetails != null) {
- fragment = browserDetails.getUriFragment();
- }
- }
-
- public WebBrowser getWebBrowser() {
- return ((WebApplicationContext) root.getApplication().getContext())
- .getBrowser();
- }
-
- public void setBrowserWindowSize(Integer width, Integer height) {
- boolean fireEvent = false;
-
- if (width != null) {
- int newWidth = width.intValue();
- if (newWidth != browserWindowWidth) {
- browserWindowWidth = newWidth;
- fireEvent = true;
- }
- }
-
- if (height != null) {
- int newHeight = height.intValue();
- if (newHeight != browserWindowHeight) {
- browserWindowHeight = newHeight;
- fireEvent = true;
- }
- }
-
- if (fireEvent) {
- fireEvent(new BrowserWindowResizeEvent(this, browserWindowWidth,
- browserWindowHeight));
- }
-
- }
-
- /**
- * Adds a new {@link BrowserWindowResizeListener} to this root. The listener
- * will be notified whenever the browser window within which this root
- * resides is resized.
- *
- * @param resizeListener
- * the listener to add
- *
- * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent)
- * @see #setResizeLazy(boolean)
- */
- public void addListener(BrowserWindowResizeListener resizeListener) {
- addListener(BrowserWindowResizeEvent.class, resizeListener,
- BROWSWER_RESIZE_METHOD);
- }
-
- /**
- * Removes a {@link BrowserWindowResizeListener} from this root. The
- * listener will no longer be notified when the browser window is resized.
- *
- * @param resizeListener
- * the listener to remove
- */
- public void removeListener(BrowserWindowResizeListener resizeListener) {
- removeListener(BrowserWindowResizeEvent.class, resizeListener,
- BROWSWER_RESIZE_METHOD);
- }
-
- /**
- * Gets the last known height of the browser window in which this root
- * resides.
- *
- * @return the browser window height in pixels
- */
- public int getBrowserWindowHeight() {
- return browserWindowHeight;
- }
-
- /**
- * Gets the last known width of the browser window in which this root
- * resides.
- *
- * @return the browser window width in pixels
- */
- public int getBrowserWindowWidth() {
- return browserWindowWidth;
- }
-
- public JavaScript getJavaScript() {
- if (javaScript == null) {
- // Create and attach on first use
- javaScript = new JavaScript();
- javaScript.extend(root);
- }
-
- return javaScript;
- }
-
- public void paintContent(PaintTarget target) throws PaintException {
- if (!openList.isEmpty()) {
- for (final Iterator<OpenResource> i = openList.iterator(); i
- .hasNext();) {
- (i.next()).paintContent(target);
- }
- openList.clear();
- }
-
- // Paint notifications
- if (notifications != null) {
- target.startTag("notifications");
- for (final Iterator<Notification> it = notifications.iterator(); it
- .hasNext();) {
- final Notification n = it.next();
- target.startTag("notification");
- if (n.getCaption() != null) {
- target.addAttribute(
- VNotification.ATTRIBUTE_NOTIFICATION_CAPTION,
- n.getCaption());
- }
- if (n.getDescription() != null) {
- target.addAttribute(
- VNotification.ATTRIBUTE_NOTIFICATION_MESSAGE,
- n.getDescription());
- }
- if (n.getIcon() != null) {
- target.addAttribute(
- VNotification.ATTRIBUTE_NOTIFICATION_ICON,
- n.getIcon());
- }
- if (!n.isHtmlContentAllowed()) {
- target.addAttribute(
- VRoot.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, true);
- }
- target.addAttribute(
- VNotification.ATTRIBUTE_NOTIFICATION_POSITION,
- n.getPosition());
- target.addAttribute(VNotification.ATTRIBUTE_NOTIFICATION_DELAY,
- n.getDelayMsec());
- if (n.getStyleName() != null) {
- target.addAttribute(
- VNotification.ATTRIBUTE_NOTIFICATION_STYLE,
- n.getStyleName());
- }
- target.endTag("notification");
- }
- target.endTag("notifications");
- notifications = null;
- }
-
- if (fragment != null) {
- target.addAttribute(VRoot.FRAGMENT_VARIABLE, fragment);
- }
-
- }
-
- /**
- * Opens the given resource in this root. The contents of this Root is
- * replaced by the {@code Resource}.
- *
- * @param resource
- * the resource to show in this root
- */
- public void open(Resource resource) {
- openList.add(new OpenResource(resource, null, -1, -1, BORDER_DEFAULT));
- root.requestRepaint();
- }
-
- /**
- * Opens the given resource in a window with the given name.
- * <p>
- * The supplied {@code windowName} is used as the target name in a
- * window.open call in the client. This means that special values such as
- * "_blank", "_self", "_top", "_parent" have special meaning. An empty or
- * <code>null</code> window name is also a special case.
- * </p>
- * <p>
- * "", null and "_self" as {@code windowName} all causes the resource to be
- * opened in the current window, replacing any old contents. For
- * downloadable content you should avoid "_self" as "_self" causes the
- * client to skip rendering of any other changes as it considers them
- * irrelevant (the page will be replaced by the resource). This can speed up
- * the opening of a resource, but it might also put the client side into an
- * inconsistent state if the window content is not completely replaced e.g.,
- * if the resource is downloaded instead of displayed in the browser.
- * </p>
- * <p>
- * "_blank" as {@code windowName} causes the resource to always be opened in
- * a new window or tab (depends on the browser and browser settings).
- * </p>
- * <p>
- * "_top" and "_parent" as {@code windowName} works as specified by the HTML
- * standard.
- * </p>
- * <p>
- * Any other {@code windowName} will open the resource in a window with that
- * name, either by opening a new window/tab in the browser or by replacing
- * the contents of an existing window with that name.
- * </p>
- *
- * @param resource
- * the resource.
- * @param windowName
- * the name of the window.
- */
- public void open(Resource resource, String windowName) {
- openList.add(new OpenResource(resource, windowName, -1, -1,
- BORDER_DEFAULT));
- root.requestRepaint();
- }
-
- /**
- * Opens the given resource in a window with the given size, border and
- * name. For more information on the meaning of {@code windowName}, see
- * {@link #open(Resource, String)}.
- *
- * @param resource
- * the resource.
- * @param windowName
- * the name of the window.
- * @param width
- * the width of the window in pixels
- * @param height
- * the height of the window in pixels
- * @param border
- * the border style of the window. See {@link #BORDER_NONE
- * Window.BORDER_* constants}
- */
- public void open(Resource resource, String windowName, int width,
- int height, int border) {
- openList.add(new OpenResource(resource, windowName, width, height,
- border));
- root.requestRepaint();
- }
-
- /**
- * Internal helper method to actually add a notification.
- *
- * @param notification
- * the notification to add
- */
- private void addNotification(Notification notification) {
- if (notifications == null) {
- notifications = new LinkedList<Notification>();
- }
- notifications.add(notification);
- root.requestRepaint();
- }
-
- /**
- * Shows a notification message.
- *
- * @see Notification
- *
- * @param notification
- * The notification message to show
- *
- * @deprecated Use Notification.show(Page) instead.
- */
- @Deprecated
- public void showNotification(Notification notification) {
- addNotification(notification);
- }
-
- /**
- * Gets the Page to which the current root belongs. This is automatically
- * defined when processing requests to the server. In other cases, (e.g.
- * from background threads), the current root is not automatically defined.
- *
- * @see Root#getCurrent()
- *
- * @return the current page instance if available, otherwise
- * <code>null</code>
- */
- public static Page getCurrent() {
- Root currentRoot = Root.getCurrent();
- if (currentRoot == null) {
- return null;
- }
- return currentRoot.getPage();
- }
-
- /**
- * Sets the page title. The page title is displayed by the browser e.g. as
- * the title of the browser window or as the title of the tab.
- *
- * @param title
- * the new page title to set
- */
- public void setTitle(String title) {
- root.getRpcProxy(PageClientRpc.class).setTitle(title);
- }
-
-}
diff --git a/src/com/vaadin/terminal/PaintException.java b/src/com/vaadin/terminal/PaintException.java
deleted file mode 100644
index 68f689b7f1..0000000000
--- a/src/com/vaadin/terminal/PaintException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-/**
- * <code>PaintExcepection</code> is thrown if painting of a component fails.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class PaintException extends IOException implements Serializable {
-
- /**
- * Constructs an instance of <code>PaintExeception</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message.
- */
- public PaintException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs an instance of <code>PaintExeception</code> with the specified
- * detail message and cause.
- *
- * @param msg
- * the detail message.
- * @param cause
- * the cause
- */
- public PaintException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
- /**
- * Constructs an instance of <code>PaintExeception</code> from IOException.
- *
- * @param exception
- * the original exception.
- */
- public PaintException(IOException exception) {
- super(exception.getMessage());
- }
-}
diff --git a/src/com/vaadin/terminal/PaintTarget.java b/src/com/vaadin/terminal/PaintTarget.java
deleted file mode 100644
index b658c9f4a3..0000000000
--- a/src/com/vaadin/terminal/PaintTarget.java
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import com.vaadin.terminal.StreamVariable.StreamingStartEvent;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-import com.vaadin.ui.Component;
-
-/**
- * This interface defines the methods for painting XML to the UIDL stream.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface PaintTarget extends Serializable {
-
- /**
- * Prints single XMLsection.
- *
- * Prints full XML section. The section data is escaped from XML tags and
- * surrounded by XML start and end-tags.
- *
- * @param sectionTagName
- * the name of the tag.
- * @param sectionData
- * the scetion data.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addSection(String sectionTagName, String sectionData)
- throws PaintException;
-
- /**
- * Result of starting to paint a Paintable (
- * {@link PaintTarget#startPaintable(Component, String)}).
- *
- * @since 7.0
- */
- public enum PaintStatus {
- /**
- * Painting started, addVariable() and addAttribute() etc. methods may
- * be called.
- */
- PAINTING,
- /**
- * A previously unpainted or painted {@link Paintable} has been queued
- * be created/update later in a separate change in the same set of
- * changes.
- */
- CACHED
- }
-
- /**
- * Prints element start tag of a paintable section. Starts a paintable
- * section using the given tag. The PaintTarget may implement a caching
- * scheme, that checks the paintable has actually changed or can a cached
- * version be used instead. This method should call the startTag method.
- * <p>
- * If the Paintable is found in cache and this function returns true it may
- * omit the content and close the tag, in which case cached content should
- * be used.
- * </p>
- * <p>
- * This method may also add only a reference to the paintable and queue the
- * paintable to be painted separately.
- * </p>
- * <p>
- * Each paintable being painted should be closed by a matching
- * {@link #endPaintable(Component)} regardless of the {@link PaintStatus}
- * returned.
- * </p>
- *
- * @param paintable
- * the paintable to start.
- * @param tag
- * the name of the start tag.
- * @return {@link PaintStatus} - ready to paint or already cached on the
- * client (also used for sub paintables that are painted later
- * separately)
- * @throws PaintException
- * if the paint operation failed.
- * @see #startTag(String)
- * @since 7.0 (previously using startTag(Paintable, String))
- */
- public PaintStatus startPaintable(Component paintable, String tag)
- throws PaintException;
-
- /**
- * Prints paintable element end tag.
- *
- * Calls to {@link #startPaintable(Component, String)}should be matched by
- * {@link #endPaintable(Component)}. If the parent tag is closed before
- * every child tag is closed a PaintException is raised.
- *
- * @param paintable
- * the paintable to close.
- * @throws PaintException
- * if the paint operation failed.
- * @since 7.0 (previously using engTag(String))
- */
- public void endPaintable(Component paintable) throws PaintException;
-
- /**
- * Prints element start tag.
- *
- * <pre>
- * Todo:
- * Checking of input values
- * </pre>
- *
- * @param tagName
- * the name of the start tag.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void startTag(String tagName) throws PaintException;
-
- /**
- * Prints element end tag.
- *
- * If the parent tag is closed before every child tag is closed an
- * PaintException is raised.
- *
- * @param tagName
- * the name of the end tag.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void endTag(String tagName) throws PaintException;
-
- /**
- * Adds a boolean attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Attribute name.
- * @param value
- * the Attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, boolean value) throws PaintException;
-
- /**
- * Adds a integer attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Attribute name.
- * @param value
- * the Attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, int value) throws PaintException;
-
- /**
- * Adds a resource attribute to component. Atributes must be added before
- * any content is written.
- *
- * @param name
- * the Attribute name
- * @param value
- * the Attribute value
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, Resource value) throws PaintException;
-
- /**
- * Adds details about {@link StreamVariable} to the UIDL stream. Eg. in web
- * terminals Receivers are typically rendered for the client side as URLs,
- * where the client side implementation can do an http post request.
- * <p>
- * The urls in UIDL message may use Vaadin specific protocol. Before
- * actually using the urls on the client side, they should be passed via
- * {@link ApplicationConnection#translateVaadinUri(String)}.
- * <p>
- * Note that in current terminal implementation StreamVariables are cleaned
- * from the terminal only when:
- * <ul>
- * <li>a StreamVariable with same name replaces an old one
- * <li>the variable owner is no more attached
- * <li>the developer signals this by calling
- * {@link StreamingStartEvent#disposeStreamVariable()}
- * </ul>
- * Most commonly a component developer can just ignore this issue, but with
- * strict memory requirements and lots of StreamVariables implementations
- * that reserve a lot of memory this may be a critical issue.
- *
- * @param owner
- * the ReceiverOwner that can track the progress of streaming to
- * the given StreamVariable
- * @param name
- * an identifying name for the StreamVariable
- * @param value
- * the StreamVariable to paint
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name,
- StreamVariable value) throws PaintException;
-
- /**
- * Adds a long attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Attribute name.
- * @param value
- * the Attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, long value) throws PaintException;
-
- /**
- * Adds a float attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Attribute name.
- * @param value
- * the Attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, float value) throws PaintException;
-
- /**
- * Adds a double attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Attribute name.
- * @param value
- * the Attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, double value) throws PaintException;
-
- /**
- * Adds a string attribute to component. Atributes must be added before any
- * content is written.
- *
- * @param name
- * the Boolean attribute name.
- * @param value
- * the Boolean attribute value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addAttribute(String name, String value) throws PaintException;
-
- /**
- * TODO
- *
- * @param name
- * @param value
- * @throws PaintException
- */
- public void addAttribute(String name, Map<?, ?> value)
- throws PaintException;
-
- /**
- * Adds a Paintable type attribute. On client side the value will be a
- * terminal specific reference to corresponding component on client side
- * implementation.
- *
- * @param name
- * the name of the attribute
- * @param value
- * the Paintable to be referenced on client side
- * @throws PaintException
- */
- public void addAttribute(String name, Component value)
- throws PaintException;
-
- /**
- * Adds a string type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, String value)
- throws PaintException;
-
- /**
- * Adds a int type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, int value)
- throws PaintException;
-
- /**
- * Adds a long type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, long value)
- throws PaintException;
-
- /**
- * Adds a float type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, float value)
- throws PaintException;
-
- /**
- * Adds a double type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, double value)
- throws PaintException;
-
- /**
- * Adds a boolean type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, boolean value)
- throws PaintException;
-
- /**
- * Adds a string array type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- * @param value
- * the Variable initial value.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addVariable(VariableOwner owner, String name, String[] value)
- throws PaintException;
-
- /**
- * Adds a Paintable type variable. On client side the variable value will be
- * a terminal specific reference to corresponding component on client side
- * implementation. When updated from client side, terminal will map the
- * client side component reference back to a corresponding server side
- * reference.
- *
- * @param owner
- * the Listener for variable changes
- * @param name
- * the name of the variable
- * @param value
- * the initial value of the variable
- *
- * @throws PaintException
- * if the paint oparation fails
- */
- public void addVariable(VariableOwner owner, String name, Component value)
- throws PaintException;
-
- /**
- * Adds a upload stream type variable.
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addUploadStreamVariable(VariableOwner owner, String name)
- throws PaintException;
-
- /**
- * Prints single XML section.
- * <p>
- * Prints full XML section. The section data must be XML and it is
- * surrounded by XML start and end-tags.
- * </p>
- *
- * @param sectionTagName
- * the tag name.
- * @param sectionData
- * the section data to be printed.
- * @param namespace
- * the namespace.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addXMLSection(String sectionTagName, String sectionData,
- String namespace) throws PaintException;
-
- /**
- * Adds UIDL directly. The UIDL must be valid in accordance with the
- * UIDL.dtd
- *
- * @param uidl
- * the UIDL to be added.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void addUIDL(java.lang.String uidl) throws PaintException;
-
- /**
- * Adds text node. All the contents of the text are XML-escaped.
- *
- * @param text
- * the Text to add
- * @throws PaintException
- * if the paint operation failed.
- */
- void addText(String text) throws PaintException;
-
- /**
- * Adds CDATA node to target UIDL-tree.
- *
- * @param text
- * the Character data to add
- * @throws PaintException
- * if the paint operation failed.
- * @since 3.1
- */
- void addCharacterData(String text) throws PaintException;
-
- public void addAttribute(String string, Object[] keys);
-
- /**
- * @return the "tag" string used in communication to present given
- * {@link ClientConnector} type. Terminal may define how to present
- * the connector.
- */
- public String getTag(ClientConnector paintable);
-
- /**
- * @return true if a full repaint has been requested. E.g. refresh in a
- * browser window or such.
- */
- public boolean isFullRepaint();
-
-}
diff --git a/src/com/vaadin/terminal/RequestHandler.java b/src/com/vaadin/terminal/RequestHandler.java
deleted file mode 100644
index f37201715d..0000000000
--- a/src/com/vaadin/terminal/RequestHandler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-import com.vaadin.Application;
-
-/**
- * Handler for producing a response to non-UIDL requests. Handlers can be added
- * to applications using {@link Application#addRequestHandler(RequestHandler)}
- */
-public interface RequestHandler extends Serializable {
-
- /**
- * Handles a non-UIDL request. If a response is written, this method should
- * return <code>false</code> to indicate that no more request handlers
- * should be invoked for the request.
- *
- * @param application
- * The application to which the request belongs
- * @param request
- * The request to handle
- * @param response
- * The response object to which a response can be written.
- * @return true if a response has been written and no further request
- * handlers should be called, otherwise false
- * @throws IOException
- */
- boolean handleRequest(Application application, WrappedRequest request,
- WrappedResponse response) throws IOException;
-
-}
diff --git a/src/com/vaadin/terminal/Resource.java b/src/com/vaadin/terminal/Resource.java
deleted file mode 100644
index 58dc4fea9d..0000000000
--- a/src/com/vaadin/terminal/Resource.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-/**
- * <code>Resource</code> provided to the client terminal. Support for actually
- * displaying the resource type is left to the terminal.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Resource extends Serializable {
-
- /**
- * Gets the MIME type of the resource.
- *
- * @return the MIME type of the resource.
- */
- public String getMIMEType();
-}
diff --git a/src/com/vaadin/terminal/Scrollable.java b/src/com/vaadin/terminal/Scrollable.java
deleted file mode 100644
index 472954c556..0000000000
--- a/src/com/vaadin/terminal/Scrollable.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-/**
- * <p>
- * This interface is implemented by all visual objects that can be scrolled
- * programmatically from the server-side. The unit of scrolling is pixel.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Scrollable extends Serializable {
-
- /**
- * Gets scroll left offset.
- *
- * <p>
- * Scrolling offset is the number of pixels this scrollable has been
- * scrolled right.
- * </p>
- *
- * @return Horizontal scrolling position in pixels.
- */
- public int getScrollLeft();
-
- /**
- * Sets scroll left offset.
- *
- * <p>
- * Scrolling offset is the number of pixels this scrollable has been
- * scrolled right.
- * </p>
- *
- * @param scrollLeft
- * the xOffset.
- */
- public void setScrollLeft(int scrollLeft);
-
- /**
- * Gets scroll top offset.
- *
- * <p>
- * Scrolling offset is the number of pixels this scrollable has been
- * scrolled down.
- * </p>
- *
- * @return Vertical scrolling position in pixels.
- */
- public int getScrollTop();
-
- /**
- * Sets scroll top offset.
- *
- * <p>
- * Scrolling offset is the number of pixels this scrollable has been
- * scrolled down.
- * </p>
- *
- * <p>
- * The scrolling position is limited by the current height of the content
- * area. If the position is below the height, it is scrolled to the bottom.
- * However, if the same response also adds height to the content area,
- * scrolling to bottom only scrolls to the bottom of the previous content
- * area.
- * </p>
- *
- * @param scrollTop
- * the yOffset.
- */
- public void setScrollTop(int scrollTop);
-
-}
diff --git a/src/com/vaadin/terminal/Sizeable.java b/src/com/vaadin/terminal/Sizeable.java
deleted file mode 100644
index e3c98e0fa9..0000000000
--- a/src/com/vaadin/terminal/Sizeable.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-/**
- * Interface to be implemented by components wishing to display some object that
- * may be dynamically resized during runtime.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Sizeable extends Serializable {
-
- /**
- * @deprecated from 7.0, use {@link Unit#PIXELS} instead    
- */
- @Deprecated
- public static final Unit UNITS_PIXELS = Unit.PIXELS;
-
- /**
- * @deprecated from 7.0, use {@link Unit#POINTS} instead    
- */
- @Deprecated
- public static final Unit UNITS_POINTS = Unit.POINTS;
-
- /**
- * @deprecated from 7.0, use {@link Unit#PICAS} instead    
- */
- @Deprecated
- public static final Unit UNITS_PICAS = Unit.PICAS;
-
- /**
- * @deprecated from 7.0, use {@link Unit#EM} instead    
- */
- @Deprecated
- public static final Unit UNITS_EM = Unit.EM;
-
- /**
- * @deprecated from 7.0, use {@link Unit#EX} instead    
- */
- @Deprecated
- public static final Unit UNITS_EX = Unit.EX;
-
- /**
- * @deprecated from 7.0, use {@link Unit#MM} instead    
- */
- @Deprecated
- public static final Unit UNITS_MM = Unit.MM;
-
- /**
- * @deprecated from 7.0, use {@link Unit#CM} instead    
- */
- @Deprecated
- public static final Unit UNITS_CM = Unit.CM;
-
- /**
- * @deprecated from 7.0, use {@link Unit#INCH} instead    
- */
- @Deprecated
- public static final Unit UNITS_INCH = Unit.INCH;
-
- /**
- * @deprecated from 7.0, use {@link Unit#PERCENTAGE} instead    
- */
- @Deprecated
- public static final Unit UNITS_PERCENTAGE = Unit.PERCENTAGE;
-
- public static final float SIZE_UNDEFINED = -1;
-
- public enum Unit {
- /**
- * Unit code representing pixels.
- */
- PIXELS("px"),
- /**
- * Unit code representing points (1/72nd of an inch).
- */
- POINTS("pt"),
- /**
- * Unit code representing picas (12 points).
- */
- PICAS("pc"),
- /**
- * Unit code representing the font-size of the relevant font.
- */
- EM("em"),
- /**
- * Unit code representing the x-height of the relevant font.
- */
- EX("ex"),
- /**
- * Unit code representing millimeters.
- */
- MM("mm"),
- /**
- * Unit code representing centimeters.
- */
- CM("cm"),
- /**
- * Unit code representing inches.
- */
- INCH("in"),
- /**
- * Unit code representing in percentage of the containing element
- * defined by terminal.
- */
- PERCENTAGE("%");
-
- private String symbol;
-
- private Unit(String symbol) {
- this.symbol = symbol;
- }
-
- public String getSymbol() {
- return symbol;
- }
-
- @Override
- public String toString() {
- return symbol;
- }
-
- public static Unit getUnitFromSymbol(String symbol) {
- if (symbol == null) {
- return Unit.PIXELS; // Defaults to pixels
- }
- for (Unit unit : Unit.values()) {
- if (symbol.equals(unit.getSymbol())) {
- return unit;
- }
- }
- return Unit.PIXELS; // Defaults to pixels
- }
- }
-
- /**
- * Gets the width of the object. Negative number implies unspecified size
- * (terminal is free to set the size).
- *
- * @return width of the object in units specified by widthUnits property.
- */
- public float getWidth();
-
- /**
- * Gets the height of the object. Negative number implies unspecified size
- * (terminal is free to set the size).
- *
- * @return height of the object in units specified by heightUnits property.
- */
- public float getHeight();
-
- /**
- * Gets the width property units.
- *
- * @return units used in width property.
- */
- public Unit getWidthUnits();
-
- /**
- * Gets the height property units.
- *
- * @return units used in height property.
- */
- public Unit getHeightUnits();
-
- /**
- * Sets the height of the component using String presentation.
- *
- * String presentation is similar to what is used in Cascading Style Sheets.
- * Size can be length or percentage of available size.
- *
- * The empty string ("") or null will unset the height and set the units to
- * pixels.
- *
- * See <a
- * href="http://www.w3.org/TR/REC-CSS2/syndata.html#value-def-length">CSS
- * specification</a> for more details.
- *
- * @param height
- * in CSS style string representation
- */
- public void setHeight(String height);
-
- /**
- * Sets the width of the object. Negative number implies unspecified size
- * (terminal is free to set the size).
- *
- * @param width
- * the width of the object.
- * @param unit
- * the unit used for the width.
- */
- public void setWidth(float width, Unit unit);
-
- /**
- * Sets the height of the object. Negative number implies unspecified size
- * (terminal is free to set the size).
- *
- * @param height
- * the height of the object.
- * @param unit
- * the unit used for the width.
- */
- public void setHeight(float height, Unit unit);
-
- /**
- * Sets the width of the component using String presentation.
- *
- * String presentation is similar to what is used in Cascading Style Sheets.
- * Size can be length or percentage of available size.
- *
- * The empty string ("") or null will unset the width and set the units to
- * pixels.
- *
- * See <a
- * href="http://www.w3.org/TR/REC-CSS2/syndata.html#value-def-length">CSS
- * specification</a> for more details.
- *
- * @param width
- * in CSS style string representation, null or empty string to
- * reset
- */
- public void setWidth(String width);
-
- /**
- * Sets the size to 100% x 100%.
- */
- public void setSizeFull();
-
- /**
- * Clears any size settings.
- */
- public void setSizeUndefined();
-
-}
diff --git a/src/com/vaadin/terminal/StreamResource.java b/src/com/vaadin/terminal/StreamResource.java
deleted file mode 100644
index 1afd91dc08..0000000000
--- a/src/com/vaadin/terminal/StreamResource.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.InputStream;
-import java.io.Serializable;
-
-import com.vaadin.Application;
-import com.vaadin.service.FileTypeResolver;
-
-/**
- * <code>StreamResource</code> is a resource provided to the client directly by
- * the application. The strean resource is fetched from URI that is most often
- * in the context of the application or window. The resource is automatically
- * registered to window in creation.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class StreamResource implements ApplicationResource {
-
- /**
- * Source stream the downloaded content is fetched from.
- */
- private StreamSource streamSource = null;
-
- /**
- * Explicit mime-type.
- */
- private String MIMEType = null;
-
- /**
- * Filename.
- */
- private String filename;
-
- /**
- * Application.
- */
- private final Application application;
-
- /**
- * Default buffer size for this stream resource.
- */
- private int bufferSize = 0;
-
- /**
- * Default cache time for this stream resource.
- */
- private long cacheTime = DEFAULT_CACHETIME;
-
- /**
- * Creates a new stream resource for downloading from stream.
- *
- * @param streamSource
- * the source Stream.
- * @param filename
- * the name of the file.
- * @param application
- * the Application object.
- */
- public StreamResource(StreamSource streamSource, String filename,
- Application application) {
-
- this.application = application;
- setFilename(filename);
- setStreamSource(streamSource);
-
- // Register to application
- application.addResource(this);
-
- }
-
- /**
- * @see com.vaadin.terminal.Resource#getMIMEType()
- */
- @Override
- public String getMIMEType() {
- if (MIMEType != null) {
- return MIMEType;
- }
- return FileTypeResolver.getMIMEType(filename);
- }
-
- /**
- * Sets the mime type of the resource.
- *
- * @param MIMEType
- * the MIME type to be set.
- */
- public void setMIMEType(String MIMEType) {
- this.MIMEType = MIMEType;
- }
-
- /**
- * Returns the source for this <code>StreamResource</code>. StreamSource is
- * queried when the resource is about to be streamed to the client.
- *
- * @return Source of the StreamResource.
- */
- public StreamSource getStreamSource() {
- return streamSource;
- }
-
- /**
- * Sets the source for this <code>StreamResource</code>.
- * <code>StreamSource</code> is queried when the resource is about to be
- * streamed to the client.
- *
- * @param streamSource
- * the source to set.
- */
- public void setStreamSource(StreamSource streamSource) {
- this.streamSource = streamSource;
- }
-
- /**
- * Gets the filename.
- *
- * @return the filename.
- */
- @Override
- public String getFilename() {
- return filename;
- }
-
- /**
- * Sets the filename.
- *
- * @param filename
- * the filename to set.
- */
- public void setFilename(String filename) {
- this.filename = filename;
- }
-
- /**
- * @see com.vaadin.terminal.ApplicationResource#getApplication()
- */
- @Override
- public Application getApplication() {
- return application;
- }
-
- /**
- * @see com.vaadin.terminal.ApplicationResource#getStream()
- */
- @Override
- public DownloadStream getStream() {
- final StreamSource ss = getStreamSource();
- if (ss == null) {
- return null;
- }
- final DownloadStream ds = new DownloadStream(ss.getStream(),
- getMIMEType(), getFilename());
- ds.setBufferSize(getBufferSize());
- ds.setCacheTime(cacheTime);
- return ds;
- }
-
- /**
- * Interface implemented by the source of a StreamResource.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface StreamSource extends Serializable {
-
- /**
- * Returns new input stream that is used for reading the resource.
- */
- public InputStream getStream();
- }
-
- /* documented in superclass */
- @Override
- public int getBufferSize() {
- return bufferSize;
- }
-
- /**
- * Sets the size of the download buffer used for this resource.
- *
- * @param bufferSize
- * the size of the buffer in bytes.
- */
- public void setBufferSize(int bufferSize) {
- this.bufferSize = bufferSize;
- }
-
- /* documented in superclass */
- @Override
- public long getCacheTime() {
- return cacheTime;
- }
-
- /**
- * Sets the length of cache expiration time.
- *
- * <p>
- * This gives the adapter the possibility cache streams sent to the client.
- * The caching may be made in adapter or at the client if the client
- * supports caching. Zero or negavive value disbales the caching of this
- * stream.
- * </p>
- *
- * @param cacheTime
- * the cache time in milliseconds.
- *
- */
- public void setCacheTime(long cacheTime) {
- this.cacheTime = cacheTime;
- }
-
-}
diff --git a/src/com/vaadin/terminal/StreamVariable.java b/src/com/vaadin/terminal/StreamVariable.java
deleted file mode 100644
index 63763a5751..0000000000
--- a/src/com/vaadin/terminal/StreamVariable.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal;
-
-import java.io.OutputStream;
-import java.io.Serializable;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.StreamVariable.StreamingEndEvent;
-import com.vaadin.terminal.StreamVariable.StreamingErrorEvent;
-import com.vaadin.terminal.StreamVariable.StreamingStartEvent;
-
-/**
- * StreamVariable is a special kind of variable whose value is streamed to an
- * {@link OutputStream} provided by the {@link #getOutputStream()} method. E.g.
- * in web terminals {@link StreamVariable} can be used to send large files from
- * browsers to the server without consuming large amounts of memory.
- * <p>
- * Note, writing to the {@link OutputStream} is not synchronized by the terminal
- * (to avoid stalls in other operations when eg. streaming to a slow network
- * service or file system). If UI is changed as a side effect of writing to the
- * output stream, developer must handle synchronization manually.
- * <p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.5
- * @see PaintTarget#addVariable(VariableOwner, String, StreamVariable)
- */
-public interface StreamVariable extends Serializable {
-
- /**
- * Invoked by the terminal when a new upload arrives, after
- * {@link #streamingStarted(StreamingStartEvent)} method has been called.
- * The terminal implementation will write the streamed variable to the
- * returned output stream.
- *
- * @return Stream to which the uploaded file should be written.
- */
- public OutputStream getOutputStream();
-
- /**
- * Whether the {@link #onProgress(long, long)} method should be called
- * during the upload.
- * <p>
- * {@link #onProgress(long, long)} is called in a synchronized block when
- * the content is being received. This is potentially bit slow, so we are
- * calling that method only if requested. The value is requested after the
- * {@link #uploadStarted(StreamingStartEvent)} event, but not after reading
- * each buffer.
- *
- * @return true if this {@link StreamVariable} wants to by notified during
- * the upload of the progress of streaming.
- * @see #onProgress(StreamingProgressEvent)
- */
- public boolean listenProgress();
-
- /**
- * This method is called by the terminal if {@link #listenProgress()}
- * returns true when the streaming starts.
- */
- public void onProgress(StreamingProgressEvent event);
-
- public void streamingStarted(StreamingStartEvent event);
-
- public void streamingFinished(StreamingEndEvent event);
-
- public void streamingFailed(StreamingErrorEvent event);
-
- /*
- * Not synchronized to avoid stalls (caused by UIDL requests) while
- * streaming the content. Implementations also most commonly atomic even
- * without the restriction.
- */
- /**
- * If this method returns true while the content is being streamed the
- * Terminal to stop receiving current upload.
- * <p>
- * Note, the usage of this method is not synchronized over the Application
- * instance by the terminal like other methods. The implementation should
- * only return a boolean field and especially not modify UI or implement a
- * synchronization by itself.
- *
- * @return true if the streaming should be interrupted as soon as possible.
- */
- public boolean isInterrupted();
-
- public interface StreamingEvent extends Serializable {
-
- /**
- * @return the file name of the streamed file if known
- */
- public String getFileName();
-
- /**
- * @return the mime type of the streamed file if known
- */
- public String getMimeType();
-
- /**
- * @return the length of the stream (in bytes) if known, else -1
- */
- public long getContentLength();
-
- /**
- * @return then number of bytes streamed to StreamVariable
- */
- public long getBytesReceived();
- }
-
- /**
- * Event passed to {@link #uploadStarted(StreamingStartEvent)} method before
- * the streaming of the content to {@link StreamVariable} starts.
- */
- public interface StreamingStartEvent extends StreamingEvent {
- /**
- * The owner of the StreamVariable can call this method to inform the
- * terminal implementation that this StreamVariable will not be used to
- * accept more post.
- */
- public void disposeStreamVariable();
- }
-
- /**
- * Event passed to {@link #onProgress(StreamingProgressEvent)} method during
- * the streaming progresses.
- */
- public interface StreamingProgressEvent extends StreamingEvent {
- }
-
- /**
- * Event passed to {@link #uploadFinished(StreamingEndEvent)} method the
- * contents have been streamed to StreamVariable successfully.
- */
- public interface StreamingEndEvent extends StreamingEvent {
- }
-
- /**
- * Event passed to {@link #uploadFailed(StreamingErrorEvent)} method when
- * the streaming ended before the end of the input. The streaming may fail
- * due an interruption by {@link } or due an other unknown exception in
- * communication. In the latter case the exception is also passed to
- * {@link Application#terminalError(com.vaadin.terminal.Terminal.ErrorEvent)}
- * .
- */
- public interface StreamingErrorEvent extends StreamingEvent {
-
- /**
- * @return the exception that caused the receiving not to finish cleanly
- */
- public Exception getException();
-
- }
-
-}
diff --git a/src/com/vaadin/terminal/SystemError.java b/src/com/vaadin/terminal/SystemError.java
deleted file mode 100644
index bae135ee6b..0000000000
--- a/src/com/vaadin/terminal/SystemError.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-
-/**
- * <code>SystemError</code> is an error message for a problem caused by error in
- * system, not the user application code. The system error can contain technical
- * information such as stack trace and exception.
- *
- * SystemError does not support HTML in error messages or stack traces. If HTML
- * messages are required, use {@link UserError} or a custom implementation of
- * {@link ErrorMessage}.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class SystemError extends AbstractErrorMessage {
-
- /**
- * Constructor for SystemError with error message specified.
- *
- * @param message
- * the Textual error description.
- */
- public SystemError(String message) {
- super(message);
- setErrorLevel(ErrorLevel.SYSTEMERROR);
- setMode(ContentMode.XHTML);
- setMessage(getHtmlMessage());
- }
-
- /**
- * Constructor for SystemError with causing exception and error message.
- *
- * @param message
- * the Textual error description.
- * @param cause
- * the throwable causing the system error.
- */
- public SystemError(String message, Throwable cause) {
- this(message);
- addCause(AbstractErrorMessage.getErrorMessageForException(cause));
- }
-
- /**
- * Constructor for SystemError with cause.
- *
- * @param cause
- * the throwable causing the system error.
- */
- public SystemError(Throwable cause) {
- this(null, cause);
- }
-
- /**
- * Returns the message of the error in HTML.
- *
- * Note that this API may change in future versions.
- */
- protected String getHtmlMessage() {
- // TODO wrapping div with namespace? See the old code:
- // target.addXMLSection("div", message,
- // "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
-
- StringBuilder sb = new StringBuilder();
- if (getMessage() != null) {
- sb.append("<h2>");
- sb.append(AbstractApplicationServlet
- .safeEscapeForHtml(getMessage()));
- sb.append("</h2>");
- }
- return sb.toString();
- }
-
-}
diff --git a/src/com/vaadin/terminal/Terminal.java b/src/com/vaadin/terminal/Terminal.java
deleted file mode 100644
index 9dc6ced6a7..0000000000
--- a/src/com/vaadin/terminal/Terminal.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-
-/**
- * An interface that provides information about the user's terminal.
- * Implementors typically provide additional information using methods not in
- * this interface. </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Terminal extends Serializable {
-
- /**
- * Gets the name of the default theme for this terminal.
- *
- * @return the name of the theme that is used by default by this terminal.
- */
- public String getDefaultTheme();
-
- /**
- * Gets the width of the terminal screen in pixels. This is the width of the
- * screen and not the width available for the application.
- * <p>
- * Note that the screen width is typically not available in the
- * {@link com.vaadin.Application#init()} method as this is called before the
- * browser has a chance to report the screen size to the server.
- * </p>
- *
- * @return the width of the terminal screen.
- */
- public int getScreenWidth();
-
- /**
- * Gets the height of the terminal screen in pixels. This is the height of
- * the screen and not the height available for the application.
- *
- * <p>
- * Note that the screen height is typically not available in the
- * {@link com.vaadin.Application#init()} method as this is called before the
- * browser has a chance to report the screen size to the server.
- * </p>
- *
- * @return the height of the terminal screen.
- */
- public int getScreenHeight();
-
- /**
- * An error event implementation for Terminal.
- */
- public interface ErrorEvent extends Serializable {
-
- /**
- * Gets the contained throwable, the cause of the error.
- */
- public Throwable getThrowable();
-
- }
-
- /**
- * Interface for listening to Terminal errors.
- */
- public interface ErrorListener extends Serializable {
-
- /**
- * Invoked when a terminal error occurs.
- *
- * @param event
- * the fired event.
- */
- public void terminalError(Terminal.ErrorEvent event);
- }
-}
diff --git a/src/com/vaadin/terminal/ThemeResource.java b/src/com/vaadin/terminal/ThemeResource.java
deleted file mode 100644
index 41674b2373..0000000000
--- a/src/com/vaadin/terminal/ThemeResource.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import com.vaadin.service.FileTypeResolver;
-
-/**
- * <code>ThemeResource</code> is a named theme dependant resource provided and
- * managed by a theme. The actual resource contents are dynamically resolved to
- * comply with the used theme by the terminal adapter. This is commonly used to
- * provide static images, flash, java-applets, etc for the terminals.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class ThemeResource implements Resource {
-
- /**
- * Id of the terminal managed resource.
- */
- private String resourceID = null;
-
- /**
- * Creates a resource.
- *
- * @param resourceId
- * the Id of the resource.
- */
- public ThemeResource(String resourceId) {
- if (resourceId == null) {
- throw new NullPointerException("Resource ID must not be null");
- }
- if (resourceId.length() == 0) {
- throw new IllegalArgumentException("Resource ID can not be empty");
- }
- if (resourceId.charAt(0) == '/') {
- throw new IllegalArgumentException(
- "Resource ID must be relative (can not begin with /)");
- }
-
- resourceID = resourceId;
- }
-
- /**
- * Tests if the given object equals this Resource.
- *
- * @param obj
- * the object to be tested for equality.
- * @return <code>true</code> if the given object equals this Icon,
- * <code>false</code> if not.
- * @see java.lang.Object#equals(Object)
- */
- @Override
- public boolean equals(Object obj) {
- return obj instanceof ThemeResource
- && resourceID.equals(((ThemeResource) obj).resourceID);
- }
-
- /**
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return resourceID.hashCode();
- }
-
- /**
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return resourceID.toString();
- }
-
- /**
- * Gets the resource id.
- *
- * @return the resource id.
- */
- public String getResourceId() {
- return resourceID;
- }
-
- /**
- * @see com.vaadin.terminal.Resource#getMIMEType()
- */
- @Override
- public String getMIMEType() {
- return FileTypeResolver.getMIMEType(getResourceId());
- }
-}
diff --git a/src/com/vaadin/terminal/UserError.java b/src/com/vaadin/terminal/UserError.java
deleted file mode 100644
index a7a4fd89e2..0000000000
--- a/src/com/vaadin/terminal/UserError.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-/**
- * <code>UserError</code> is a controlled error occurred in application. User
- * errors are occur in normal usage of the application and guide the user.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class UserError extends AbstractErrorMessage {
-
- /**
- * @deprecated from 7.0, use {@link ContentMode#TEXT} instead    
- */
- @Deprecated
- public static final ContentMode CONTENT_TEXT = ContentMode.TEXT;
-
- /**
- * @deprecated from 7.0, use {@link ContentMode#PREFORMATTED} instead    
- */
- @Deprecated
- public static final ContentMode CONTENT_PREFORMATTED = ContentMode.PREFORMATTED;
-
- /**
- * @deprecated from 7.0, use {@link ContentMode#XHTML} instead    
- */
- @Deprecated
- public static final ContentMode CONTENT_XHTML = ContentMode.XHTML;
-
- /**
- * Creates a textual error message of level ERROR.
- *
- * @param textErrorMessage
- * the text of the error message.
- */
- public UserError(String textErrorMessage) {
- super(textErrorMessage);
- }
-
- /**
- * Creates an error message with level and content mode.
- *
- * @param message
- * the error message.
- * @param contentMode
- * the content Mode.
- * @param errorLevel
- * the level of error.
- */
- public UserError(String message, ContentMode contentMode,
- ErrorLevel errorLevel) {
- super(message);
- if (contentMode == null) {
- contentMode = ContentMode.TEXT;
- }
- if (errorLevel == null) {
- errorLevel = ErrorLevel.ERROR;
- }
- setMode(contentMode);
- setErrorLevel(errorLevel);
- }
-
-}
diff --git a/src/com/vaadin/terminal/Vaadin6Component.java b/src/com/vaadin/terminal/Vaadin6Component.java
deleted file mode 100644
index 59cbf956ca..0000000000
--- a/src/com/vaadin/terminal/Vaadin6Component.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal;
-
-import java.util.EventListener;
-
-import com.vaadin.ui.Component;
-
-/**
- * Interface provided to ease porting of Vaadin 6 components to Vaadin 7. By
- * implementing this interface your Component will be able to use
- * {@link #paintContent(PaintTarget)} and
- * {@link #changeVariables(Object, java.util.Map)} just like in Vaadin 6.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- *
- */
-public interface Vaadin6Component extends VariableOwner, Component,
- EventListener {
-
- /**
- * <p>
- * Paints the Paintable into a UIDL stream. This method creates the UIDL
- * sequence describing it and outputs it to the given UIDL stream.
- * </p>
- *
- * <p>
- * It is called when the contents of the component should be painted in
- * response to the component first being shown or having been altered so
- * that its visual representation is changed.
- * </p>
- *
- * @param target
- * the target UIDL stream where the component should paint itself
- * to.
- * @throws PaintException
- * if the paint operation failed.
- */
- public void paintContent(PaintTarget target) throws PaintException;
-
-}
diff --git a/src/com/vaadin/terminal/VariableOwner.java b/src/com/vaadin/terminal/VariableOwner.java
deleted file mode 100644
index c52e04c008..0000000000
--- a/src/com/vaadin/terminal/VariableOwner.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.Serializable;
-import java.util.Map;
-
-/**
- * <p>
- * Listener interface for UI variable changes. The user communicates with the
- * application using the so-called <i>variables</i>. When the user makes a
- * change using the UI the terminal trasmits the changed variables to the
- * application, and the components owning those variables may then process those
- * changes.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- * @deprecated in 7.0. Only provided to ease porting of Vaadin 6 components. Do
- * not implement this directly, implement {@link Vaadin6Component}.
- */
-@Deprecated
-public interface VariableOwner extends Serializable {
-
- /**
- * Called when one or more variables handled by the implementing class are
- * changed.
- *
- * @param source
- * the Source of the variable change. This is the origin of the
- * event. For example in Web Adapter this is the request.
- * @param variables
- * the Mapping from variable names to new variable values.
- */
- public void changeVariables(Object source, Map<String, Object> variables);
-
- /**
- * <p>
- * Tests if the variable owner is enabled or not. The terminal should not
- * send any variable changes to disabled variable owners.
- * </p>
- *
- * @return <code>true</code> if the variable owner is enabled,
- * <code>false</code> if not
- */
- public boolean isEnabled();
-
- /**
- * <p>
- * Tests if the variable owner is in immediate mode or not. Being in
- * immediate mode means that all variable changes are required to be sent
- * back from the terminal immediately when they occur.
- * </p>
- *
- * <p>
- * <strong>Note:</strong> <code>VariableOwner</code> does not include a set-
- * method for the immediateness property. This is because not all
- * VariableOwners wish to offer the functionality. Such VariableOwners are
- * never in the immediate mode, thus they always return <code>false</code>
- * in {@link #isImmediate()}.
- * </p>
- *
- * @return <code>true</code> if the component is in immediate mode,
- * <code>false</code> if not.
- */
- public boolean isImmediate();
-
- /**
- * VariableOwner error event.
- */
- public interface ErrorEvent extends Terminal.ErrorEvent {
-
- /**
- * Gets the source VariableOwner.
- *
- * @return the variable owner.
- */
- public VariableOwner getVariableOwner();
-
- }
-}
diff --git a/src/com/vaadin/terminal/WrappedRequest.java b/src/com/vaadin/terminal/WrappedRequest.java
deleted file mode 100644
index a27213d921..0000000000
--- a/src/com/vaadin/terminal/WrappedRequest.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.portlet.PortletRequest;
-import javax.servlet.ServletRequest;
-import javax.servlet.http.HttpServletRequest;
-
-import com.vaadin.Application;
-import com.vaadin.RootRequiresMoreInformationException;
-import com.vaadin.annotations.EagerInit;
-import com.vaadin.terminal.gwt.server.WebBrowser;
-import com.vaadin.ui.Root;
-
-/**
- * A generic request to the server, wrapping a more specific request type, e.g.
- * HttpServletReqest or PortletRequest.
- *
- * @since 7.0
- */
-public interface WrappedRequest extends Serializable {
-
- /**
- * Detailed information extracted from the browser.
- *
- * @see WrappedRequest#getBrowserDetails()
- */
- public interface BrowserDetails extends Serializable {
- /**
- * Gets the URI hash fragment for the request. This is typically used to
- * encode navigation within an application.
- *
- * @return the URI hash fragment
- */
- public String getUriFragment();
-
- /**
- * Gets the value of window.name from the browser. This can be used to
- * keep track of the specific window between browser reloads.
- *
- * @return the string value of window.name in the browser
- */
- public String getWindowName();
-
- /**
- * Gets a reference to the {@link WebBrowser} object containing
- * additional information, e.g. screen size and the time zone offset.
- *
- * @return the web browser object
- */
- public WebBrowser getWebBrowser();
- }
-
- /**
- * Gets the named request parameter This is typically a HTTP GET or POST
- * parameter, though other request types might have other ways of
- * representing parameters.
- *
- * @see javax.servlet.ServletRequest#getParameter(String)
- * @see javax.portlet.PortletRequest#getParameter(String)
- *
- * @param parameter
- * the name of the parameter
- * @return The paramter value, or <code>null</code> if no parameter with the
- * given name is present
- */
- public String getParameter(String parameter);
-
- /**
- * Gets all the parameters of the request.
- *
- * @see #getParameter(String)
- *
- * @see javax.servlet.ServletRequest#getParameterMap()
- * @see javax.portlet.PortletRequest#getParameter(String)
- *
- * @return A mapping of parameter names to arrays of parameter values
- */
- public Map<String, String[]> getParameterMap();
-
- /**
- * Returns the length of the request content that can be read from the input
- * stream returned by {@link #getInputStream()}.
- *
- * @see javax.servlet.ServletRequest#getContentLength()
- * @see javax.portlet.ClientDataRequest#getContentLength()
- *
- * @return content length in bytes
- */
- public int getContentLength();
-
- /**
- * Returns an input stream from which the request content can be read. The
- * request content length can be obtained with {@link #getContentLength()}
- * without reading the full stream contents.
- *
- * @see javax.servlet.ServletRequest#getInputStream()
- * @see javax.portlet.ClientDataRequest#getPortletInputStream()
- *
- * @return the input stream from which the contents of the request can be
- * read
- * @throws IOException
- * if the input stream can not be opened
- */
- public InputStream getInputStream() throws IOException;
-
- /**
- * Gets a request attribute.
- *
- * @param name
- * the name of the attribute
- * @return the value of the attribute, or <code>null</code> if there is no
- * attribute with the given name
- *
- * @see javax.servlet.ServletRequest#getAttribute(String)
- * @see javax.portlet.PortletRequest#getAttribute(String)
- */
- public Object getAttribute(String name);
-
- /**
- * Defines a request attribute.
- *
- * @param name
- * the name of the attribute
- * @param value
- * the attribute value
- *
- * @see javax.servlet.ServletRequest#setAttribute(String, Object)
- * @see javax.portlet.PortletRequest#setAttribute(String, Object)
- */
- public void setAttribute(String name, Object value);
-
- /**
- * Gets the path of the requested resource relative to the application. The
- * path be <code>null</code> if no path information is available. Does
- * always start with / if the path isn't <code>null</code>.
- *
- * @return a string with the path relative to the application.
- *
- * @see javax.servlet.http.HttpServletRequest#getPathInfo()
- */
- public String getRequestPathInfo();
-
- /**
- * Returns the maximum time interval, in seconds, that the session
- * associated with this request will be kept open between client accesses.
- *
- * @return an integer specifying the number of seconds the session
- * associated with this request remains open between client requests
- *
- * @see javax.servlet.http.HttpSession#getMaxInactiveInterval()
- * @see javax.portlet.PortletSession#getMaxInactiveInterval()
- */
- public int getSessionMaxInactiveInterval();
-
- /**
- * Gets an attribute from the session associated with this request.
- *
- * @param name
- * the name of the attribute
- * @return the attribute value, or <code>null</code> if the attribute is not
- * defined in the session
- *
- * @see javax.servlet.http.HttpSession#getAttribute(String)
- * @see javax.portlet.PortletSession#getAttribute(String)
- */
- public Object getSessionAttribute(String name);
-
- /**
- * Saves an attribute value in the session associated with this request.
- *
- * @param name
- * the name of the attribute
- * @param attribute
- * the attribute value
- *
- * @see javax.servlet.http.HttpSession#setAttribute(String, Object)
- * @see javax.portlet.PortletSession#setAttribute(String, Object)
- */
- public void setSessionAttribute(String name, Object attribute);
-
- /**
- * Returns the MIME type of the body of the request, or null if the type is
- * not known.
- *
- * @return a string containing the name of the MIME type of the request, or
- * null if the type is not known
- *
- * @see javax.servlet.ServletRequest#getContentType()
- * @see javax.portlet.ResourceRequest#getContentType()
- *
- */
- public String getContentType();
-
- /**
- * Gets detailed information about the browser from which the request
- * originated. This consists of information that is not available from
- * normal HTTP requests, but requires additional information to be extracted
- * for instance using javascript in the browser.
- *
- * This information is only guaranteed to be available in some special
- * cases, for instance when {@link Application#getRoot} is called again
- * after throwing {@link RootRequiresMoreInformationException} or in
- * {@link Root#init(WrappedRequest)} for a Root class not annotated with
- * {@link EagerInit}
- *
- * @return the browser details, or <code>null</code> if details are not
- * available
- *
- * @see BrowserDetails
- */
- public BrowserDetails getBrowserDetails();
-
- /**
- * Gets locale information from the query, e.g. using the Accept-Language
- * header.
- *
- * @return the preferred Locale
- *
- * @see ServletRequest#getLocale()
- * @see PortletRequest#getLocale()
- */
- public Locale getLocale();
-
- /**
- * Returns the IP address from which the request came. This might also be
- * the address of a proxy between the server and the original requester.
- *
- * @return a string containing the IP address, or <code>null</code> if the
- * address is not available
- *
- * @see ServletRequest#getRemoteAddr()
- */
- public String getRemoteAddr();
-
- /**
- * Checks whether the request was made using a secure channel, e.g. using
- * https.
- *
- * @return a boolean indicating if the request is secure
- *
- * @see ServletRequest#isSecure()
- * @see PortletRequest#isSecure()
- */
- public boolean isSecure();
-
- /**
- * Gets the value of a request header, e.g. a http header for a
- * {@link HttpServletRequest}.
- *
- * @param headerName
- * the name of the header
- * @return the header value, or <code>null</code> if the header is not
- * present in the request
- *
- * @see HttpServletRequest#getHeader(String)
- */
- public String getHeader(String headerName);
-
- /**
- * Gets the deployment configuration for the context of this request.
- *
- * @return the deployment configuration
- *
- * @see DeploymentConfiguration
- */
- public DeploymentConfiguration getDeploymentConfiguration();
-
-}
diff --git a/src/com/vaadin/terminal/WrappedResponse.java b/src/com/vaadin/terminal/WrappedResponse.java
deleted file mode 100644
index 995133a269..0000000000
--- a/src/com/vaadin/terminal/WrappedResponse.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-
-import javax.portlet.MimeResponse;
-import javax.portlet.PortletResponse;
-import javax.portlet.ResourceResponse;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * A generic response from the server, wrapping a more specific response type,
- * e.g. HttpServletResponse or PortletResponse.
- *
- * @since 7.0
- */
-public interface WrappedResponse extends Serializable {
-
- /**
- * Sets the (http) status code for the response. If you want to include an
- * error message along the status code, use {@link #sendError(int, String)}
- * instead.
- *
- * @param statusCode
- * the status code to set
- * @see HttpServletResponse#setStatus(int)
- *
- * @see ResourceResponse#HTTP_STATUS_CODE
- */
- public void setStatus(int statusCode);
-
- /**
- * Sets the content type of this response. If the content type including a
- * charset is set before {@link #getWriter()} is invoked, the returned
- * PrintWriter will automatically use the defined charset.
- *
- * @param contentType
- * a string specifying the MIME type of the content
- *
- * @see ServletResponse#setContentType(String)
- * @see MimeResponse#setContentType(String)
- */
- public void setContentType(String contentType);
-
- /**
- * Sets the value of a generic response header. If the header had already
- * been set, the new value overwrites the previous one.
- *
- * @param name
- * the name of the header
- * @param value
- * the header value.
- *
- * @see HttpServletResponse#setHeader(String, String)
- * @see PortletResponse#setProperty(String, String)
- */
- public void setHeader(String name, String value);
-
- /**
- * Properly formats a timestamp as a date header. If the header had already
- * been set, the new value overwrites the previous one.
- *
- * @param name
- * the name of the header
- * @param timestamp
- * the number of milliseconds since epoch
- *
- * @see HttpServletResponse#setDateHeader(String, long)
- */
- public void setDateHeader(String name, long timestamp);
-
- /**
- * Returns a <code>OutputStream</code> for writing binary data in the
- * response.
- * <p>
- * Either this method or getWriter() may be called to write the response,
- * not both.
- *
- * @return a <code>OutputStream</code> for writing binary data
- * @throws IOException
- * if an input or output exception occurred
- *
- * @see #getWriter()
- * @see ServletResponse#getOutputStream()
- * @see MimeResponse#getPortletOutputStream()
- */
- public OutputStream getOutputStream() throws IOException;
-
- /**
- * Returns a <code>PrintWriter</code> object that can send character text to
- * the client. The PrintWriter uses the character encoding defined using
- * setContentType.
- * <p>
- * Either this method or getOutputStream() may be called to write the
- * response, not both.
- *
- * @return a <code>PrintWriter</code> for writing character text
- * @throws IOException
- * if an input or output exception occurred
- *
- * @see #getOutputStream()
- * @see ServletResponse#getWriter()
- * @see MimeResponse#getWriter()
- */
- public PrintWriter getWriter() throws IOException;
-
- /**
- * Sets cache time in milliseconds, -1 means no cache at all. All required
- * headers related to caching in the response are set based on the time.
- *
- * @param milliseconds
- * Cache time in milliseconds
- */
- public void setCacheTime(long milliseconds);
-
- /**
- * Sends an error response to the client using the specified status code and
- * clears the buffer. In some configurations, this can cause a predefined
- * error page to be displayed.
- *
- * @param errorCode
- * the HTTP status code
- * @param message
- * a message to accompany the error
- * @throws IOException
- * if an input or output exception occurs
- *
- * @see HttpServletResponse#sendError(int, String)
- */
- public void sendError(int errorCode, String message) throws IOException;
-
- /**
- * Gets the deployment configuration for the context of this response.
- *
- * @return the deployment configuration
- *
- * @see DeploymentConfiguration
- */
- public DeploymentConfiguration getDeploymentConfiguration();
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
deleted file mode 100644
index 40958e2868..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.security.GeneralSecurityException;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.logging.Logger;
-
-import javax.portlet.ActionRequest;
-import javax.portlet.ActionResponse;
-import javax.portlet.EventRequest;
-import javax.portlet.EventResponse;
-import javax.portlet.GenericPortlet;
-import javax.portlet.PortletConfig;
-import javax.portlet.PortletContext;
-import javax.portlet.PortletException;
-import javax.portlet.PortletRequest;
-import javax.portlet.PortletResponse;
-import javax.portlet.PortletSession;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceRequest;
-import javax.portlet.ResourceResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-
-import com.liferay.portal.kernel.util.PortalClassInvoker;
-import com.liferay.portal.kernel.util.PropsUtil;
-import com.vaadin.Application;
-import com.vaadin.Application.ApplicationStartEvent;
-import com.vaadin.Application.SystemMessages;
-import com.vaadin.RootRequiresMoreInformationException;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.server.AbstractCommunicationManager.Callback;
-import com.vaadin.ui.Root;
-
-/**
- * Portlet 2.0 base class. This replaces the servlet in servlet/portlet 1.0
- * deployments and handles various portlet requests from the browser.
- *
- * TODO Document me!
- *
- * @author peholmst
- */
-public abstract class AbstractApplicationPortlet extends GenericPortlet
- implements Constants {
-
- public static final String RESOURCE_URL_ID = "APP";
-
- public static class WrappedHttpAndPortletRequest extends
- WrappedPortletRequest {
-
- public WrappedHttpAndPortletRequest(PortletRequest request,
- HttpServletRequest originalRequest,
- DeploymentConfiguration deploymentConfiguration) {
- super(request, deploymentConfiguration);
- this.originalRequest = originalRequest;
- }
-
- private final HttpServletRequest originalRequest;
-
- @Override
- public String getParameter(String name) {
- String parameter = super.getParameter(name);
- if (parameter == null) {
- parameter = originalRequest.getParameter(name);
- }
- return parameter;
- }
-
- @Override
- public String getRemoteAddr() {
- return originalRequest.getRemoteAddr();
- }
-
- @Override
- public String getHeader(String name) {
- String header = super.getHeader(name);
- if (header == null) {
- header = originalRequest.getHeader(name);
- }
- return header;
- }
-
- @Override
- public Map<String, String[]> getParameterMap() {
- Map<String, String[]> parameterMap = super.getParameterMap();
- if (parameterMap == null) {
- parameterMap = originalRequest.getParameterMap();
- }
- return parameterMap;
- }
- }
-
- public static class WrappedGateinRequest extends
- WrappedHttpAndPortletRequest {
- public WrappedGateinRequest(PortletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- super(request, getOriginalRequest(request), deploymentConfiguration);
- }
-
- private static final HttpServletRequest getOriginalRequest(
- PortletRequest request) {
- try {
- Method getRealReq = request.getClass().getMethod(
- "getRealRequest");
- HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq
- .invoke(request);
- return origRequest;
- } catch (Exception e) {
- throw new IllegalStateException("GateIn request not detected",
- e);
- }
- }
- }
-
- public static class WrappedLiferayRequest extends
- WrappedHttpAndPortletRequest {
-
- public WrappedLiferayRequest(PortletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- super(request, getOriginalRequest(request), deploymentConfiguration);
- }
-
- @Override
- public String getPortalProperty(String name) {
- return PropsUtil.get(name);
- }
-
- private static HttpServletRequest getOriginalRequest(
- PortletRequest request) {
- try {
- // httpRequest = PortalUtil.getHttpServletRequest(request);
- HttpServletRequest httpRequest = (HttpServletRequest) PortalClassInvoker
- .invoke("com.liferay.portal.util.PortalUtil",
- "getHttpServletRequest", request);
-
- // httpRequest =
- // PortalUtil.getOriginalServletRequest(httpRequest);
- httpRequest = (HttpServletRequest) PortalClassInvoker.invoke(
- "com.liferay.portal.util.PortalUtil",
- "getOriginalServletRequest", httpRequest);
- return httpRequest;
- } catch (Exception e) {
- throw new IllegalStateException("Liferay request not detected",
- e);
- }
- }
-
- }
-
- public static class AbstractApplicationPortletWrapper implements Callback {
-
- private final AbstractApplicationPortlet portlet;
-
- public AbstractApplicationPortletWrapper(
- AbstractApplicationPortlet portlet) {
- this.portlet = portlet;
- }
-
- @Override
- public void criticalNotification(WrappedRequest request,
- WrappedResponse response, String cap, String msg,
- String details, String outOfSyncURL) throws IOException {
- portlet.criticalNotification(WrappedPortletRequest.cast(request),
- (WrappedPortletResponse) response, cap, msg, details,
- outOfSyncURL);
- }
- }
-
- /**
- * This portlet parameter is used to add styles to the main element. E.g
- * "height:500px" generates a style="height:500px" to the main element.
- */
- public static final String PORTLET_PARAMETER_STYLE = "style";
-
- /**
- * This portal parameter is used to define the name of the Vaadin theme that
- * is used for all Vaadin applications in the portal.
- */
- public static final String PORTAL_PARAMETER_VAADIN_THEME = "vaadin.theme";
-
- public static final String WRITE_AJAX_PAGE_SCRIPT_WIDGETSET_SHOULD_WRITE = "writeAjaxPageScriptWidgetsetShouldWrite";
-
- // TODO some parts could be shared with AbstractApplicationServlet
-
- // TODO Can we close the application when the portlet is removed? Do we know
- // when the portlet is removed?
-
- private boolean productionMode = false;
-
- private DeploymentConfiguration deploymentConfiguration = new AbstractDeploymentConfiguration(
- getClass()) {
- @Override
- public String getConfiguredWidgetset(WrappedRequest request) {
-
- String widgetset = getApplicationOrSystemProperty(
- PARAMETER_WIDGETSET, null);
-
- if (widgetset == null) {
- // If no widgetset defined for the application, check the
- // portal
- // property
- widgetset = WrappedPortletRequest.cast(request)
- .getPortalProperty(PORTAL_PARAMETER_VAADIN_WIDGETSET);
- }
-
- if (widgetset == null) {
- // If no widgetset defined for the portal, use the default
- widgetset = DEFAULT_WIDGETSET;
- }
-
- return widgetset;
- }
-
- @Override
- public String getConfiguredTheme(WrappedRequest request) {
-
- // is the default theme defined by the portal?
- String themeName = WrappedPortletRequest.cast(request)
- .getPortalProperty(Constants.PORTAL_PARAMETER_VAADIN_THEME);
-
- if (themeName == null) {
- // no, using the default theme defined by Vaadin
- themeName = DEFAULT_THEME_NAME;
- }
-
- return themeName;
- }
-
- @Override
- public boolean isStandalone(WrappedRequest request) {
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.DeploymentConfiguration#getStaticFileLocation
- * (com.vaadin.terminal.WrappedRequest)
- *
- * Return the URL from where static files, e.g. the widgetset and the
- * theme, are served. In a standard configuration the VAADIN folder
- * inside the returned folder is what is used for widgetsets and themes.
- *
- * @return The location of static resources (inside which there should
- * be a VAADIN directory). Does not end with a slash (/).
- */
-
- @Override
- public String getStaticFileLocation(WrappedRequest request) {
- String staticFileLocation = WrappedPortletRequest.cast(request)
- .getPortalProperty(
- Constants.PORTAL_PARAMETER_VAADIN_RESOURCE_PATH);
- if (staticFileLocation != null) {
- // remove trailing slash if any
- while (staticFileLocation.endsWith(".")) {
- staticFileLocation = staticFileLocation.substring(0,
- staticFileLocation.length() - 1);
- }
- return staticFileLocation;
- } else {
- // default for Liferay
- return "/html";
- }
- }
-
- @Override
- public String getMimeType(String resourceName) {
- return getPortletContext().getMimeType(resourceName);
- }
- };
-
- private final AddonContext addonContext = new AddonContext(
- getDeploymentConfiguration());
-
- @Override
- public void init(PortletConfig config) throws PortletException {
- super.init(config);
- Properties applicationProperties = getDeploymentConfiguration()
- .getInitParameters();
-
- // Read default parameters from the context
- final PortletContext context = config.getPortletContext();
- for (final Enumeration<String> e = context.getInitParameterNames(); e
- .hasMoreElements();) {
- final String name = e.nextElement();
- applicationProperties.setProperty(name,
- context.getInitParameter(name));
- }
-
- // Override with application settings from portlet.xml
- for (final Enumeration<String> e = config.getInitParameterNames(); e
- .hasMoreElements();) {
- final String name = e.nextElement();
- applicationProperties.setProperty(name,
- config.getInitParameter(name));
- }
-
- checkProductionMode();
- checkCrossSiteProtection();
-
- addonContext.init();
- }
-
- @Override
- public void destroy() {
- super.destroy();
-
- addonContext.destroy();
- }
-
- private void checkCrossSiteProtection() {
- if (getDeploymentConfiguration().getApplicationOrSystemProperty(
- SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION, "false").equals(
- "true")) {
- /*
- * Print an information/warning message about running with xsrf
- * protection disabled
- */
- getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED);
- }
- }
-
- private void checkProductionMode() {
- // TODO Identical code in AbstractApplicationServlet -> refactor
- // Check if the application is in production mode.
- // We are in production mode if productionMode=true
- if (getDeploymentConfiguration().getApplicationOrSystemProperty(
- SERVLET_PARAMETER_PRODUCTION_MODE, "false").equals("true")) {
- productionMode = true;
- }
-
- if (!productionMode) {
- /* Print an information/warning message about running in debug mode */
- // TODO Maybe we need a different message for portlets?
- getLogger().warning(NOT_PRODUCTION_MODE_INFO);
- }
- }
-
- protected enum RequestType {
- FILE_UPLOAD, UIDL, RENDER, STATIC_FILE, APPLICATION_RESOURCE, DUMMY, EVENT, ACTION, UNKNOWN, BROWSER_DETAILS, CONNECTOR_RESOURCE;
- }
-
- protected RequestType getRequestType(WrappedPortletRequest wrappedRequest) {
- PortletRequest request = wrappedRequest.getPortletRequest();
- if (request instanceof RenderRequest) {
- return RequestType.RENDER;
- } else if (request instanceof ResourceRequest) {
- ResourceRequest resourceRequest = (ResourceRequest) request;
- if (ServletPortletHelper.isUIDLRequest(wrappedRequest)) {
- return RequestType.UIDL;
- } else if (isBrowserDetailsRequest(resourceRequest)) {
- return RequestType.BROWSER_DETAILS;
- } else if (ServletPortletHelper.isFileUploadRequest(wrappedRequest)) {
- return RequestType.FILE_UPLOAD;
- } else if (ServletPortletHelper
- .isConnectorResourceRequest(wrappedRequest)) {
- return RequestType.CONNECTOR_RESOURCE;
- } else if (ServletPortletHelper
- .isApplicationResourceRequest(wrappedRequest)) {
- return RequestType.APPLICATION_RESOURCE;
- } else if (isDummyRequest(resourceRequest)) {
- return RequestType.DUMMY;
- } else {
- return RequestType.STATIC_FILE;
- }
- } else if (request instanceof ActionRequest) {
- return RequestType.ACTION;
- } else if (request instanceof EventRequest) {
- return RequestType.EVENT;
- }
- return RequestType.UNKNOWN;
- }
-
- private boolean isBrowserDetailsRequest(ResourceRequest request) {
- return request.getResourceID() != null
- && request.getResourceID().equals("browserDetails");
- }
-
- private boolean isDummyRequest(ResourceRequest request) {
- return request.getResourceID() != null
- && request.getResourceID().equals("DUMMY");
- }
-
- /**
- * Returns true if the servlet is running in production mode. Production
- * mode disables all debug facilities.
- *
- * @return true if in production mode, false if in debug mode
- */
- public boolean isProductionMode() {
- return productionMode;
- }
-
- protected void handleRequest(PortletRequest request,
- PortletResponse response) throws PortletException, IOException {
- RequestTimer requestTimer = new RequestTimer();
- requestTimer.start();
-
- AbstractApplicationPortletWrapper portletWrapper = new AbstractApplicationPortletWrapper(
- this);
-
- WrappedPortletRequest wrappedRequest = createWrappedRequest(request);
-
- WrappedPortletResponse wrappedResponse = new WrappedPortletResponse(
- response, getDeploymentConfiguration());
-
- RequestType requestType = getRequestType(wrappedRequest);
-
- if (requestType == RequestType.UNKNOWN) {
- handleUnknownRequest(request, response);
- } else if (requestType == RequestType.DUMMY) {
- /*
- * This dummy page is used by action responses to redirect to, in
- * order to prevent the boot strap code from being rendered into
- * strange places such as iframes.
- */
- ((ResourceResponse) response).setContentType("text/html");
- final OutputStream out = ((ResourceResponse) response)
- .getPortletOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- outWriter.print("<html><body>dummy page</body></html>");
- outWriter.close();
- } else if (requestType == RequestType.STATIC_FILE) {
- serveStaticResources((ResourceRequest) request,
- (ResourceResponse) response);
- } else {
- Application application = null;
- boolean transactionStarted = false;
- boolean requestStarted = false;
-
- try {
- // TODO What about PARAM_UNLOADBURST & redirectToApplication??
-
- /* Find out which application this request is related to */
- application = findApplicationInstance(wrappedRequest,
- requestType);
- if (application == null) {
- return;
- }
- Application.setCurrent(application);
-
- /*
- * Get or create an application context and an application
- * manager for the session
- */
- PortletApplicationContext2 applicationContext = getApplicationContext(request
- .getPortletSession());
- applicationContext.setResponse(response);
- applicationContext.setPortletConfig(getPortletConfig());
-
- PortletCommunicationManager applicationManager = applicationContext
- .getApplicationManager(application);
-
- if (requestType == RequestType.CONNECTOR_RESOURCE) {
- applicationManager.serveConnectorResource(wrappedRequest,
- wrappedResponse);
- return;
- }
-
- /* Update browser information from request */
- applicationContext.getBrowser().updateRequestDetails(
- wrappedRequest);
-
- /*
- * Call application requestStart before Application.init() is
- * called (bypasses the limitation in TransactionListener)
- */
- if (application instanceof PortletRequestListener) {
- ((PortletRequestListener) application).onRequestStart(
- request, response);
- requestStarted = true;
- }
-
- /* Start the newly created application */
- startApplication(request, application, applicationContext);
-
- /*
- * Transaction starts. Call transaction listeners. Transaction
- * end is called in the finally block below.
- */
- applicationContext.startTransaction(application, request);
- transactionStarted = true;
-
- /* Notify listeners */
-
- // Finds the window within the application
- Root root = null;
- synchronized (application) {
- if (application.isRunning()) {
- switch (requestType) {
- case RENDER:
- case ACTION:
- // Both action requests and render requests are ok
- // without a Root as they render the initial HTML
- // and then do a second request
- try {
- root = application
- .getRootForRequest(wrappedRequest);
- } catch (RootRequiresMoreInformationException e) {
- // Ignore problem and continue without root
- }
- break;
- case BROWSER_DETAILS:
- // Should not try to find a root here as the
- // combined request details might change the root
- break;
- case FILE_UPLOAD:
- // no window
- break;
- case APPLICATION_RESOURCE:
- // use main window - should not need any window
- // root = application.getRoot();
- break;
- default:
- root = application
- .getRootForRequest(wrappedRequest);
- }
- // if window not found, not a problem - use null
- }
- }
-
- // TODO Should this happen before or after the transaction
- // starts?
- if (request instanceof RenderRequest) {
- applicationContext.firePortletRenderRequest(application,
- root, (RenderRequest) request,
- (RenderResponse) response);
- } else if (request instanceof ActionRequest) {
- applicationContext.firePortletActionRequest(application,
- root, (ActionRequest) request,
- (ActionResponse) response);
- } else if (request instanceof EventRequest) {
- applicationContext.firePortletEventRequest(application,
- root, (EventRequest) request,
- (EventResponse) response);
- } else if (request instanceof ResourceRequest) {
- applicationContext.firePortletResourceRequest(application,
- root, (ResourceRequest) request,
- (ResourceResponse) response);
- }
-
- /* Handle the request */
- if (requestType == RequestType.FILE_UPLOAD) {
- // Root is resolved in handleFileUpload by
- // PortletCommunicationManager
- applicationManager.handleFileUpload(application,
- wrappedRequest, wrappedResponse);
- return;
- } else if (requestType == RequestType.BROWSER_DETAILS) {
- applicationManager.handleBrowserDetailsRequest(
- wrappedRequest, wrappedResponse, application);
- return;
- } else if (requestType == RequestType.UIDL) {
- // Handles AJAX UIDL requests
- applicationManager.handleUidlRequest(wrappedRequest,
- wrappedResponse, portletWrapper, root);
- return;
- } else {
- /*
- * Removes the application if it has stopped
- */
- if (!application.isRunning()) {
- endApplication(request, response, application);
- return;
- }
-
- handleOtherRequest(wrappedRequest, wrappedResponse,
- requestType, application, applicationContext,
- applicationManager);
- }
- } catch (final SessionExpiredException e) {
- // TODO Figure out a better way to deal with
- // SessionExpiredExceptions
- getLogger().finest("A user session has expired");
- } catch (final GeneralSecurityException e) {
- // TODO Figure out a better way to deal with
- // GeneralSecurityExceptions
- getLogger()
- .fine("General security exception, the security key was probably incorrect.");
- } catch (final Throwable e) {
- handleServiceException(wrappedRequest, wrappedResponse,
- application, e);
- } finally {
- // Notifies transaction end
- try {
- if (transactionStarted) {
- ((PortletApplicationContext2) application.getContext())
- .endTransaction(application, request);
- }
- } finally {
- try {
- if (requestStarted) {
- ((PortletRequestListener) application)
- .onRequestEnd(request, response);
-
- }
- } finally {
- Root.setCurrent(null);
- Application.setCurrent(null);
-
- PortletSession session = request
- .getPortletSession(false);
- if (session != null) {
- requestTimer.stop(getApplicationContext(session));
- }
- }
- }
- }
- }
- }
-
- /**
- * Wraps the request in a (possibly portal specific) wrapped portlet
- * request.
- *
- * @param request
- * The original PortletRequest
- * @return A wrapped version of the PorletRequest
- */
- protected WrappedPortletRequest createWrappedRequest(PortletRequest request) {
- String portalInfo = request.getPortalContext().getPortalInfo()
- .toLowerCase();
- if (portalInfo.contains("liferay")) {
- return new WrappedLiferayRequest(request,
- getDeploymentConfiguration());
- } else if (portalInfo.contains("gatein")) {
- return new WrappedGateinRequest(request,
- getDeploymentConfiguration());
- } else {
- return new WrappedPortletRequest(request,
- getDeploymentConfiguration());
- }
-
- }
-
- protected DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- private void handleUnknownRequest(PortletRequest request,
- PortletResponse response) {
- getLogger().warning("Unknown request type");
- }
-
- /**
- * Handle a portlet request that is not for static files, UIDL or upload.
- * Also render requests are handled here.
- *
- * This method is called after starting the application and calling portlet
- * and transaction listeners.
- *
- * @param request
- * @param response
- * @param requestType
- * @param application
- * @param applicationContext
- * @param applicationManager
- * @throws PortletException
- * @throws IOException
- * @throws MalformedURLException
- */
- private void handleOtherRequest(WrappedPortletRequest request,
- WrappedResponse response, RequestType requestType,
- Application application,
- PortletApplicationContext2 applicationContext,
- PortletCommunicationManager applicationManager)
- throws PortletException, IOException, MalformedURLException {
- if (requestType == RequestType.APPLICATION_RESOURCE
- || requestType == RequestType.RENDER) {
- if (!applicationManager.handleApplicationRequest(request, response)) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND,
- "Not found");
- }
- } else if (requestType == RequestType.EVENT) {
- // nothing to do, listeners do all the work
- } else if (requestType == RequestType.ACTION) {
- // nothing to do, listeners do all the work
- } else {
- throw new IllegalStateException(
- "handleRequest() without anything to do - should never happen!");
- }
- }
-
- @Override
- public void processEvent(EventRequest request, EventResponse response)
- throws PortletException, IOException {
- handleRequest(request, response);
- }
-
- private void serveStaticResources(ResourceRequest request,
- ResourceResponse response) throws IOException, PortletException {
- final String resourceID = request.getResourceID();
- final PortletContext pc = getPortletContext();
-
- InputStream is = pc.getResourceAsStream(resourceID);
- if (is != null) {
- final String mimetype = pc.getMimeType(resourceID);
- if (mimetype != null) {
- response.setContentType(mimetype);
- }
- final OutputStream os = response.getPortletOutputStream();
- final byte buffer[] = new byte[DEFAULT_BUFFER_SIZE];
- int bytes;
- while ((bytes = is.read(buffer)) >= 0) {
- os.write(buffer, 0, bytes);
- }
- } else {
- getLogger().info(
- "Requested resource [" + resourceID
- + "] could not be found");
- response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
- Integer.toString(HttpServletResponse.SC_NOT_FOUND));
- }
- }
-
- @Override
- public void processAction(ActionRequest request, ActionResponse response)
- throws PortletException, IOException {
- handleRequest(request, response);
- }
-
- @Override
- protected void doDispatch(RenderRequest request, RenderResponse response)
- throws PortletException, IOException {
- try {
- // try to let super handle - it'll call methods annotated for
- // handling, the default doXYZ(), or throw if a handler for the mode
- // is not found
- super.doDispatch(request, response);
-
- } catch (PortletException e) {
- if (e.getCause() == null) {
- // No cause interpreted as 'unknown mode' - pass that trough
- // so that the application can handle
- handleRequest(request, response);
-
- } else {
- // Something else failed, pass on
- throw e;
- }
- }
- }
-
- @Override
- public void serveResource(ResourceRequest request, ResourceResponse response)
- throws PortletException, IOException {
- handleRequest(request, response);
- }
-
- boolean requestCanCreateApplication(PortletRequest request,
- RequestType requestType) {
- if (requestType == RequestType.UIDL && isRepaintAll(request)) {
- return true;
- } else if (requestType == RequestType.RENDER) {
- // In most cases the first request is a render request that renders
- // the HTML fragment. This should create an application instance.
- return true;
- } else if (requestType == RequestType.EVENT) {
- // A portlet can also be sent an event even though it has not been
- // rendered, e.g. portlet on one page sends an event to a portlet on
- // another page and then moves the user to that page.
- return true;
- }
- return false;
- }
-
- private boolean isRepaintAll(PortletRequest request) {
- return (request.getParameter(URL_PARAMETER_REPAINT_ALL) != null)
- && (request.getParameter(URL_PARAMETER_REPAINT_ALL).equals("1"));
- }
-
- private void startApplication(PortletRequest request,
- Application application, PortletApplicationContext2 context)
- throws PortletException, MalformedURLException {
- if (!application.isRunning()) {
- Locale locale = request.getLocale();
- application.setLocale(locale);
- // No application URL when running inside a portlet
- application.start(new ApplicationStartEvent(null,
- getDeploymentConfiguration().getInitParameters(), context,
- isProductionMode()));
- addonContext.applicationStarted(application);
- }
- }
-
- private void endApplication(PortletRequest request,
- PortletResponse response, Application application)
- throws IOException {
- final PortletSession session = request.getPortletSession();
- if (session != null) {
- getApplicationContext(session).removeApplication(application);
- }
- // Do not send any redirects when running inside a portlet.
- }
-
- private Application findApplicationInstance(
- WrappedPortletRequest wrappedRequest, RequestType requestType)
- throws PortletException, SessionExpiredException,
- MalformedURLException {
- PortletRequest request = wrappedRequest.getPortletRequest();
-
- boolean requestCanCreateApplication = requestCanCreateApplication(
- request, requestType);
-
- /* Find an existing application for this request. */
- Application application = getExistingApplication(request,
- requestCanCreateApplication);
-
- if (application != null) {
- /*
- * There is an existing application. We can use this as long as the
- * user not specifically requested to close or restart it.
- */
-
- final boolean restartApplication = (wrappedRequest
- .getParameter(URL_PARAMETER_RESTART_APPLICATION) != null);
- final boolean closeApplication = (wrappedRequest
- .getParameter(URL_PARAMETER_CLOSE_APPLICATION) != null);
-
- if (restartApplication) {
- closeApplication(application, request.getPortletSession(false));
- return createApplication(request);
- } else if (closeApplication) {
- closeApplication(application, request.getPortletSession(false));
- return null;
- } else {
- return application;
- }
- }
-
- // No existing application was found
-
- if (requestCanCreateApplication) {
- return createApplication(request);
- } else {
- throw new SessionExpiredException();
- }
- }
-
- private void closeApplication(Application application,
- PortletSession session) {
- if (application == null) {
- return;
- }
-
- application.close();
- if (session != null) {
- PortletApplicationContext2 context = getApplicationContext(session);
- context.removeApplication(application);
- }
- }
-
- private Application createApplication(PortletRequest request)
- throws PortletException, MalformedURLException {
- Application newApplication = getNewApplication(request);
- final PortletApplicationContext2 context = getApplicationContext(request
- .getPortletSession());
- context.addApplication(newApplication, request.getWindowID());
- return newApplication;
- }
-
- private Application getExistingApplication(PortletRequest request,
- boolean allowSessionCreation) throws MalformedURLException,
- SessionExpiredException {
-
- final PortletSession session = request
- .getPortletSession(allowSessionCreation);
-
- if (session == null) {
- throw new SessionExpiredException();
- }
-
- PortletApplicationContext2 context = getApplicationContext(session);
- Application application = context.getApplicationForWindowId(request
- .getWindowID());
- if (application == null) {
- return null;
- }
- if (application.isRunning()) {
- return application;
- }
- // application found but not running
- context.removeApplication(application);
-
- return null;
- }
-
- protected abstract Class<? extends Application> getApplicationClass()
- throws ClassNotFoundException;
-
- protected Application getNewApplication(PortletRequest request)
- throws PortletException {
- try {
- final Application application = getApplicationClass().newInstance();
- application.setRootPreserved(true);
- return application;
- } catch (final IllegalAccessException e) {
- throw new PortletException("getNewApplication failed", e);
- } catch (final InstantiationException e) {
- throw new PortletException("getNewApplication failed", e);
- } catch (final ClassNotFoundException e) {
- throw new PortletException("getNewApplication failed", e);
- }
- }
-
- /**
- * Get system messages from the current application class
- *
- * @return
- */
- protected SystemMessages getSystemMessages() {
- try {
- Class<? extends Application> appCls = getApplicationClass();
- Method m = appCls.getMethod("getSystemMessages", (Class[]) null);
- return (Application.SystemMessages) m.invoke(null, (Object[]) null);
- } catch (ClassNotFoundException e) {
- // This should never happen
- throw new SystemMessageException(e);
- } catch (SecurityException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (NoSuchMethodException e) {
- // This is completely ok and should be silently ignored
- } catch (IllegalArgumentException e) {
- // This should never happen
- throw new SystemMessageException(e);
- } catch (IllegalAccessException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (InvocationTargetException e) {
- // This should never happen
- throw new SystemMessageException(e);
- }
- return Application.getSystemMessages();
- }
-
- private void handleServiceException(WrappedPortletRequest request,
- WrappedPortletResponse response, Application application,
- Throwable e) throws IOException, PortletException {
- // TODO Check that this error handler is working when running inside a
- // portlet
-
- // if this was an UIDL request, response UIDL back to client
- if (getRequestType(request) == RequestType.UIDL) {
- Application.SystemMessages ci = getSystemMessages();
- criticalNotification(request, response,
- ci.getInternalErrorCaption(), ci.getInternalErrorMessage(),
- null, ci.getInternalErrorURL());
- if (application != null) {
- application.getErrorHandler()
- .terminalError(new RequestError(e));
- } else {
- throw new PortletException(e);
- }
- } else {
- // Re-throw other exceptions
- throw new PortletException(e);
- }
-
- }
-
- @SuppressWarnings("serial")
- public class RequestError implements Terminal.ErrorEvent, Serializable {
-
- private final Throwable throwable;
-
- public RequestError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
- * Send notification to client's application. Used to notify client of
- * critical errors and session expiration due to long inactivity. Server has
- * no knowledge of what application client refers to.
- *
- * @param request
- * the Portlet request instance.
- * @param response
- * the Portlet response to write to.
- * @param caption
- * for the notification
- * @param message
- * for the notification
- * @param details
- * a detail message to show in addition to the passed message.
- * Currently shown directly but could be hidden behind a details
- * drop down.
- * @param url
- * url to load after message, null for current page
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- void criticalNotification(WrappedPortletRequest request,
- WrappedPortletResponse response, String caption, String message,
- String details, String url) throws IOException {
-
- // clients JS app is still running, but server application either
- // no longer exists or it might fail to perform reasonably.
- // send a notification to client's application and link how
- // to "restart" application.
-
- if (caption != null) {
- caption = "\"" + caption + "\"";
- }
- if (details != null) {
- if (message == null) {
- message = details;
- } else {
- message += "<br/><br/>" + details;
- }
- }
- if (message != null) {
- message = "\"" + message + "\"";
- }
- if (url != null) {
- url = "\"" + url + "\"";
- }
-
- // Set the response type
- response.setContentType("application/json; charset=UTF-8");
- final OutputStream out = response.getOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- outWriter.print("for(;;);[{\"changes\":[], \"meta\" : {"
- + "\"appError\": {" + "\"caption\":" + caption + ","
- + "\"message\" : " + message + "," + "\"url\" : " + url
- + "}}, \"resources\": {}, \"locales\":[]}]");
- outWriter.close();
- }
-
- /**
- *
- * Gets the application context for a PortletSession. If no context is
- * currently stored in a session a new context is created and stored in the
- * session.
- *
- * @param portletSession
- * the portlet session.
- * @return the application context for the session.
- */
- protected PortletApplicationContext2 getApplicationContext(
- PortletSession portletSession) {
- return PortletApplicationContext2.getApplicationContext(portletSession);
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(AbstractApplicationPortlet.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
deleted file mode 100644
index 603bc74a21..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java
+++ /dev/null
@@ -1,1623 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import com.vaadin.Application;
-import com.vaadin.Application.ApplicationStartEvent;
-import com.vaadin.Application.SystemMessages;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.ThemeResource;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.server.AbstractCommunicationManager.Callback;
-import com.vaadin.ui.Root;
-
-/**
- * Abstract implementation of the ApplicationServlet which handles all
- * communication between the client and the server.
- *
- * It is possible to extend this class to provide own functionality but in most
- * cases this is unnecessary.
- *
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.0
- */
-
-@SuppressWarnings("serial")
-public abstract class AbstractApplicationServlet extends HttpServlet implements
- Constants {
-
- private static class AbstractApplicationServletWrapper implements Callback {
-
- private final AbstractApplicationServlet servlet;
-
- public AbstractApplicationServletWrapper(
- AbstractApplicationServlet servlet) {
- this.servlet = servlet;
- }
-
- @Override
- public void criticalNotification(WrappedRequest request,
- WrappedResponse response, String cap, String msg,
- String details, String outOfSyncURL) throws IOException {
- servlet.criticalNotification(
- WrappedHttpServletRequest.cast(request),
- ((WrappedHttpServletResponse) response), cap, msg, details,
- outOfSyncURL);
- }
- }
-
- // TODO Move some (all?) of the constants to a separate interface (shared
- // with portlet)
-
- private boolean productionMode = false;
-
- private final String resourcePath = null;
-
- private int resourceCacheTime = 3600;
-
- private DeploymentConfiguration deploymentConfiguration = new AbstractDeploymentConfiguration(
- getClass()) {
-
- @Override
- public String getStaticFileLocation(WrappedRequest request) {
- HttpServletRequest servletRequest = WrappedHttpServletRequest
- .cast(request);
- return AbstractApplicationServlet.this
- .getStaticFilesLocation(servletRequest);
- }
-
- @Override
- public String getConfiguredWidgetset(WrappedRequest request) {
- return getApplicationOrSystemProperty(
- AbstractApplicationServlet.PARAMETER_WIDGETSET,
- AbstractApplicationServlet.DEFAULT_WIDGETSET);
- }
-
- @Override
- public String getConfiguredTheme(WrappedRequest request) {
- // Use the default
- return AbstractApplicationServlet.getDefaultTheme();
- }
-
- @Override
- public boolean isStandalone(WrappedRequest request) {
- return true;
- }
-
- @Override
- public String getMimeType(String resourceName) {
- return getServletContext().getMimeType(resourceName);
- }
- };
-
- private final AddonContext addonContext = new AddonContext(
- getDeploymentConfiguration());
-
- /**
- * Called by the servlet container to indicate to a servlet that the servlet
- * is being placed into service.
- *
- * @param servletConfig
- * the object containing the servlet's configuration and
- * initialization parameters
- * @throws javax.servlet.ServletException
- * if an exception has occurred that interferes with the
- * servlet's normal operation.
- */
- @Override
- public void init(javax.servlet.ServletConfig servletConfig)
- throws javax.servlet.ServletException {
- super.init(servletConfig);
- Properties applicationProperties = getDeploymentConfiguration()
- .getInitParameters();
-
- // Read default parameters from server.xml
- final ServletContext context = servletConfig.getServletContext();
- for (final Enumeration<String> e = context.getInitParameterNames(); e
- .hasMoreElements();) {
- final String name = e.nextElement();
- applicationProperties.setProperty(name,
- context.getInitParameter(name));
- }
-
- // Override with application config from web.xml
- for (final Enumeration<String> e = servletConfig
- .getInitParameterNames(); e.hasMoreElements();) {
- final String name = e.nextElement();
- applicationProperties.setProperty(name,
- servletConfig.getInitParameter(name));
- }
-
- checkProductionMode();
- checkCrossSiteProtection();
- checkResourceCacheTime();
-
- addonContext.init();
- }
-
- @Override
- public void destroy() {
- super.destroy();
-
- addonContext.destroy();
- }
-
- private void checkCrossSiteProtection() {
- if (getDeploymentConfiguration().getApplicationOrSystemProperty(
- SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION, "false").equals(
- "true")) {
- /*
- * Print an information/warning message about running with xsrf
- * protection disabled
- */
- getLogger().warning(WARNING_XSRF_PROTECTION_DISABLED);
- }
- }
-
- private void checkProductionMode() {
- // Check if the application is in production mode.
- // We are in production mode if productionMode=true
- if (getDeploymentConfiguration().getApplicationOrSystemProperty(
- SERVLET_PARAMETER_PRODUCTION_MODE, "false").equals("true")) {
- productionMode = true;
- }
-
- if (!productionMode) {
- /* Print an information/warning message about running in debug mode */
- getLogger().warning(NOT_PRODUCTION_MODE_INFO);
- }
-
- }
-
- private void checkResourceCacheTime() {
- // Check if the browser caching time has been set in web.xml
- try {
- String rct = getDeploymentConfiguration()
- .getApplicationOrSystemProperty(
- SERVLET_PARAMETER_RESOURCE_CACHE_TIME, "3600");
- resourceCacheTime = Integer.parseInt(rct);
- } catch (NumberFormatException nfe) {
- // Default is 1h
- resourceCacheTime = 3600;
- getLogger().warning(WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC);
- }
- }
-
- /**
- * Returns true if the servlet is running in production mode. Production
- * mode disables all debug facilities.
- *
- * @return true if in production mode, false if in debug mode
- */
- public boolean isProductionMode() {
- return productionMode;
- }
-
- /**
- * Returns the amount of milliseconds the browser should cache a file.
- * Default is 1 hour (3600 ms).
- *
- * @return The amount of milliseconds files are cached in the browser
- */
- public int getResourceCacheTime() {
- return resourceCacheTime;
- }
-
- /**
- * Receives standard HTTP requests from the public service method and
- * dispatches them.
- *
- * @param request
- * the object that contains the request the client made of the
- * servlet.
- * @param response
- * the object that contains the response the servlet returns to
- * the client.
- * @throws ServletException
- * if an input or output error occurs while the servlet is
- * handling the TRACE request.
- * @throws IOException
- * if the request for the TRACE cannot be handled.
- */
-
- @Override
- protected void service(HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
- service(createWrappedRequest(request), createWrappedResponse(response));
- }
-
- private void service(WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws ServletException,
- IOException {
- RequestTimer requestTimer = new RequestTimer();
- requestTimer.start();
-
- AbstractApplicationServletWrapper servletWrapper = new AbstractApplicationServletWrapper(
- this);
-
- RequestType requestType = getRequestType(request);
- if (!ensureCookiesEnabled(requestType, request, response)) {
- return;
- }
-
- if (requestType == RequestType.STATIC_FILE) {
- serveStaticResources(request, response);
- return;
- }
-
- Application application = null;
- boolean transactionStarted = false;
- boolean requestStarted = false;
-
- try {
- // If a duplicate "close application" URL is received for an
- // application that is not open, redirect to the application's main
- // page.
- // This is needed as e.g. Spring Security remembers the last
- // URL from the application, which is the logout URL, and repeats
- // it.
- // We can tell apart a real onunload request from a repeated one
- // based on the real one having content (at least the UIDL security
- // key).
- if (requestType == RequestType.UIDL
- && request.getParameterMap().containsKey(
- ApplicationConnection.PARAM_UNLOADBURST)
- && request.getContentLength() < 1
- && getExistingApplication(request, false) == null) {
- redirectToApplication(request, response);
- return;
- }
-
- // Find out which application this request is related to
- application = findApplicationInstance(request, requestType);
- if (application == null) {
- return;
- }
- Application.setCurrent(application);
-
- /*
- * Get or create a WebApplicationContext and an ApplicationManager
- * for the session
- */
- WebApplicationContext webApplicationContext = getApplicationContext(request
- .getSession());
- CommunicationManager applicationManager = webApplicationContext
- .getApplicationManager(application, this);
-
- if (requestType == RequestType.CONNECTOR_RESOURCE) {
- applicationManager.serveConnectorResource(request, response);
- return;
- }
-
- /* Update browser information from the request */
- webApplicationContext.getBrowser().updateRequestDetails(request);
-
- /*
- * Call application requestStart before Application.init() is called
- * (bypasses the limitation in TransactionListener)
- */
- if (application instanceof HttpServletRequestListener) {
- ((HttpServletRequestListener) application).onRequestStart(
- request, response);
- requestStarted = true;
- }
-
- // Start the application if it's newly created
- startApplication(request, application, webApplicationContext);
-
- /*
- * Transaction starts. Call transaction listeners. Transaction end
- * is called in the finally block below.
- */
- webApplicationContext.startTransaction(application, request);
- transactionStarted = true;
-
- /* Handle the request */
- if (requestType == RequestType.FILE_UPLOAD) {
- // Root is resolved in communication manager
- applicationManager.handleFileUpload(application, request,
- response);
- return;
- } else if (requestType == RequestType.UIDL) {
- Root root = application.getRootForRequest(request);
- if (root == null) {
- throw new ServletException(ERROR_NO_ROOT_FOUND);
- }
- // Handles AJAX UIDL requests
- applicationManager.handleUidlRequest(request, response,
- servletWrapper, root);
- return;
- } else if (requestType == RequestType.BROWSER_DETAILS) {
- // Browser details - not related to a specific root
- applicationManager.handleBrowserDetailsRequest(request,
- response, application);
- return;
- }
-
- // Removes application if it has stopped (maybe by thread or
- // transactionlistener)
- if (!application.isRunning()) {
- endApplication(request, response, application);
- return;
- }
-
- if (applicationManager.handleApplicationRequest(request, response)) {
- return;
- }
- // TODO Should return 404 error here and not do anything more
-
- } catch (final SessionExpiredException e) {
- // Session has expired, notify user
- handleServiceSessionExpired(request, response);
- } catch (final GeneralSecurityException e) {
- handleServiceSecurityException(request, response);
- } catch (final Throwable e) {
- handleServiceException(request, response, application, e);
- } finally {
- // Notifies transaction end
- try {
- if (transactionStarted) {
- ((WebApplicationContext) application.getContext())
- .endTransaction(application, request);
-
- }
-
- } finally {
- try {
- if (requestStarted) {
- ((HttpServletRequestListener) application)
- .onRequestEnd(request, response);
- }
- } finally {
- Root.setCurrent(null);
- Application.setCurrent(null);
-
- HttpSession session = request.getSession(false);
- if (session != null) {
- requestTimer.stop(getApplicationContext(session));
- }
- }
- }
-
- }
- }
-
- private WrappedHttpServletResponse createWrappedResponse(
- HttpServletResponse response) {
- WrappedHttpServletResponse wrappedResponse = new WrappedHttpServletResponse(
- response, getDeploymentConfiguration());
- return wrappedResponse;
- }
-
- /**
- * Create a wrapped request for a http servlet request. This method can be
- * overridden if the wrapped request should have special properties.
- *
- * @param request
- * the original http servlet request
- * @return a wrapped request for the original request
- */
- protected WrappedHttpServletRequest createWrappedRequest(
- HttpServletRequest request) {
- return new WrappedHttpServletRequest(request,
- getDeploymentConfiguration());
- }
-
- /**
- * Gets a the deployment configuration for this servlet.
- *
- * @return the deployment configuration
- */
- protected DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- /**
- * Check that cookie support is enabled in the browser. Only checks UIDL
- * requests.
- *
- * @param requestType
- * Type of the request as returned by
- * {@link #getRequestType(HttpServletRequest)}
- * @param request
- * The request from the browser
- * @param response
- * The response to which an error can be written
- * @return false if cookies are disabled, true otherwise
- * @throws IOException
- */
- private boolean ensureCookiesEnabled(RequestType requestType,
- WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException {
- if (requestType == RequestType.UIDL && !isRepaintAll(request)) {
- // In all other but the first UIDL request a cookie should be
- // returned by the browser.
- // This can be removed if cookieless mode (#3228) is supported
- if (request.getRequestedSessionId() == null) {
- // User has cookies disabled
- criticalNotification(request, response, getSystemMessages()
- .getCookiesDisabledCaption(), getSystemMessages()
- .getCookiesDisabledMessage(), null, getSystemMessages()
- .getCookiesDisabledURL());
- return false;
- }
- }
- return true;
- }
-
- /**
- * Send a notification to client's application. Used to notify client of
- * critical errors, session expiration and more. Server has no knowledge of
- * what application client refers to.
- *
- * @param request
- * the HTTP request instance.
- * @param response
- * the HTTP response to write to.
- * @param caption
- * the notification caption
- * @param message
- * to notification body
- * @param details
- * a detail message to show in addition to the message. Currently
- * shown directly below the message but could be hidden behind a
- * details drop down in the future. Mainly used to give
- * additional information not necessarily useful to the end user.
- * @param url
- * url to load when the message is dismissed. Null will reload
- * the current page.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- protected void criticalNotification(WrappedHttpServletRequest request,
- HttpServletResponse response, String caption, String message,
- String details, String url) throws IOException {
-
- if (ServletPortletHelper.isUIDLRequest(request)) {
-
- if (caption != null) {
- caption = "\"" + JsonPaintTarget.escapeJSON(caption) + "\"";
- }
- if (details != null) {
- if (message == null) {
- message = details;
- } else {
- message += "<br/><br/>" + details;
- }
- }
-
- if (message != null) {
- message = "\"" + JsonPaintTarget.escapeJSON(message) + "\"";
- }
- if (url != null) {
- url = "\"" + JsonPaintTarget.escapeJSON(url) + "\"";
- }
-
- String output = "for(;;);[{\"changes\":[], \"meta\" : {"
- + "\"appError\": {" + "\"caption\":" + caption + ","
- + "\"message\" : " + message + "," + "\"url\" : " + url
- + "}}, \"resources\": {}, \"locales\":[]}]";
- writeResponse(response, "application/json; charset=UTF-8", output);
- } else {
- // Create an HTML reponse with the error
- String output = "";
-
- if (url != null) {
- output += "<a href=\"" + url + "\">";
- }
- if (caption != null) {
- output += "<b>" + caption + "</b><br/>";
- }
- if (message != null) {
- output += message;
- output += "<br/><br/>";
- }
-
- if (details != null) {
- output += details;
- output += "<br/><br/>";
- }
- if (url != null) {
- output += "</a>";
- }
- writeResponse(response, "text/html; charset=UTF-8", output);
-
- }
-
- }
-
- /**
- * Writes the response in {@code output} using the contentType given in
- * {@code contentType} to the provided {@link HttpServletResponse}
- *
- * @param response
- * @param contentType
- * @param output
- * Output to write (UTF-8 encoded)
- * @throws IOException
- */
- private void writeResponse(HttpServletResponse response,
- String contentType, String output) throws IOException {
- response.setContentType(contentType);
- final ServletOutputStream out = response.getOutputStream();
- // Set the response type
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- outWriter.print(output);
- outWriter.flush();
- outWriter.close();
- out.flush();
-
- }
-
- /**
- * Returns the application instance to be used for the request. If an
- * existing instance is not found a new one is created or null is returned
- * to indicate that the application is not available.
- *
- * @param request
- * @param requestType
- * @return
- * @throws MalformedURLException
- * @throws IllegalAccessException
- * @throws InstantiationException
- * @throws ServletException
- * @throws SessionExpiredException
- */
- private Application findApplicationInstance(HttpServletRequest request,
- RequestType requestType) throws MalformedURLException,
- ServletException, SessionExpiredException {
-
- boolean requestCanCreateApplication = requestCanCreateApplication(
- request, requestType);
-
- /* Find an existing application for this request. */
- Application application = getExistingApplication(request,
- requestCanCreateApplication);
-
- if (application != null) {
- /*
- * There is an existing application. We can use this as long as the
- * user not specifically requested to close or restart it.
- */
-
- final boolean restartApplication = (request
- .getParameter(URL_PARAMETER_RESTART_APPLICATION) != null);
- final boolean closeApplication = (request
- .getParameter(URL_PARAMETER_CLOSE_APPLICATION) != null);
-
- if (restartApplication) {
- closeApplication(application, request.getSession(false));
- return createApplication(request);
- } else if (closeApplication) {
- closeApplication(application, request.getSession(false));
- return null;
- } else {
- return application;
- }
- }
-
- // No existing application was found
-
- if (requestCanCreateApplication) {
- /*
- * If the request is such that it should create a new application if
- * one as not found, we do that.
- */
- return createApplication(request);
- } else {
- /*
- * The application was not found and a new one should not be
- * created. Assume the session has expired.
- */
- throw new SessionExpiredException();
- }
-
- }
-
- /**
- * Check if the request should create an application if an existing
- * application is not found.
- *
- * @param request
- * @param requestType
- * @return true if an application should be created, false otherwise
- */
- boolean requestCanCreateApplication(HttpServletRequest request,
- RequestType requestType) {
- if (requestType == RequestType.UIDL && isRepaintAll(request)) {
- /*
- * UIDL request contains valid repaintAll=1 event, the user probably
- * wants to initiate a new application through a custom index.html
- * without using the bootstrap page.
- */
- return true;
-
- } else if (requestType == RequestType.OTHER) {
- /*
- * I.e URIs that are not application resources or static (theme)
- * files.
- */
- return true;
-
- }
-
- return false;
- }
-
- /**
- * Gets resource path using different implementations. Required to
- * supporting different servlet container implementations (application
- * servers).
- *
- * @param servletContext
- * @param path
- * the resource path.
- * @return the resource path.
- */
- protected static String getResourcePath(ServletContext servletContext,
- String path) {
- String resultPath = null;
- resultPath = servletContext.getRealPath(path);
- if (resultPath != null) {
- return resultPath;
- } else {
- try {
- final URL url = servletContext.getResource(path);
- resultPath = url.getFile();
- } catch (final Exception e) {
- // FIXME: Handle exception
- getLogger().log(Level.INFO,
- "Could not find resource path " + path, e);
- }
- }
- return resultPath;
- }
-
- /**
- * Creates a new application and registers it into WebApplicationContext
- * (aka session). This is not meant to be overridden. Override
- * getNewApplication to create the application instance in a custom way.
- *
- * @param request
- * @return
- * @throws ServletException
- * @throws MalformedURLException
- */
- private Application createApplication(HttpServletRequest request)
- throws ServletException, MalformedURLException {
- Application newApplication = getNewApplication(request);
-
- final WebApplicationContext context = getApplicationContext(request
- .getSession());
- context.addApplication(newApplication);
-
- return newApplication;
- }
-
- private void handleServiceException(WrappedHttpServletRequest request,
- WrappedHttpServletResponse response, Application application,
- Throwable e) throws IOException, ServletException {
- // if this was an UIDL request, response UIDL back to client
- if (getRequestType(request) == RequestType.UIDL) {
- Application.SystemMessages ci = getSystemMessages();
- criticalNotification(request, response,
- ci.getInternalErrorCaption(), ci.getInternalErrorMessage(),
- null, ci.getInternalErrorURL());
- if (application != null) {
- application.getErrorHandler()
- .terminalError(new RequestError(e));
- } else {
- throw new ServletException(e);
- }
- } else {
- // Re-throw other exceptions
- throw new ServletException(e);
- }
-
- }
-
- /**
- * A helper method to strip away characters that might somehow be used for
- * XSS attacs. Leaves at least alphanumeric characters intact. Also removes
- * eg. ( and ), so values should be safe in javascript too.
- *
- * @param themeName
- * @return
- */
- protected static String stripSpecialChars(String themeName) {
- StringBuilder sb = new StringBuilder();
- char[] charArray = themeName.toCharArray();
- for (int i = 0; i < charArray.length; i++) {
- char c = charArray[i];
- if (!CHAR_BLACKLIST.contains(c)) {
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- private static final Collection<Character> CHAR_BLACKLIST = new HashSet<Character>(
- Arrays.asList(new Character[] { '&', '"', '\'', '<', '>', '(', ')',
- ';' }));
-
- /**
- * Returns the default theme. Must never return null.
- *
- * @return
- */
- public static String getDefaultTheme() {
- return DEFAULT_THEME_NAME;
- }
-
- void handleServiceSessionExpired(WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException,
- ServletException {
-
- if (isOnUnloadRequest(request)) {
- /*
- * Request was an unload request (e.g. window close event) and the
- * client expects no response if it fails.
- */
- return;
- }
-
- try {
- Application.SystemMessages ci = getSystemMessages();
- if (getRequestType(request) != RequestType.UIDL) {
- // 'plain' http req - e.g. browser reload;
- // just go ahead redirect the browser
- response.sendRedirect(ci.getSessionExpiredURL());
- } else {
- /*
- * Invalidate session (weird to have session if we're saying
- * that it's expired, and worse: portal integration will fail
- * since the session is not created by the portal.
- *
- * Session must be invalidated before criticalNotification as it
- * commits the response.
- */
- request.getSession().invalidate();
-
- // send uidl redirect
- criticalNotification(request, response,
- ci.getSessionExpiredCaption(),
- ci.getSessionExpiredMessage(), null,
- ci.getSessionExpiredURL());
-
- }
- } catch (SystemMessageException ee) {
- throw new ServletException(ee);
- }
-
- }
-
- private void handleServiceSecurityException(
- WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException,
- ServletException {
- if (isOnUnloadRequest(request)) {
- /*
- * Request was an unload request (e.g. window close event) and the
- * client expects no response if it fails.
- */
- return;
- }
-
- try {
- Application.SystemMessages ci = getSystemMessages();
- if (getRequestType(request) != RequestType.UIDL) {
- // 'plain' http req - e.g. browser reload;
- // just go ahead redirect the browser
- response.sendRedirect(ci.getCommunicationErrorURL());
- } else {
- // send uidl redirect
- criticalNotification(request, response,
- ci.getCommunicationErrorCaption(),
- ci.getCommunicationErrorMessage(),
- INVALID_SECURITY_KEY_MSG, ci.getCommunicationErrorURL());
- /*
- * Invalidate session. Portal integration will fail otherwise
- * since the session is not created by the portal.
- */
- request.getSession().invalidate();
- }
- } catch (SystemMessageException ee) {
- throw new ServletException(ee);
- }
-
- log("Invalid security key received from " + request.getRemoteHost());
- }
-
- /**
- * Creates a new application for the given request.
- *
- * @param request
- * the HTTP request.
- * @return A new Application instance.
- * @throws ServletException
- */
- protected abstract Application getNewApplication(HttpServletRequest request)
- throws ServletException;
-
- /**
- * Starts the application if it is not already running.
- *
- * @param request
- * @param application
- * @param webApplicationContext
- * @throws ServletException
- * @throws MalformedURLException
- */
- private void startApplication(HttpServletRequest request,
- Application application, WebApplicationContext webApplicationContext)
- throws ServletException, MalformedURLException {
-
- if (!application.isRunning()) {
- // Create application
- final URL applicationUrl = getApplicationUrl(request);
-
- // Initial locale comes from the request
- Locale locale = request.getLocale();
- application.setLocale(locale);
- application.start(new ApplicationStartEvent(applicationUrl,
- getDeploymentConfiguration().getInitParameters(),
- webApplicationContext, isProductionMode()));
- addonContext.applicationStarted(application);
- }
- }
-
- /**
- * Check if this is a request for a static resource and, if it is, serve the
- * resource to the client.
- *
- * @param request
- * @param response
- * @return true if a file was served and the request has been handled, false
- * otherwise.
- * @throws IOException
- * @throws ServletException
- */
- private boolean serveStaticResources(HttpServletRequest request,
- HttpServletResponse response) throws IOException, ServletException {
-
- // FIXME What does 10 refer to?
- String pathInfo = request.getPathInfo();
- if (pathInfo == null || pathInfo.length() <= 10) {
- return false;
- }
-
- if ((request.getContextPath() != null)
- && (request.getRequestURI().startsWith("/VAADIN/"))) {
- serveStaticResourcesInVAADIN(request.getRequestURI(), request,
- response);
- return true;
- } else if (request.getRequestURI().startsWith(
- request.getContextPath() + "/VAADIN/")) {
- serveStaticResourcesInVAADIN(
- request.getRequestURI().substring(
- request.getContextPath().length()), request,
- response);
- return true;
- }
-
- return false;
- }
-
- /**
- * Serve resources from VAADIN directory.
- *
- * @param filename
- * The filename to serve. Should always start with /VAADIN/.
- * @param request
- * @param response
- * @throws IOException
- * @throws ServletException
- */
- private void serveStaticResourcesInVAADIN(String filename,
- HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
-
- final ServletContext sc = getServletContext();
- URL resourceUrl = sc.getResource(filename);
- if (resourceUrl == null) {
- // try if requested file is found from classloader
-
- // strip leading "/" otherwise stream from JAR wont work
- filename = filename.substring(1);
- resourceUrl = getDeploymentConfiguration().getClassLoader()
- .getResource(filename);
-
- if (resourceUrl == null) {
- // cannot serve requested file
- getLogger()
- .info("Requested resource ["
- + filename
- + "] not found from filesystem or through class loader."
- + " Add widgetset and/or theme JAR to your classpath or add files to WebContent/VAADIN folder.");
- response.setStatus(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- // security check: do not permit navigation out of the VAADIN
- // directory
- if (!isAllowedVAADINResourceUrl(request, resourceUrl)) {
- getLogger()
- .info("Requested resource ["
- + filename
- + "] not accessible in the VAADIN directory or access to it is forbidden.");
- response.setStatus(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
- }
-
- // Find the modification timestamp
- long lastModifiedTime = 0;
- URLConnection connection = null;
- try {
- connection = resourceUrl.openConnection();
- lastModifiedTime = connection.getLastModified();
- // Remove milliseconds to avoid comparison problems (milliseconds
- // are not returned by the browser in the "If-Modified-Since"
- // header).
- lastModifiedTime = lastModifiedTime - lastModifiedTime % 1000;
-
- if (browserHasNewestVersion(request, lastModifiedTime)) {
- response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
- return;
- }
- } catch (Exception e) {
- // Failed to find out last modified timestamp. Continue without it.
- getLogger()
- .log(Level.FINEST,
- "Failed to find out last modified timestamp. Continuing without it.",
- e);
- } finally {
- if (connection instanceof URLConnection) {
- try {
- // Explicitly close the input stream to prevent it
- // from remaining hanging
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4257700
- InputStream is = connection.getInputStream();
- if (is != null) {
- is.close();
- }
- } catch (IOException e) {
- getLogger().log(Level.INFO,
- "Error closing URLConnection input stream", e);
- }
- }
- }
-
- // Set type mime type if we can determine it based on the filename
- final String mimetype = sc.getMimeType(filename);
- if (mimetype != null) {
- response.setContentType(mimetype);
- }
-
- // Provide modification timestamp to the browser if it is known.
- if (lastModifiedTime > 0) {
- response.setDateHeader("Last-Modified", lastModifiedTime);
- /*
- * The browser is allowed to cache for 1 hour without checking if
- * the file has changed. This forces browsers to fetch a new version
- * when the Vaadin version is updated. This will cause more requests
- * to the servlet than without this but for high volume sites the
- * static files should never be served through the servlet. The
- * cache timeout can be configured by setting the resourceCacheTime
- * parameter in web.xml
- */
- response.setHeader("Cache-Control",
- "max-age= " + String.valueOf(resourceCacheTime));
- }
-
- // Write the resource to the client.
- final OutputStream os = response.getOutputStream();
- final byte buffer[] = new byte[DEFAULT_BUFFER_SIZE];
- int bytes;
- InputStream is = resourceUrl.openStream();
- while ((bytes = is.read(buffer)) >= 0) {
- os.write(buffer, 0, bytes);
- }
- is.close();
- }
-
- /**
- * Check whether a URL obtained from a classloader refers to a valid static
- * resource in the directory VAADIN.
- *
- * Warning: Overriding of this method is not recommended, but is possible to
- * support non-default classloaders or servers that may produce URLs
- * different from the normal ones. The method prototype may change in the
- * future. Care should be taken not to expose class files or other resources
- * outside the VAADIN directory if the method is overridden.
- *
- * @param request
- * @param resourceUrl
- * @return
- *
- * @since 6.6.7
- */
- protected boolean isAllowedVAADINResourceUrl(HttpServletRequest request,
- URL resourceUrl) {
- if ("jar".equals(resourceUrl.getProtocol())) {
- // This branch is used for accessing resources directly from the
- // Vaadin JAR in development environments and in similar cases.
-
- // Inside a JAR, a ".." would mean a real directory named ".." so
- // using it in paths should just result in the file not being found.
- // However, performing a check in case some servers or class loaders
- // try to normalize the path by collapsing ".." before the class
- // loader sees it.
-
- if (!resourceUrl.getPath().contains("!/VAADIN/")) {
- getLogger().info(
- "Blocked attempt to access a JAR entry not starting with /VAADIN/: "
- + resourceUrl);
- return false;
- }
- getLogger().fine(
- "Accepted access to a JAR entry using a class loader: "
- + resourceUrl);
- return true;
- } else {
- // Some servers such as GlassFish extract files from JARs (file:)
- // and e.g. JBoss 5+ use protocols vsf: and vfsfile: .
-
- // Check that the URL is in a VAADIN directory and does not contain
- // "/../"
- if (!resourceUrl.getPath().contains("/VAADIN/")
- || resourceUrl.getPath().contains("/../")) {
- getLogger().info(
- "Blocked attempt to access file: " + resourceUrl);
- return false;
- }
- getLogger().fine(
- "Accepted access to a file using a class loader: "
- + resourceUrl);
- return true;
- }
- }
-
- /**
- * Checks if the browser has an up to date cached version of requested
- * resource. Currently the check is performed using the "If-Modified-Since"
- * header. Could be expanded if needed.
- *
- * @param request
- * The HttpServletRequest from the browser.
- * @param resourceLastModifiedTimestamp
- * The timestamp when the resource was last modified. 0 if the
- * last modification time is unknown.
- * @return true if the If-Modified-Since header tells the cached version in
- * the browser is up to date, false otherwise
- */
- private boolean browserHasNewestVersion(HttpServletRequest request,
- long resourceLastModifiedTimestamp) {
- if (resourceLastModifiedTimestamp < 1) {
- // We do not know when it was modified so the browser cannot have an
- // up-to-date version
- return false;
- }
- /*
- * The browser can request the resource conditionally using an
- * If-Modified-Since header. Check this against the last modification
- * time.
- */
- try {
- // If-Modified-Since represents the timestamp of the version cached
- // in the browser
- long headerIfModifiedSince = request
- .getDateHeader("If-Modified-Since");
-
- if (headerIfModifiedSince >= resourceLastModifiedTimestamp) {
- // Browser has this an up-to-date version of the resource
- return true;
- }
- } catch (Exception e) {
- // Failed to parse header. Fail silently - the browser does not have
- // an up-to-date version in its cache.
- }
- return false;
- }
-
- protected enum RequestType {
- FILE_UPLOAD, BROWSER_DETAILS, UIDL, OTHER, STATIC_FILE, APPLICATION_RESOURCE, CONNECTOR_RESOURCE;
- }
-
- protected RequestType getRequestType(WrappedHttpServletRequest request) {
- if (ServletPortletHelper.isFileUploadRequest(request)) {
- return RequestType.FILE_UPLOAD;
- } else if (ServletPortletHelper.isConnectorResourceRequest(request)) {
- return RequestType.CONNECTOR_RESOURCE;
- } else if (isBrowserDetailsRequest(request)) {
- return RequestType.BROWSER_DETAILS;
- } else if (ServletPortletHelper.isUIDLRequest(request)) {
- return RequestType.UIDL;
- } else if (isStaticResourceRequest(request)) {
- return RequestType.STATIC_FILE;
- } else if (ServletPortletHelper.isApplicationResourceRequest(request)) {
- return RequestType.APPLICATION_RESOURCE;
- }
- return RequestType.OTHER;
-
- }
-
- private static boolean isBrowserDetailsRequest(HttpServletRequest request) {
- return "POST".equals(request.getMethod())
- && request.getParameter("browserDetails") != null;
- }
-
- private boolean isStaticResourceRequest(HttpServletRequest request) {
- String pathInfo = request.getPathInfo();
- if (pathInfo == null || pathInfo.length() <= 10) {
- return false;
- }
-
- if ((request.getContextPath() != null)
- && (request.getRequestURI().startsWith("/VAADIN/"))) {
- return true;
- } else if (request.getRequestURI().startsWith(
- request.getContextPath() + "/VAADIN/")) {
- return true;
- }
-
- return false;
- }
-
- private boolean isOnUnloadRequest(HttpServletRequest request) {
- return request.getParameter(ApplicationConnection.PARAM_UNLOADBURST) != null;
- }
-
- /**
- * Get system messages from the current application class
- *
- * @return
- */
- protected SystemMessages getSystemMessages() {
- Class<? extends Application> appCls = null;
- try {
- appCls = getApplicationClass();
- } catch (ClassNotFoundException e) {
- // Previous comment claimed that this should never happen
- throw new SystemMessageException(e);
- }
- return getSystemMessages(appCls);
- }
-
- public static SystemMessages getSystemMessages(
- Class<? extends Application> appCls) {
- try {
- if (appCls != null) {
- Method m = appCls
- .getMethod("getSystemMessages", (Class[]) null);
- return (Application.SystemMessages) m.invoke(null,
- (Object[]) null);
- }
- } catch (SecurityException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (NoSuchMethodException e) {
- // This is completely ok and should be silently ignored
- } catch (IllegalArgumentException e) {
- // This should never happen
- throw new SystemMessageException(e);
- } catch (IllegalAccessException e) {
- throw new SystemMessageException(
- "Application.getSystemMessage() should be static public", e);
- } catch (InvocationTargetException e) {
- // This should never happen
- throw new SystemMessageException(e);
- }
- return Application.getSystemMessages();
- }
-
- protected abstract Class<? extends Application> getApplicationClass()
- throws ClassNotFoundException;
-
- /**
- * Return the URL from where static files, e.g. the widgetset and the theme,
- * are served. In a standard configuration the VAADIN folder inside the
- * returned folder is what is used for widgetsets and themes.
- *
- * The returned folder is usually the same as the context path and
- * independent of the application.
- *
- * @param request
- * @return The location of static resources (should contain the VAADIN
- * directory). Never ends with a slash (/).
- */
- protected String getStaticFilesLocation(HttpServletRequest request) {
-
- return getWebApplicationsStaticFileLocation(request);
- }
-
- /**
- * The default method to fetch static files location (URL). This method does
- * not check for request attribute {@value #REQUEST_VAADIN_STATIC_FILE_PATH}
- *
- * @param request
- * @return
- */
- private String getWebApplicationsStaticFileLocation(
- HttpServletRequest request) {
- String staticFileLocation;
- // if property is defined in configurations, use that
- staticFileLocation = getDeploymentConfiguration()
- .getApplicationOrSystemProperty(PARAMETER_VAADIN_RESOURCES,
- null);
- if (staticFileLocation != null) {
- return staticFileLocation;
- }
-
- // the last (but most common) option is to generate default location
- // from request
-
- // if context is specified add it to widgetsetUrl
- String ctxPath = request.getContextPath();
-
- // FIXME: ctxPath.length() == 0 condition is probably unnecessary and
- // might even be wrong.
-
- if (ctxPath.length() == 0
- && request.getAttribute("javax.servlet.include.context_path") != null) {
- // include request (e.g portlet), get context path from
- // attribute
- ctxPath = (String) request
- .getAttribute("javax.servlet.include.context_path");
- }
-
- // Remove heading and trailing slashes from the context path
- ctxPath = removeHeadingOrTrailing(ctxPath, "/");
-
- if (ctxPath.equals("")) {
- return "";
- } else {
- return "/" + ctxPath;
- }
- }
-
- /**
- * Remove any heading or trailing "what" from the "string".
- *
- * @param string
- * @param what
- * @return
- */
- private static String removeHeadingOrTrailing(String string, String what) {
- while (string.startsWith(what)) {
- string = string.substring(1);
- }
-
- while (string.endsWith(what)) {
- string = string.substring(0, string.length() - 1);
- }
-
- return string;
- }
-
- /**
- * Write a redirect response to the main page of the application.
- *
- * @param request
- * @param response
- * @throws IOException
- * if sending the redirect fails due to an input/output error or
- * a bad application URL
- */
- private void redirectToApplication(HttpServletRequest request,
- HttpServletResponse response) throws IOException {
- String applicationUrl = getApplicationUrl(request).toExternalForm();
- response.sendRedirect(response.encodeRedirectURL(applicationUrl));
- }
-
- /**
- * Gets the current application URL from request.
- *
- * @param request
- * the HTTP request.
- * @throws MalformedURLException
- * if the application is denied access to the persistent data
- * store represented by the given URL.
- */
- protected URL getApplicationUrl(HttpServletRequest request)
- throws MalformedURLException {
- final URL reqURL = new URL(
- (request.isSecure() ? "https://" : "http://")
- + request.getServerName()
- + ((request.isSecure() && request.getServerPort() == 443)
- || (!request.isSecure() && request
- .getServerPort() == 80) ? "" : ":"
- + request.getServerPort())
- + request.getRequestURI());
- String servletPath = "";
- if (request.getAttribute("javax.servlet.include.servlet_path") != null) {
- // this is an include request
- servletPath = request.getAttribute(
- "javax.servlet.include.context_path").toString()
- + request
- .getAttribute("javax.servlet.include.servlet_path");
-
- } else {
- servletPath = request.getContextPath() + request.getServletPath();
- }
-
- if (servletPath.length() == 0
- || servletPath.charAt(servletPath.length() - 1) != '/') {
- servletPath = servletPath + "/";
- }
- URL u = new URL(reqURL, servletPath);
- return u;
- }
-
- /**
- * Gets the existing application for given request. Looks for application
- * instance for given request based on the requested URL.
- *
- * @param request
- * the HTTP request.
- * @param allowSessionCreation
- * true if a session should be created if no session exists,
- * false if no session should be created
- * @return Application instance, or null if the URL does not map to valid
- * application.
- * @throws MalformedURLException
- * if the application is denied access to the persistent data
- * store represented by the given URL.
- * @throws IllegalAccessException
- * @throws InstantiationException
- * @throws SessionExpiredException
- */
- protected Application getExistingApplication(HttpServletRequest request,
- boolean allowSessionCreation) throws MalformedURLException,
- SessionExpiredException {
-
- // Ensures that the session is still valid
- final HttpSession session = request.getSession(allowSessionCreation);
- if (session == null) {
- throw new SessionExpiredException();
- }
-
- WebApplicationContext context = getApplicationContext(session);
-
- // Gets application list for the session.
- final Collection<Application> applications = context.getApplications();
-
- // Search for the application (using the application URI) from the list
- for (final Iterator<Application> i = applications.iterator(); i
- .hasNext();) {
- final Application sessionApplication = i.next();
- final String sessionApplicationPath = sessionApplication.getURL()
- .getPath();
- String requestApplicationPath = getApplicationUrl(request)
- .getPath();
-
- if (requestApplicationPath.equals(sessionApplicationPath)) {
- // Found a running application
- if (sessionApplication.isRunning()) {
- return sessionApplication;
- }
- // Application has stopped, so remove it before creating a new
- // application
- getApplicationContext(session).removeApplication(
- sessionApplication);
- break;
- }
- }
-
- // Existing application not found
- return null;
- }
-
- /**
- * Ends the application.
- *
- * @param request
- * the HTTP request.
- * @param response
- * the HTTP response to write to.
- * @param application
- * the application to end.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- private void endApplication(HttpServletRequest request,
- HttpServletResponse response, Application application)
- throws IOException {
-
- String logoutUrl = application.getLogoutURL();
- if (logoutUrl == null) {
- logoutUrl = application.getURL().toString();
- }
-
- final HttpSession session = request.getSession();
- if (session != null) {
- getApplicationContext(session).removeApplication(application);
- }
-
- response.sendRedirect(response.encodeRedirectURL(logoutUrl));
- }
-
- /**
- * Returns the path info; note that this _can_ be different than
- * request.getPathInfo(). Examples where this might be useful:
- * <ul>
- * <li>An application runner servlet that runs different Vaadin applications
- * based on an identifier.</li>
- * <li>Providing a REST interface in the context root, while serving a
- * Vaadin UI on a sub-URI using only one servlet (e.g. REST on
- * http://example.com/foo, UI on http://example.com/foo/vaadin)</li>
- *
- * @param request
- * @return
- */
- protected String getRequestPathInfo(HttpServletRequest request) {
- return request.getPathInfo();
- }
-
- /**
- * Gets relative location of a theme resource.
- *
- * @param theme
- * the Theme name.
- * @param resource
- * the Theme resource.
- * @return External URI specifying the resource
- */
- public String getResourceLocation(String theme, ThemeResource resource) {
-
- if (resourcePath == null) {
- return resource.getResourceId();
- }
- return resourcePath + theme + "/" + resource.getResourceId();
- }
-
- private boolean isRepaintAll(HttpServletRequest request) {
- return (request.getParameter(URL_PARAMETER_REPAINT_ALL) != null)
- && (request.getParameter(URL_PARAMETER_REPAINT_ALL).equals("1"));
- }
-
- private void closeApplication(Application application, HttpSession session) {
- if (application == null) {
- return;
- }
-
- application.close();
- if (session != null) {
- WebApplicationContext context = getApplicationContext(session);
- context.removeApplication(application);
- }
- }
-
- /**
- *
- * Gets the application context from an HttpSession. If no context is
- * currently stored in a session a new context is created and stored in the
- * session.
- *
- * @param session
- * the HTTP session.
- * @return the application context for HttpSession.
- */
- protected WebApplicationContext getApplicationContext(HttpSession session) {
- /*
- * TODO the ApplicationContext.getApplicationContext() should be removed
- * and logic moved here. Now overriding context type is possible, but
- * the whole creation logic should be here. MT 1101
- */
- return WebApplicationContext.getApplicationContext(session);
- }
-
- public class RequestError implements Terminal.ErrorEvent, Serializable {
-
- private final Throwable throwable;
-
- public RequestError(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
- * Override this method if you need to use a specialized communicaiton
- * mananger implementation.
- *
- * @deprecated Instead of overriding this method, override
- * {@link WebApplicationContext} implementation via
- * {@link AbstractApplicationServlet#getApplicationContext(HttpSession)}
- * method and in that customized implementation return your
- * CommunicationManager in
- * {@link WebApplicationContext#getApplicationManager(Application, AbstractApplicationServlet)}
- * method.
- *
- * @param application
- * @return
- */
- @Deprecated
- public CommunicationManager createCommunicationManager(
- Application application) {
- return new CommunicationManager(application);
- }
-
- /**
- * Escapes characters to html entities. An exception is made for some
- * "safe characters" to keep the text somewhat readable.
- *
- * @param unsafe
- * @return a safe string to be added inside an html tag
- */
- public static final String safeEscapeForHtml(String unsafe) {
- if (null == unsafe) {
- return null;
- }
- StringBuilder safe = new StringBuilder();
- char[] charArray = unsafe.toCharArray();
- for (int i = 0; i < charArray.length; i++) {
- char c = charArray[i];
- if (isSafe(c)) {
- safe.append(c);
- } else {
- safe.append("&#");
- safe.append((int) c);
- safe.append(";");
- }
- }
-
- return safe.toString();
- }
-
- private static boolean isSafe(char c) {
- return //
- c > 47 && c < 58 || // alphanum
- c > 64 && c < 91 || // A-Z
- c > 96 && c < 123 // a-z
- ;
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(AbstractApplicationServlet.class.getName());
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
deleted file mode 100644
index ba1b3cadb6..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java
+++ /dev/null
@@ -1,2790 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.text.CharacterIterator;
-import java.text.DateFormat;
-import java.text.DateFormatSymbols;
-import java.text.SimpleDateFormat;
-import java.text.StringCharacterIterator;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.http.HttpServletResponse;
-
-import com.vaadin.Application;
-import com.vaadin.Application.SystemMessages;
-import com.vaadin.RootRequiresMoreInformationException;
-import com.vaadin.Version;
-import com.vaadin.annotations.JavaScript;
-import com.vaadin.annotations.StyleSheet;
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.external.json.JSONObject;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.communication.MethodInvocation;
-import com.vaadin.shared.communication.SharedState;
-import com.vaadin.shared.communication.UidlValue;
-import com.vaadin.terminal.AbstractClientConnector;
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.LegacyPaint;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.StreamVariable;
-import com.vaadin.terminal.StreamVariable.StreamingEndEvent;
-import com.vaadin.terminal.StreamVariable.StreamingErrorEvent;
-import com.vaadin.terminal.Terminal.ErrorEvent;
-import com.vaadin.terminal.Terminal.ErrorListener;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.server.BootstrapHandler.BootstrapContext;
-import com.vaadin.terminal.gwt.server.ComponentSizeValidator.InvalidLayout;
-import com.vaadin.terminal.gwt.server.RpcManager.RpcInvocationException;
-import com.vaadin.ui.AbstractComponent;
-import com.vaadin.ui.AbstractField;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ConnectorTracker;
-import com.vaadin.ui.HasComponents;
-import com.vaadin.ui.Root;
-import com.vaadin.ui.Window;
-
-/**
- * This is a common base class for the server-side implementations of the
- * communication system between the client code (compiled with GWT into
- * JavaScript) and the server side components. Its client side counterpart is
- * {@link ApplicationConnection}.
- *
- * TODO Document better!
- */
-@SuppressWarnings("serial")
-public abstract class AbstractCommunicationManager implements Serializable {
-
- private static final String DASHDASH = "--";
-
- private static final RequestHandler APP_RESOURCE_HANDLER = new ApplicationResourceHandler();
-
- private static final RequestHandler UNSUPPORTED_BROWSER_HANDLER = new UnsupportedBrowserHandler();
-
- /**
- * TODO Document me!
- *
- * @author peholmst
- */
- public interface Callback extends Serializable {
-
- public void criticalNotification(WrappedRequest request,
- WrappedResponse response, String cap, String msg,
- String details, String outOfSyncURL) throws IOException;
- }
-
- static class UploadInterruptedException extends Exception {
- public UploadInterruptedException() {
- super("Upload interrupted by other thread");
- }
- }
-
- private static String GET_PARAM_REPAINT_ALL = "repaintAll";
-
- // flag used in the request to indicate that the security token should be
- // written to the response
- private static final String WRITE_SECURITY_TOKEN_FLAG = "writeSecurityToken";
-
- /* Variable records indexes */
- public static final char VAR_BURST_SEPARATOR = '\u001d';
-
- public static final char VAR_ESCAPE_CHARACTER = '\u001b';
-
- private final HashMap<Integer, ClientCache> rootToClientCache = new HashMap<Integer, ClientCache>();
-
- private static final int MAX_BUFFER_SIZE = 64 * 1024;
-
- /* Same as in apache commons file upload library that was previously used. */
- private static final int MAX_UPLOAD_BUFFER_SIZE = 4 * 1024;
-
- private static final String GET_PARAM_ANALYZE_LAYOUTS = "analyzeLayouts";
-
- /**
- * The application this communication manager is used for
- */
- private final Application application;
-
- private List<String> locales;
-
- private int pendingLocalesIndex;
-
- private int timeoutInterval = -1;
-
- private DragAndDropService dragAndDropService;
-
- private String requestThemeName;
-
- private int maxInactiveInterval;
-
- private Connector highlightedConnector;
-
- private Map<String, Class<?>> connectorResourceContexts = new HashMap<String, Class<?>>();
-
- private Map<String, Map<String, StreamVariable>> pidToNameToStreamVariable;
-
- private Map<StreamVariable, String> streamVariableToSeckey;
-
- /**
- * TODO New constructor - document me!
- *
- * @param application
- */
- public AbstractCommunicationManager(Application application) {
- this.application = application;
- application.addRequestHandler(getBootstrapHandler());
- application.addRequestHandler(APP_RESOURCE_HANDLER);
- application.addRequestHandler(UNSUPPORTED_BROWSER_HANDLER);
- requireLocale(application.getLocale().toString());
- }
-
- protected Application getApplication() {
- return application;
- }
-
- private static final int LF = "\n".getBytes()[0];
-
- private static final String CRLF = "\r\n";
-
- private static final String UTF8 = "UTF8";
-
- private static final String GET_PARAM_HIGHLIGHT_COMPONENT = "highlightComponent";
-
- private static String readLine(InputStream stream) throws IOException {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- int readByte = stream.read();
- while (readByte != LF) {
- bout.write(readByte);
- readByte = stream.read();
- }
- byte[] bytes = bout.toByteArray();
- return new String(bytes, 0, bytes.length - 1, UTF8);
- }
-
- /**
- * Method used to stream content from a multipart request (either from
- * servlet or portlet request) to given StreamVariable
- *
- *
- * @param request
- * @param response
- * @param streamVariable
- * @param owner
- * @param boundary
- * @throws IOException
- */
- protected void doHandleSimpleMultipartFileUpload(WrappedRequest request,
- WrappedResponse response, StreamVariable streamVariable,
- String variableName, ClientConnector owner, String boundary)
- throws IOException {
- // multipart parsing, supports only one file for request, but that is
- // fine for our current terminal
-
- final InputStream inputStream = request.getInputStream();
-
- int contentLength = request.getContentLength();
-
- boolean atStart = false;
- boolean firstFileFieldFound = false;
-
- String rawfilename = "unknown";
- String rawMimeType = "application/octet-stream";
-
- /*
- * Read the stream until the actual file starts (empty line). Read
- * filename and content type from multipart headers.
- */
- while (!atStart) {
- String readLine = readLine(inputStream);
- contentLength -= (readLine.length() + 2);
- if (readLine.startsWith("Content-Disposition:")
- && readLine.indexOf("filename=") > 0) {
- rawfilename = readLine.replaceAll(".*filename=", "");
- String parenthesis = rawfilename.substring(0, 1);
- rawfilename = rawfilename.substring(1);
- rawfilename = rawfilename.substring(0,
- rawfilename.indexOf(parenthesis));
- firstFileFieldFound = true;
- } else if (firstFileFieldFound && readLine.equals("")) {
- atStart = true;
- } else if (readLine.startsWith("Content-Type")) {
- rawMimeType = readLine.split(": ")[1];
- }
- }
-
- contentLength -= (boundary.length() + CRLF.length() + 2
- * DASHDASH.length() + 2); // 2 == CRLF
-
- /*
- * Reads bytes from the underlying stream. Compares the read bytes to
- * the boundary string and returns -1 if met.
- *
- * The matching happens so that if the read byte equals to the first
- * char of boundary string, the stream goes to "buffering mode". In
- * buffering mode bytes are read until the character does not match the
- * corresponding from boundary string or the full boundary string is
- * found.
- *
- * Note, if this is someday needed elsewhere, don't shoot yourself to
- * foot and split to a top level helper class.
- */
- InputStream simpleMultiPartReader = new SimpleMultiPartInputStream(
- inputStream, boundary);
-
- /*
- * Should report only the filename even if the browser sends the path
- */
- final String filename = removePath(rawfilename);
- final String mimeType = rawMimeType;
-
- try {
- // TODO Shouldn't this check connectorEnabled?
- if (owner == null) {
- throw new UploadException(
- "File upload ignored because the connector for the stream variable was not found");
- }
- if (owner instanceof Component) {
- if (((Component) owner).isReadOnly()) {
- throw new UploadException(
- "Warning: file upload ignored because the componente was read-only");
- }
- }
- boolean forgetVariable = streamToReceiver(simpleMultiPartReader,
- streamVariable, filename, mimeType, contentLength);
- if (forgetVariable) {
- cleanStreamVariable(owner, variableName);
- }
- } catch (Exception e) {
- synchronized (application) {
- handleChangeVariablesError(application, (Component) owner, e,
- new HashMap<String, Object>());
- }
- }
- sendUploadResponse(request, response);
-
- }
-
- /**
- * Used to stream plain file post (aka XHR2.post(File))
- *
- * @param request
- * @param response
- * @param streamVariable
- * @param owner
- * @param contentLength
- * @throws IOException
- */
- protected void doHandleXhrFilePost(WrappedRequest request,
- WrappedResponse response, StreamVariable streamVariable,
- String variableName, ClientConnector owner, int contentLength)
- throws IOException {
-
- // These are unknown in filexhr ATM, maybe add to Accept header that
- // is accessible in portlets
- final String filename = "unknown";
- final String mimeType = filename;
- final InputStream stream = request.getInputStream();
- try {
- /*
- * safe cast as in GWT terminal all variable owners are expected to
- * be components.
- */
- Component component = (Component) owner;
- if (component.isReadOnly()) {
- throw new UploadException(
- "Warning: file upload ignored because the component was read-only");
- }
- boolean forgetVariable = streamToReceiver(stream, streamVariable,
- filename, mimeType, contentLength);
- if (forgetVariable) {
- cleanStreamVariable(owner, variableName);
- }
- } catch (Exception e) {
- synchronized (application) {
- handleChangeVariablesError(application, (Component) owner, e,
- new HashMap<String, Object>());
- }
- }
- sendUploadResponse(request, response);
- }
-
- /**
- * @param in
- * @param streamVariable
- * @param filename
- * @param type
- * @param contentLength
- * @return true if the streamvariable has informed that the terminal can
- * forget this variable
- * @throws UploadException
- */
- protected final boolean streamToReceiver(final InputStream in,
- StreamVariable streamVariable, String filename, String type,
- int contentLength) throws UploadException {
- if (streamVariable == null) {
- throw new IllegalStateException(
- "StreamVariable for the post not found");
- }
-
- final Application application = getApplication();
-
- OutputStream out = null;
- int totalBytes = 0;
- StreamingStartEventImpl startedEvent = new StreamingStartEventImpl(
- filename, type, contentLength);
- try {
- boolean listenProgress;
- synchronized (application) {
- streamVariable.streamingStarted(startedEvent);
- out = streamVariable.getOutputStream();
- listenProgress = streamVariable.listenProgress();
- }
-
- // Gets the output target stream
- if (out == null) {
- throw new NoOutputStreamException();
- }
-
- if (null == in) {
- // No file, for instance non-existent filename in html upload
- throw new NoInputStreamException();
- }
-
- final byte buffer[] = new byte[MAX_UPLOAD_BUFFER_SIZE];
- int bytesReadToBuffer = 0;
- while ((bytesReadToBuffer = in.read(buffer)) > 0) {
- out.write(buffer, 0, bytesReadToBuffer);
- totalBytes += bytesReadToBuffer;
- if (listenProgress) {
- // update progress if listener set and contentLength
- // received
- synchronized (application) {
- StreamingProgressEventImpl progressEvent = new StreamingProgressEventImpl(
- filename, type, contentLength, totalBytes);
- streamVariable.onProgress(progressEvent);
- }
- }
- if (streamVariable.isInterrupted()) {
- throw new UploadInterruptedException();
- }
- }
-
- // upload successful
- out.close();
- StreamingEndEvent event = new StreamingEndEventImpl(filename, type,
- totalBytes);
- synchronized (application) {
- streamVariable.streamingFinished(event);
- }
-
- } catch (UploadInterruptedException e) {
- // Download interrupted by application code
- tryToCloseStream(out);
- StreamingErrorEvent event = new StreamingErrorEventImpl(filename,
- type, contentLength, totalBytes, e);
- synchronized (application) {
- streamVariable.streamingFailed(event);
- }
- // Note, we are not throwing interrupted exception forward as it is
- // not a terminal level error like all other exception.
- } catch (final Exception e) {
- tryToCloseStream(out);
- synchronized (application) {
- StreamingErrorEvent event = new StreamingErrorEventImpl(
- filename, type, contentLength, totalBytes, e);
- synchronized (application) {
- streamVariable.streamingFailed(event);
- }
- // throw exception for terminal to be handled (to be passed to
- // terminalErrorHandler)
- throw new UploadException(e);
- }
- }
- return startedEvent.isDisposed();
- }
-
- static void tryToCloseStream(OutputStream out) {
- try {
- // try to close output stream (e.g. file handle)
- if (out != null) {
- out.close();
- }
- } catch (IOException e1) {
- // NOP
- }
- }
-
- /**
- * Removes any possible path information from the filename and returns the
- * filename. Separators / and \\ are used.
- *
- * @param name
- * @return
- */
- private static String removePath(String filename) {
- if (filename != null) {
- filename = filename.replaceAll("^.*[/\\\\]", "");
- }
-
- return filename;
- }
-
- /**
- * TODO document
- *
- * @param request
- * @param response
- * @throws IOException
- */
- protected void sendUploadResponse(WrappedRequest request,
- WrappedResponse response) throws IOException {
- response.setContentType("text/html");
- final OutputStream out = response.getOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- outWriter.print("<html><body>download handled</body></html>");
- outWriter.flush();
- out.close();
- }
-
- /**
- * Internally process a UIDL request from the client.
- *
- * This method calls
- * {@link #handleVariables(WrappedRequest, WrappedResponse, Callback, Application, Root)}
- * to process any changes to variables by the client and then repaints
- * affected components using {@link #paintAfterVariableChanges()}.
- *
- * Also, some cleanup is done when a request arrives for an application that
- * has already been closed.
- *
- * The method handleUidlRequest(...) in subclasses should call this method.
- *
- * TODO better documentation
- *
- * @param request
- * @param response
- * @param callback
- * @param root
- * target window for the UIDL request, can be null if target not
- * found
- * @throws IOException
- * @throws InvalidUIDLSecurityKeyException
- * @throws JSONException
- */
- public void handleUidlRequest(WrappedRequest request,
- WrappedResponse response, Callback callback, Root root)
- throws IOException, InvalidUIDLSecurityKeyException, JSONException {
-
- checkWidgetsetVersion(request);
- requestThemeName = request.getParameter("theme");
- maxInactiveInterval = request.getSessionMaxInactiveInterval();
- // repaint requested or session has timed out and new one is created
- boolean repaintAll;
- final OutputStream out;
-
- repaintAll = (request.getParameter(GET_PARAM_REPAINT_ALL) != null);
- // || (request.getSession().isNew()); FIXME What the h*ll is this??
- out = response.getOutputStream();
-
- boolean analyzeLayouts = false;
- if (repaintAll) {
- // analyzing can be done only with repaintAll
- analyzeLayouts = (request.getParameter(GET_PARAM_ANALYZE_LAYOUTS) != null);
-
- if (request.getParameter(GET_PARAM_HIGHLIGHT_COMPONENT) != null) {
- String pid = request
- .getParameter(GET_PARAM_HIGHLIGHT_COMPONENT);
- highlightedConnector = root.getConnectorTracker().getConnector(
- pid);
- highlightConnector(highlightedConnector);
- }
- }
-
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
-
- // The rest of the process is synchronized with the application
- // in order to guarantee that no parallel variable handling is
- // made
- synchronized (application) {
-
- // Finds the window within the application
- if (application.isRunning()) {
- // Returns if no window found
- if (root == null) {
- // This should not happen, no windows exists but
- // application is still open.
- getLogger().warning("Could not get root for application");
- return;
- }
- } else {
- // application has been closed
- endApplication(request, response, application);
- return;
- }
-
- // Change all variables based on request parameters
- if (!handleVariables(request, response, callback, application, root)) {
-
- // var inconsistency; the client is probably out-of-sync
- SystemMessages ci = null;
- try {
- Method m = application.getClass().getMethod(
- "getSystemMessages", (Class[]) null);
- ci = (Application.SystemMessages) m.invoke(null,
- (Object[]) null);
- } catch (Exception e2) {
- // FIXME: Handle exception
- // Not critical, but something is still wrong; print
- // stacktrace
- getLogger().log(Level.WARNING,
- "getSystemMessages() failed - continuing", e2);
- }
- if (ci != null) {
- String msg = ci.getOutOfSyncMessage();
- String cap = ci.getOutOfSyncCaption();
- if (msg != null || cap != null) {
- callback.criticalNotification(request, response, cap,
- msg, null, ci.getOutOfSyncURL());
- // will reload page after this
- return;
- }
- }
- // No message to show, let's just repaint all.
- repaintAll = true;
- }
-
- paintAfterVariableChanges(request, response, callback, repaintAll,
- outWriter, root, analyzeLayouts);
- postPaint(root);
- }
-
- outWriter.close();
- requestThemeName = null;
- }
-
- /**
- * Checks that the version reported by the client (widgetset) matches that
- * of the server.
- *
- * @param request
- */
- private void checkWidgetsetVersion(WrappedRequest request) {
- String widgetsetVersion = request.getParameter("wsver");
- if (widgetsetVersion == null) {
- // Only check when the widgetset version is reported. It is reported
- // in the first UIDL request (not the initial request as it is a
- // plain GET /)
- return;
- }
-
- if (!Version.getFullVersion().equals(widgetsetVersion)) {
- getLogger().warning(
- String.format(Constants.WIDGETSET_MISMATCH_INFO,
- Version.getFullVersion(), widgetsetVersion));
- }
- }
-
- /**
- * Method called after the paint phase while still being synchronized on the
- * application
- *
- * @param root
- *
- */
- protected void postPaint(Root root) {
- // Remove connectors that have been detached from the application during
- // handling of the request
- root.getConnectorTracker().cleanConnectorMap();
-
- if (pidToNameToStreamVariable != null) {
- Iterator<String> iterator = pidToNameToStreamVariable.keySet()
- .iterator();
- while (iterator.hasNext()) {
- String connectorId = iterator.next();
- if (root.getConnectorTracker().getConnector(connectorId) == null) {
- // Owner is no longer attached to the application
- Map<String, StreamVariable> removed = pidToNameToStreamVariable
- .get(connectorId);
- for (String key : removed.keySet()) {
- streamVariableToSeckey.remove(removed.get(key));
- }
- iterator.remove();
- }
- }
- }
- }
-
- protected void highlightConnector(Connector highlightedConnector) {
- StringBuilder sb = new StringBuilder();
- sb.append("*** Debug details of a component: *** \n");
- sb.append("Type: ");
- sb.append(highlightedConnector.getClass().getName());
- if (highlightedConnector instanceof AbstractComponent) {
- AbstractComponent component = (AbstractComponent) highlightedConnector;
- sb.append("\nId:");
- sb.append(highlightedConnector.getConnectorId());
- if (component.getCaption() != null) {
- sb.append("\nCaption:");
- sb.append(component.getCaption());
- }
-
- printHighlightedComponentHierarchy(sb, component);
- }
- getLogger().info(sb.toString());
- }
-
- protected void printHighlightedComponentHierarchy(StringBuilder sb,
- AbstractComponent component) {
- LinkedList<Component> h = new LinkedList<Component>();
- h.add(component);
- Component parent = component.getParent();
- while (parent != null) {
- h.addFirst(parent);
- parent = parent.getParent();
- }
-
- sb.append("\nComponent hierarchy:\n");
- Application application2 = component.getApplication();
- sb.append(application2.getClass().getName());
- sb.append(".");
- sb.append(application2.getClass().getSimpleName());
- sb.append("(");
- sb.append(application2.getClass().getSimpleName());
- sb.append(".java");
- sb.append(":1)");
- int l = 1;
- for (Component component2 : h) {
- sb.append("\n");
- for (int i = 0; i < l; i++) {
- sb.append(" ");
- }
- l++;
- Class<? extends Component> componentClass = component2.getClass();
- Class<?> topClass = componentClass;
- while (topClass.getEnclosingClass() != null) {
- topClass = topClass.getEnclosingClass();
- }
- sb.append(componentClass.getName());
- sb.append(".");
- sb.append(componentClass.getSimpleName());
- sb.append("(");
- sb.append(topClass.getSimpleName());
- sb.append(".java:1)");
- }
- }
-
- /**
- * TODO document
- *
- * @param request
- * @param response
- * @param callback
- * @param repaintAll
- * @param outWriter
- * @param window
- * @param analyzeLayouts
- * @throws PaintException
- * @throws IOException
- * @throws JSONException
- */
- private void paintAfterVariableChanges(WrappedRequest request,
- WrappedResponse response, Callback callback, boolean repaintAll,
- final PrintWriter outWriter, Root root, boolean analyzeLayouts)
- throws PaintException, IOException, JSONException {
-
- // Removes application if it has stopped during variable changes
- if (!application.isRunning()) {
- endApplication(request, response, application);
- return;
- }
-
- openJsonMessage(outWriter, response);
-
- // security key
- Object writeSecurityTokenFlag = request
- .getAttribute(WRITE_SECURITY_TOKEN_FLAG);
-
- if (writeSecurityTokenFlag != null) {
- outWriter.print(getSecurityKeyUIDL(request));
- }
-
- writeUidlResponse(request, repaintAll, outWriter, root, analyzeLayouts);
-
- closeJsonMessage(outWriter);
-
- outWriter.close();
-
- }
-
- /**
- * Gets the security key (and generates one if needed) as UIDL.
- *
- * @param request
- * @return the security key UIDL or "" if the feature is turned off
- */
- public String getSecurityKeyUIDL(WrappedRequest request) {
- final String seckey = getSecurityKey(request);
- if (seckey != null) {
- return "\"" + ApplicationConnection.UIDL_SECURITY_TOKEN_ID
- + "\":\"" + seckey + "\",";
- } else {
- return "";
- }
- }
-
- /**
- * Gets the security key (and generates one if needed).
- *
- * @param request
- * @return the security key
- */
- protected String getSecurityKey(WrappedRequest request) {
- String seckey = null;
- seckey = (String) request
- .getSessionAttribute(ApplicationConnection.UIDL_SECURITY_TOKEN_ID);
- if (seckey == null) {
- seckey = UUID.randomUUID().toString();
- request.setSessionAttribute(
- ApplicationConnection.UIDL_SECURITY_TOKEN_ID, seckey);
- }
-
- return seckey;
- }
-
- @SuppressWarnings("unchecked")
- public void writeUidlResponse(WrappedRequest request, boolean repaintAll,
- final PrintWriter outWriter, Root root, boolean analyzeLayouts)
- throws PaintException, JSONException {
- ArrayList<ClientConnector> dirtyVisibleConnectors = new ArrayList<ClientConnector>();
- Application application = root.getApplication();
- // Paints components
- ConnectorTracker rootConnectorTracker = root.getConnectorTracker();
- getLogger().log(Level.FINE, "* Creating response to client");
- if (repaintAll) {
- getClientCache(root).clear();
- rootConnectorTracker.markAllConnectorsDirty();
-
- // Reset sent locales
- locales = null;
- requireLocale(application.getLocale().toString());
- }
-
- dirtyVisibleConnectors
- .addAll(getDirtyVisibleConnectors(rootConnectorTracker));
-
- getLogger().log(
- Level.FINE,
- "Found " + dirtyVisibleConnectors.size()
- + " dirty connectors to paint");
- for (ClientConnector connector : dirtyVisibleConnectors) {
- if (connector instanceof Component) {
- ((Component) connector).updateState();
- }
- }
- rootConnectorTracker.markAllConnectorsClean();
-
- outWriter.print("\"changes\":[");
-
- List<InvalidLayout> invalidComponentRelativeSizes = null;
-
- JsonPaintTarget paintTarget = new JsonPaintTarget(this, outWriter,
- !repaintAll);
- legacyPaint(paintTarget, dirtyVisibleConnectors);
-
- if (analyzeLayouts) {
- invalidComponentRelativeSizes = ComponentSizeValidator
- .validateComponentRelativeSizes(root.getContent(), null,
- null);
-
- // Also check any existing subwindows
- if (root.getWindows() != null) {
- for (Window subWindow : root.getWindows()) {
- invalidComponentRelativeSizes = ComponentSizeValidator
- .validateComponentRelativeSizes(
- subWindow.getContent(),
- invalidComponentRelativeSizes, null);
- }
- }
- }
-
- paintTarget.close();
- outWriter.print("], "); // close changes
-
- // send shared state to client
-
- // for now, send the complete state of all modified and new
- // components
-
- // Ideally, all this would be sent before "changes", but that causes
- // complications with legacy components that create sub-components
- // in their paint phase. Nevertheless, this will be processed on the
- // client after component creation but before legacy UIDL
- // processing.
- JSONObject sharedStates = new JSONObject();
- for (ClientConnector connector : dirtyVisibleConnectors) {
- SharedState state = connector.getState();
- if (null != state) {
- // encode and send shared state
- try {
- Class<? extends SharedState> stateType = connector
- .getStateType();
- SharedState referenceState = null;
- if (repaintAll) {
- // Use an empty state object as reference for full
- // repaints
- try {
- referenceState = stateType.newInstance();
- } catch (Exception e) {
- getLogger().log(
- Level.WARNING,
- "Error creating reference object for state of type "
- + stateType.getName());
- }
- }
- Object stateJson = JsonCodec.encode(state, referenceState,
- stateType, root.getConnectorTracker());
-
- sharedStates.put(connector.getConnectorId(), stateJson);
- } catch (JSONException e) {
- throw new PaintException(
- "Failed to serialize shared state for connector "
- + connector.getClass().getName() + " ("
- + connector.getConnectorId() + "): "
- + e.getMessage(), e);
- }
- }
- }
- outWriter.print("\"state\":");
- outWriter.append(sharedStates.toString());
- outWriter.print(", "); // close states
-
- // TODO This should be optimized. The type only needs to be
- // sent once for each connector id + on refresh. Use the same cache as
- // widget mapping
-
- JSONObject connectorTypes = new JSONObject();
- for (ClientConnector connector : dirtyVisibleConnectors) {
- String connectorType = paintTarget.getTag(connector);
- try {
- connectorTypes.put(connector.getConnectorId(), connectorType);
- } catch (JSONException e) {
- throw new PaintException(
- "Failed to send connector type for connector "
- + connector.getConnectorId() + ": "
- + e.getMessage(), e);
- }
- }
- outWriter.print("\"types\":");
- outWriter.append(connectorTypes.toString());
- outWriter.print(", "); // close states
-
- // Send update hierarchy information to the client.
-
- // This could be optimized aswell to send only info if hierarchy has
- // actually changed. Much like with the shared state. Note though
- // that an empty hierarchy is information aswell (e.g. change from 1
- // child to 0 children)
-
- outWriter.print("\"hierarchy\":");
-
- JSONObject hierarchyInfo = new JSONObject();
- for (ClientConnector connector : dirtyVisibleConnectors) {
- String connectorId = connector.getConnectorId();
- JSONArray children = new JSONArray();
-
- for (ClientConnector child : AbstractClientConnector
- .getAllChildrenIterable(connector)) {
- if (isVisible(child)) {
- children.put(child.getConnectorId());
- }
- }
- try {
- hierarchyInfo.put(connectorId, children);
- } catch (JSONException e) {
- throw new PaintException(
- "Failed to send hierarchy information about "
- + connectorId + " to the client: "
- + e.getMessage(), e);
- }
- }
- outWriter.append(hierarchyInfo.toString());
- outWriter.print(", "); // close hierarchy
-
- // send server to client RPC calls for components in the root, in call
- // order
-
- // collect RPC calls from components in the root in the order in
- // which they were performed, remove the calls from components
-
- LinkedList<ClientConnector> rpcPendingQueue = new LinkedList<ClientConnector>(
- dirtyVisibleConnectors);
- List<ClientMethodInvocation> pendingInvocations = collectPendingRpcCalls(dirtyVisibleConnectors);
-
- JSONArray rpcCalls = new JSONArray();
- for (ClientMethodInvocation invocation : pendingInvocations) {
- // add invocation to rpcCalls
- try {
- JSONArray invocationJson = new JSONArray();
- invocationJson.put(invocation.getConnector().getConnectorId());
- invocationJson.put(invocation.getInterfaceName());
- invocationJson.put(invocation.getMethodName());
- JSONArray paramJson = new JSONArray();
- for (int i = 0; i < invocation.getParameterTypes().length; ++i) {
- Type parameterType = invocation.getParameterTypes()[i];
- Object referenceParameter = null;
- // TODO Use default values for RPC parameter types
- // if (!JsonCodec.isInternalType(parameterType)) {
- // try {
- // referenceParameter = parameterType.newInstance();
- // } catch (Exception e) {
- // logger.log(Level.WARNING,
- // "Error creating reference object for parameter of type "
- // + parameterType.getName());
- // }
- // }
- paramJson.put(JsonCodec.encode(
- invocation.getParameters()[i], referenceParameter,
- parameterType, root.getConnectorTracker()));
- }
- invocationJson.put(paramJson);
- rpcCalls.put(invocationJson);
- } catch (JSONException e) {
- throw new PaintException(
- "Failed to serialize RPC method call parameters for connector "
- + invocation.getConnector().getConnectorId()
- + " method " + invocation.getInterfaceName()
- + "." + invocation.getMethodName() + ": "
- + e.getMessage(), e);
- }
-
- }
-
- if (rpcCalls.length() > 0) {
- outWriter.print("\"rpc\" : ");
- outWriter.append(rpcCalls.toString());
- outWriter.print(", "); // close rpc
- }
-
- outWriter.print("\"meta\" : {");
- boolean metaOpen = false;
-
- if (repaintAll) {
- metaOpen = true;
- outWriter.write("\"repaintAll\":true");
- if (analyzeLayouts) {
- outWriter.write(", \"invalidLayouts\":");
- outWriter.write("[");
- if (invalidComponentRelativeSizes != null) {
- boolean first = true;
- for (InvalidLayout invalidLayout : invalidComponentRelativeSizes) {
- if (!first) {
- outWriter.write(",");
- } else {
- first = false;
- }
- invalidLayout.reportErrors(outWriter, this, System.err);
- }
- }
- outWriter.write("]");
- }
- if (highlightedConnector != null) {
- outWriter.write(", \"hl\":\"");
- outWriter.write(highlightedConnector.getConnectorId());
- outWriter.write("\"");
- highlightedConnector = null;
- }
- }
-
- SystemMessages ci = null;
- try {
- Method m = application.getClass().getMethod("getSystemMessages",
- (Class[]) null);
- ci = (Application.SystemMessages) m.invoke(null, (Object[]) null);
- } catch (NoSuchMethodException e) {
- getLogger().log(Level.WARNING,
- "getSystemMessages() failed - continuing", e);
- } catch (IllegalArgumentException e) {
- getLogger().log(Level.WARNING,
- "getSystemMessages() failed - continuing", e);
- } catch (IllegalAccessException e) {
- getLogger().log(Level.WARNING,
- "getSystemMessages() failed - continuing", e);
- } catch (InvocationTargetException e) {
- getLogger().log(Level.WARNING,
- "getSystemMessages() failed - continuing", e);
- }
-
- // meta instruction for client to enable auto-forward to
- // sessionExpiredURL after timer expires.
- if (ci != null && ci.getSessionExpiredMessage() == null
- && ci.getSessionExpiredCaption() == null
- && ci.isSessionExpiredNotificationEnabled()) {
- int newTimeoutInterval = getTimeoutInterval();
- if (repaintAll || (timeoutInterval != newTimeoutInterval)) {
- String escapedURL = ci.getSessionExpiredURL() == null ? "" : ci
- .getSessionExpiredURL().replace("/", "\\/");
- if (metaOpen) {
- outWriter.write(",");
- }
- outWriter.write("\"timedRedirect\":{\"interval\":"
- + (newTimeoutInterval + 15) + ",\"url\":\""
- + escapedURL + "\"}");
- metaOpen = true;
- }
- timeoutInterval = newTimeoutInterval;
- }
-
- outWriter.print("}, \"resources\" : {");
-
- // Precache custom layouts
-
- // TODO We should only precache the layouts that are not
- // cached already (plagiate from usedPaintableTypes)
- int resourceIndex = 0;
- for (final Iterator<Object> i = paintTarget.getUsedResources()
- .iterator(); i.hasNext();) {
- final String resource = (String) i.next();
- InputStream is = null;
- try {
- is = getThemeResourceAsStream(root, getTheme(root), resource);
- } catch (final Exception e) {
- // FIXME: Handle exception
- getLogger().log(Level.FINER,
- "Failed to get theme resource stream.", e);
- }
- if (is != null) {
-
- outWriter.print((resourceIndex++ > 0 ? ", " : "") + "\""
- + resource + "\" : ");
- final StringBuffer layout = new StringBuffer();
-
- try {
- final InputStreamReader r = new InputStreamReader(is,
- "UTF-8");
- final char[] buffer = new char[20000];
- int charsRead = 0;
- while ((charsRead = r.read(buffer)) > 0) {
- layout.append(buffer, 0, charsRead);
- }
- r.close();
- } catch (final java.io.IOException e) {
- // FIXME: Handle exception
- getLogger().log(Level.INFO, "Resource transfer failed", e);
- }
- outWriter.print("\""
- + JsonPaintTarget.escapeJSON(layout.toString()) + "\"");
- } else {
- // FIXME: Handle exception
- getLogger().severe("CustomLayout not found: " + resource);
- }
- }
- outWriter.print("}");
-
- Collection<Class<? extends ClientConnector>> usedClientConnectors = paintTarget
- .getUsedClientConnectors();
- boolean typeMappingsOpen = false;
- ClientCache clientCache = getClientCache(root);
-
- List<Class<? extends ClientConnector>> newConnectorTypes = new ArrayList<Class<? extends ClientConnector>>();
-
- for (Class<? extends ClientConnector> class1 : usedClientConnectors) {
- if (clientCache.cache(class1)) {
- // client does not know the mapping key for this type, send
- // mapping to client
- newConnectorTypes.add(class1);
-
- if (!typeMappingsOpen) {
- typeMappingsOpen = true;
- outWriter.print(", \"typeMappings\" : { ");
- } else {
- outWriter.print(" , ");
- }
- String canonicalName = class1.getCanonicalName();
- outWriter.print("\"");
- outWriter.print(canonicalName);
- outWriter.print("\" : ");
- outWriter.print(getTagForType(class1));
- }
- }
- if (typeMappingsOpen) {
- outWriter.print(" }");
- }
-
- boolean typeInheritanceMapOpen = false;
- if (typeMappingsOpen) {
- // send the whole type inheritance map if any new mappings
- for (Class<? extends ClientConnector> class1 : usedClientConnectors) {
- if (!ClientConnector.class.isAssignableFrom(class1
- .getSuperclass())) {
- continue;
- }
- if (!typeInheritanceMapOpen) {
- typeInheritanceMapOpen = true;
- outWriter.print(", \"typeInheritanceMap\" : { ");
- } else {
- outWriter.print(" , ");
- }
- outWriter.print("\"");
- outWriter.print(getTagForType(class1));
- outWriter.print("\" : ");
- outWriter
- .print(getTagForType((Class<? extends ClientConnector>) class1
- .getSuperclass()));
- }
- if (typeInheritanceMapOpen) {
- outWriter.print(" }");
- }
- }
-
- /*
- * Ensure super classes come before sub classes to get script dependency
- * order right. Sub class @JavaScript might assume that @JavaScript
- * defined by super class is already loaded.
- */
- Collections.sort(newConnectorTypes, new Comparator<Class<?>>() {
- @Override
- public int compare(Class<?> o1, Class<?> o2) {
- // TODO optimize using Class.isAssignableFrom?
- return hierarchyDepth(o1) - hierarchyDepth(o2);
- }
-
- private int hierarchyDepth(Class<?> type) {
- if (type == Object.class) {
- return 0;
- } else {
- return hierarchyDepth(type.getSuperclass()) + 1;
- }
- }
- });
-
- List<String> scriptDependencies = new ArrayList<String>();
- List<String> styleDependencies = new ArrayList<String>();
-
- for (Class<? extends ClientConnector> class1 : newConnectorTypes) {
- JavaScript jsAnnotation = class1.getAnnotation(JavaScript.class);
- if (jsAnnotation != null) {
- for (String resource : jsAnnotation.value()) {
- scriptDependencies.add(registerResource(resource, class1));
- }
- }
-
- StyleSheet styleAnnotation = class1.getAnnotation(StyleSheet.class);
- if (styleAnnotation != null) {
- for (String resource : styleAnnotation.value()) {
- styleDependencies.add(registerResource(resource, class1));
- }
- }
- }
-
- // Include script dependencies in output if there are any
- if (!scriptDependencies.isEmpty()) {
- outWriter.print(", \"scriptDependencies\": "
- + new JSONArray(scriptDependencies).toString());
- }
-
- // Include style dependencies in output if there are any
- if (!styleDependencies.isEmpty()) {
- outWriter.print(", \"styleDependencies\": "
- + new JSONArray(styleDependencies).toString());
- }
-
- // add any pending locale definitions requested by the client
- printLocaleDeclarations(outWriter);
-
- if (dragAndDropService != null) {
- dragAndDropService.printJSONResponse(outWriter);
- }
-
- writePerformanceData(outWriter);
- }
-
- /**
- * Resolves a resource URI, registering the URI with this
- * {@code AbstractCommunicationManager} if needed and returns a fully
- * qualified URI.
- */
- private String registerResource(String resourceUri, Class<?> context) {
- try {
- URI uri = new URI(resourceUri);
- String protocol = uri.getScheme();
-
- if ("connector".equals(protocol)) {
- // Strip initial slash
- String resourceName = uri.getPath().substring(1);
- return registerConnectorResource(resourceName, context);
- }
-
- if (protocol != null || uri.getHost() != null) {
- return resourceUri;
- }
-
- // Bare path interpreted as connector resource
- return registerConnectorResource(resourceUri, context);
- } catch (URISyntaxException e) {
- getLogger().log(Level.WARNING,
- "Could not parse resource url " + resourceUri, e);
- return resourceUri;
- }
- }
-
- private String registerConnectorResource(String name, Class<?> context) {
- synchronized (connectorResourceContexts) {
- // Add to map of names accepted by serveConnectorResource
- if (connectorResourceContexts.containsKey(name)) {
- Class<?> oldContext = connectorResourceContexts.get(name);
- if (oldContext != context) {
- getLogger().warning(
- "Resource " + name + " defined by both " + context
- + " and " + oldContext + ". Resource from "
- + oldContext + " will be used.");
- }
- } else {
- connectorResourceContexts.put(name, context);
- }
- }
-
- return ApplicationConnection.CONNECTOR_PROTOCOL_PREFIX + "/" + name;
- }
-
- /**
- * Adds the performance timing data (used by TestBench 3) to the UIDL
- * response.
- */
- private void writePerformanceData(final PrintWriter outWriter) {
- AbstractWebApplicationContext ctx = (AbstractWebApplicationContext) application
- .getContext();
- outWriter.write(String.format(", \"timings\":[%d, %d]",
- ctx.getTotalSessionTime(), ctx.getLastRequestTime()));
- }
-
- private void legacyPaint(PaintTarget paintTarget,
- ArrayList<ClientConnector> dirtyVisibleConnectors)
- throws PaintException {
- List<Vaadin6Component> legacyComponents = new ArrayList<Vaadin6Component>();
- for (Connector connector : dirtyVisibleConnectors) {
- // All Components that want to use paintContent must implement
- // Vaadin6Component
- if (connector instanceof Vaadin6Component) {
- legacyComponents.add((Vaadin6Component) connector);
- }
- }
- sortByHierarchy((List) legacyComponents);
- for (Vaadin6Component c : legacyComponents) {
- getLogger().fine(
- "Painting Vaadin6Component " + c.getClass().getName() + "@"
- + Integer.toHexString(c.hashCode()));
- paintTarget.startTag("change");
- final String pid = c.getConnectorId();
- paintTarget.addAttribute("pid", pid);
- LegacyPaint.paint(c, paintTarget);
- paintTarget.endTag("change");
- }
-
- }
-
- private void sortByHierarchy(List<Component> paintables) {
- // Vaadin 6 requires parents to be painted before children as component
- // containers rely on that their updateFromUIDL method has been called
- // before children start calling e.g. updateCaption
- Collections.sort(paintables, new Comparator<Component>() {
-
- @Override
- public int compare(Component c1, Component c2) {
- int depth1 = 0;
- while (c1.getParent() != null) {
- depth1++;
- c1 = c1.getParent();
- }
- int depth2 = 0;
- while (c2.getParent() != null) {
- depth2++;
- c2 = c2.getParent();
- }
- if (depth1 < depth2) {
- return -1;
- }
- if (depth1 > depth2) {
- return 1;
- }
- return 0;
- }
- });
-
- }
-
- private ClientCache getClientCache(Root root) {
- Integer rootId = Integer.valueOf(root.getRootId());
- ClientCache cache = rootToClientCache.get(rootId);
- if (cache == null) {
- cache = new ClientCache();
- rootToClientCache.put(rootId, cache);
- }
- return cache;
- }
-
- /**
- * Checks if the connector is visible in context. For Components,
- * {@link #isVisible(Component)} is used. For other types of connectors, the
- * contextual visibility of its first Component ancestor is used. If no
- * Component ancestor is found, the connector is not visible.
- *
- * @param connector
- * The connector to check
- * @return <code>true</code> if the connector is visible to the client,
- * <code>false</code> otherwise
- */
- static boolean isVisible(ClientConnector connector) {
- if (connector instanceof Component) {
- return isVisible((Component) connector);
- } else {
- ClientConnector parent = connector.getParent();
- if (parent == null) {
- return false;
- } else {
- return isVisible(parent);
- }
- }
- }
-
- /**
- * Checks if the component is visible in context, i.e. returns false if the
- * child is hidden, the parent is hidden or the parent says the child should
- * not be rendered (using
- * {@link HasComponents#isComponentVisible(Component)}
- *
- * @param child
- * The child to check
- * @return true if the child is visible to the client, false otherwise
- */
- static boolean isVisible(Component child) {
- if (!child.isVisible()) {
- return false;
- }
-
- HasComponents parent = child.getParent();
- if (parent == null) {
- if (child instanceof Root) {
- return child.isVisible();
- } else {
- return false;
- }
- }
-
- return parent.isComponentVisible(child) && isVisible(parent);
- }
-
- private static class NullIterator<E> implements Iterator<E> {
-
- @Override
- public boolean hasNext() {
- return false;
- }
-
- @Override
- public E next() {
- return null;
- }
-
- @Override
- public void remove() {
- }
-
- }
-
- /**
- * Collects all pending RPC calls from listed {@link ClientConnector}s and
- * clears their RPC queues.
- *
- * @param rpcPendingQueue
- * list of {@link ClientConnector} of interest
- * @return ordered list of pending RPC calls
- */
- private List<ClientMethodInvocation> collectPendingRpcCalls(
- List<ClientConnector> rpcPendingQueue) {
- List<ClientMethodInvocation> pendingInvocations = new ArrayList<ClientMethodInvocation>();
- for (ClientConnector connector : rpcPendingQueue) {
- List<ClientMethodInvocation> paintablePendingRpc = connector
- .retrievePendingRpcCalls();
- if (null != paintablePendingRpc && !paintablePendingRpc.isEmpty()) {
- List<ClientMethodInvocation> oldPendingRpc = pendingInvocations;
- int totalCalls = pendingInvocations.size()
- + paintablePendingRpc.size();
- pendingInvocations = new ArrayList<ClientMethodInvocation>(
- totalCalls);
-
- // merge two ordered comparable lists
- for (int destIndex = 0, oldIndex = 0, paintableIndex = 0; destIndex < totalCalls; destIndex++) {
- if (paintableIndex >= paintablePendingRpc.size()
- || (oldIndex < oldPendingRpc.size() && ((Comparable<ClientMethodInvocation>) oldPendingRpc
- .get(oldIndex))
- .compareTo(paintablePendingRpc
- .get(paintableIndex)) <= 0)) {
- pendingInvocations.add(oldPendingRpc.get(oldIndex++));
- } else {
- pendingInvocations.add(paintablePendingRpc
- .get(paintableIndex++));
- }
- }
- }
- }
- return pendingInvocations;
- }
-
- protected abstract InputStream getThemeResourceAsStream(Root root,
- String themeName, String resource);
-
- private int getTimeoutInterval() {
- return maxInactiveInterval;
- }
-
- private String getTheme(Root root) {
- String themeName = root.getApplication().getThemeForRoot(root);
- String requestThemeName = getRequestTheme();
-
- if (requestThemeName != null) {
- themeName = requestThemeName;
- }
- if (themeName == null) {
- themeName = AbstractApplicationServlet.getDefaultTheme();
- }
- return themeName;
- }
-
- private String getRequestTheme() {
- return requestThemeName;
- }
-
- /**
- * Returns false if the cross site request forgery protection is turned off.
- *
- * @param application
- * @return false if the XSRF is turned off, true otherwise
- */
- public boolean isXSRFEnabled(Application application) {
- return !"true"
- .equals(application
- .getProperty(AbstractApplicationServlet.SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION));
- }
-
- /**
- * TODO document
- *
- * If this method returns false, something was submitted that we did not
- * expect; this is probably due to the client being out-of-sync and sending
- * variable changes for non-existing pids
- *
- * @return true if successful, false if there was an inconsistency
- */
- private boolean handleVariables(WrappedRequest request,
- WrappedResponse response, Callback callback,
- Application application2, Root root) throws IOException,
- InvalidUIDLSecurityKeyException, JSONException {
- boolean success = true;
-
- String changes = getRequestPayload(request);
- if (changes != null) {
-
- // Manage bursts one by one
- final String[] bursts = changes.split(String
- .valueOf(VAR_BURST_SEPARATOR));
-
- // Security: double cookie submission pattern unless disabled by
- // property
- if (isXSRFEnabled(application2)) {
- if (bursts.length == 1 && "init".equals(bursts[0])) {
- // init request; don't handle any variables, key sent in
- // response.
- request.setAttribute(WRITE_SECURITY_TOKEN_FLAG, true);
- return true;
- } else {
- // ApplicationServlet has stored the security token in the
- // session; check that it matched the one sent in the UIDL
- String sessId = (String) request
- .getSessionAttribute(ApplicationConnection.UIDL_SECURITY_TOKEN_ID);
-
- if (sessId == null || !sessId.equals(bursts[0])) {
- throw new InvalidUIDLSecurityKeyException(
- "Security key mismatch");
- }
- }
-
- }
-
- for (int bi = 1; bi < bursts.length; bi++) {
- // unescape any encoded separator characters in the burst
- final String burst = unescapeBurst(bursts[bi]);
- success &= handleBurst(request, root, burst);
-
- // In case that there were multiple bursts, we know that this is
- // a special synchronous case for closing window. Thus we are
- // not interested in sending any UIDL changes back to client.
- // Still we must clear component tree between bursts to ensure
- // that no removed components are updated. The painting after
- // the last burst is handled normally by the calling method.
- if (bi < bursts.length - 1) {
-
- // We will be discarding all changes
- final PrintWriter outWriter = new PrintWriter(
- new CharArrayWriter());
-
- paintAfterVariableChanges(request, response, callback,
- true, outWriter, root, false);
-
- }
-
- }
- }
- /*
- * Note that we ignore inconsistencies while handling unload request.
- * The client can't remove invalid variable changes from the burst, and
- * we don't have the required logic implemented on the server side. E.g.
- * a component is removed in a previous burst.
- */
- return success;
- }
-
- /**
- * Processes a message burst received from the client.
- *
- * A burst can contain any number of RPC calls, including legacy variable
- * change calls that are processed separately.
- *
- * Consecutive changes to the value of the same variable are combined and
- * changeVariables() is only called once for them. This preserves the Vaadin
- * 6 semantics for components and add-ons that do not use Vaadin 7 RPC
- * directly.
- *
- * @param source
- * @param root
- * the root receiving the burst
- * @param burst
- * the content of the burst as a String to be parsed
- * @return true if the processing of the burst was successful and there were
- * no messages to non-existent components
- */
- public boolean handleBurst(WrappedRequest source, Root root,
- final String burst) {
- boolean success = true;
- try {
- Set<Connector> enabledConnectors = new HashSet<Connector>();
-
- List<MethodInvocation> invocations = parseInvocations(
- root.getConnectorTracker(), burst);
- for (MethodInvocation invocation : invocations) {
- final ClientConnector connector = getConnector(root,
- invocation.getConnectorId());
-
- if (connector != null && connector.isConnectorEnabled()) {
- enabledConnectors.add(connector);
- }
- }
-
- for (int i = 0; i < invocations.size(); i++) {
- MethodInvocation invocation = invocations.get(i);
-
- final ClientConnector connector = getConnector(root,
- invocation.getConnectorId());
-
- if (connector == null) {
- getLogger().log(
- Level.WARNING,
- "RPC call to " + invocation.getInterfaceName()
- + "." + invocation.getMethodName()
- + " received for connector "
- + invocation.getConnectorId()
- + " but no such connector could be found");
- continue;
- }
-
- if (!enabledConnectors.contains(connector)) {
-
- if (invocation instanceof LegacyChangeVariablesInvocation) {
- LegacyChangeVariablesInvocation legacyInvocation = (LegacyChangeVariablesInvocation) invocation;
- // TODO convert window close to a separate RPC call and
- // handle above - not a variable change
-
- // Handle special case where window-close is called
- // after the window has been removed from the
- // application or the application has closed
- Map<String, Object> changes = legacyInvocation
- .getVariableChanges();
- if (changes.size() == 1 && changes.containsKey("close")
- && Boolean.TRUE.equals(changes.get("close"))) {
- // Silently ignore this
- continue;
- }
- }
-
- // Connector is disabled, log a warning and move to the next
- String msg = "Ignoring RPC call for disabled connector "
- + connector.getClass().getName();
- if (connector instanceof Component) {
- String caption = ((Component) connector).getCaption();
- if (caption != null) {
- msg += ", caption=" + caption;
- }
- }
- getLogger().warning(msg);
- continue;
- }
-
- if (invocation instanceof ServerRpcMethodInvocation) {
- try {
- ServerRpcManager.applyInvocation(connector,
- (ServerRpcMethodInvocation) invocation);
- } catch (RpcInvocationException e) {
- Throwable realException = e.getCause();
- Component errorComponent = null;
- if (connector instanceof Component) {
- errorComponent = (Component) connector;
- }
- handleChangeVariablesError(root.getApplication(),
- errorComponent, realException, null);
- }
- } else {
-
- // All code below is for legacy variable changes
- LegacyChangeVariablesInvocation legacyInvocation = (LegacyChangeVariablesInvocation) invocation;
- Map<String, Object> changes = legacyInvocation
- .getVariableChanges();
- try {
- if (connector instanceof VariableOwner) {
- changeVariables(source, (VariableOwner) connector,
- changes);
- } else {
- throw new IllegalStateException(
- "Received legacy variable change for "
- + connector.getClass().getName()
- + " ("
- + connector.getConnectorId()
- + ") which is not a VariableOwner. The client-side connector sent these legacy varaibles: "
- + changes.keySet());
- }
- } catch (Exception e) {
- Component errorComponent = null;
- if (connector instanceof Component) {
- errorComponent = (Component) connector;
- } else if (connector instanceof DragAndDropService) {
- Object dropHandlerOwner = changes.get("dhowner");
- if (dropHandlerOwner instanceof Component) {
- errorComponent = (Component) dropHandlerOwner;
- }
- }
- handleChangeVariablesError(root.getApplication(),
- errorComponent, e, changes);
- }
- }
- }
- } catch (JSONException e) {
- getLogger().warning(
- "Unable to parse RPC call from the client: "
- + e.getMessage());
- // TODO or return success = false?
- throw new RuntimeException(e);
- }
-
- return success;
- }
-
- /**
- * Parse a message burst from the client into a list of MethodInvocation
- * instances.
- *
- * @param connectorTracker
- * The ConnectorTracker used to lookup connectors
- * @param burst
- * message string (JSON)
- * @return list of MethodInvocation to perform
- * @throws JSONException
- */
- private List<MethodInvocation> parseInvocations(
- ConnectorTracker connectorTracker, final String burst)
- throws JSONException {
- JSONArray invocationsJson = new JSONArray(burst);
-
- ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>();
-
- MethodInvocation previousInvocation = null;
- // parse JSON to MethodInvocations
- for (int i = 0; i < invocationsJson.length(); ++i) {
-
- JSONArray invocationJson = invocationsJson.getJSONArray(i);
-
- MethodInvocation invocation = parseInvocation(invocationJson,
- previousInvocation, connectorTracker);
- if (invocation != null) {
- // Can be null iff the invocation was a legacy invocation and it
- // was merged with the previous one
- invocations.add(invocation);
- previousInvocation = invocation;
- }
- }
- return invocations;
- }
-
- private MethodInvocation parseInvocation(JSONArray invocationJson,
- MethodInvocation previousInvocation,
- ConnectorTracker connectorTracker) throws JSONException {
- String connectorId = invocationJson.getString(0);
- String interfaceName = invocationJson.getString(1);
- String methodName = invocationJson.getString(2);
-
- JSONArray parametersJson = invocationJson.getJSONArray(3);
-
- if (LegacyChangeVariablesInvocation.isLegacyVariableChange(
- interfaceName, methodName)) {
- if (!(previousInvocation instanceof LegacyChangeVariablesInvocation)) {
- previousInvocation = null;
- }
-
- return parseLegacyChangeVariablesInvocation(connectorId,
- interfaceName, methodName,
- (LegacyChangeVariablesInvocation) previousInvocation,
- parametersJson, connectorTracker);
- } else {
- return parseServerRpcInvocation(connectorId, interfaceName,
- methodName, parametersJson, connectorTracker);
- }
-
- }
-
- private LegacyChangeVariablesInvocation parseLegacyChangeVariablesInvocation(
- String connectorId, String interfaceName, String methodName,
- LegacyChangeVariablesInvocation previousInvocation,
- JSONArray parametersJson, ConnectorTracker connectorTracker)
- throws JSONException {
- if (parametersJson.length() != 2) {
- throw new JSONException(
- "Invalid parameters in legacy change variables call. Expected 2, was "
- + parametersJson.length());
- }
- String variableName = parametersJson.getString(0);
- UidlValue uidlValue = (UidlValue) JsonCodec.decodeInternalType(
- UidlValue.class, true, parametersJson.get(1), connectorTracker);
-
- Object value = uidlValue.getValue();
-
- if (previousInvocation != null
- && previousInvocation.getConnectorId().equals(connectorId)) {
- previousInvocation.setVariableChange(variableName, value);
- return null;
- } else {
- return new LegacyChangeVariablesInvocation(connectorId,
- variableName, value);
- }
- }
-
- private ServerRpcMethodInvocation parseServerRpcInvocation(
- String connectorId, String interfaceName, String methodName,
- JSONArray parametersJson, ConnectorTracker connectorTracker)
- throws JSONException {
- ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation(
- connectorId, interfaceName, methodName, parametersJson.length());
-
- Object[] parameters = new Object[parametersJson.length()];
- Type[] declaredRpcMethodParameterTypes = invocation.getMethod()
- .getGenericParameterTypes();
-
- for (int j = 0; j < parametersJson.length(); ++j) {
- Object parameterValue = parametersJson.get(j);
- Type parameterType = declaredRpcMethodParameterTypes[j];
- parameters[j] = JsonCodec.decodeInternalOrCustomType(parameterType,
- parameterValue, connectorTracker);
- }
- invocation.setParameters(parameters);
- return invocation;
- }
-
- protected void changeVariables(Object source, final VariableOwner owner,
- Map<String, Object> m) {
- owner.changeVariables(source, m);
- }
-
- protected ClientConnector getConnector(Root root, String connectorId) {
- ClientConnector c = root.getConnectorTracker()
- .getConnector(connectorId);
- if (c == null
- && connectorId.equals(getDragAndDropService().getConnectorId())) {
- return getDragAndDropService();
- }
-
- return c;
- }
-
- private DragAndDropService getDragAndDropService() {
- if (dragAndDropService == null) {
- dragAndDropService = new DragAndDropService(this);
- }
- return dragAndDropService;
- }
-
- /**
- * Reads the request data from the Request and returns it converted to an
- * UTF-8 string.
- *
- * @param request
- * @return
- * @throws IOException
- */
- protected String getRequestPayload(WrappedRequest request)
- throws IOException {
-
- int requestLength = request.getContentLength();
- if (requestLength == 0) {
- return null;
- }
-
- ByteArrayOutputStream bout = requestLength <= 0 ? new ByteArrayOutputStream()
- : new ByteArrayOutputStream(requestLength);
-
- InputStream inputStream = request.getInputStream();
- byte[] buffer = new byte[MAX_BUFFER_SIZE];
-
- while (true) {
- int read = inputStream.read(buffer);
- if (read == -1) {
- break;
- }
- bout.write(buffer, 0, read);
- }
- String result = new String(bout.toByteArray(), "utf-8");
-
- return result;
- }
-
- public class ErrorHandlerErrorEvent implements ErrorEvent, Serializable {
- private final Throwable throwable;
-
- public ErrorHandlerErrorEvent(Throwable throwable) {
- this.throwable = throwable;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- }
-
- /**
- * Handles an error (exception) that occurred when processing variable
- * changes from the client or a failure of a file upload.
- *
- * For {@link AbstractField} components,
- * {@link AbstractField#handleError(com.vaadin.ui.AbstractComponent.ComponentErrorEvent)}
- * is called. In all other cases (or if the field does not handle the
- * error), {@link ErrorListener#terminalError(ErrorEvent)} for the
- * application error handler is called.
- *
- * @param application
- * @param owner
- * component that the error concerns
- * @param e
- * exception that occurred
- * @param m
- * map from variable names to values
- */
- private void handleChangeVariablesError(Application application,
- Component owner, Throwable t, Map<String, Object> m) {
- boolean handled = false;
- ChangeVariablesErrorEvent errorEvent = new ChangeVariablesErrorEvent(
- owner, t, m);
-
- if (owner instanceof AbstractField) {
- try {
- handled = ((AbstractField<?>) owner).handleError(errorEvent);
- } catch (Exception handlerException) {
- /*
- * If there is an error in the component error handler we pass
- * the that error to the application error handler and continue
- * processing the actual error
- */
- application.getErrorHandler().terminalError(
- new ErrorHandlerErrorEvent(handlerException));
- handled = false;
- }
- }
-
- if (!handled) {
- application.getErrorHandler().terminalError(errorEvent);
- }
-
- }
-
- /**
- * Unescape encoded burst separator characters in a burst received from the
- * client. This protects from separator injection attacks.
- *
- * @param encodedValue
- * to decode
- * @return decoded value
- */
- protected String unescapeBurst(String encodedValue) {
- final StringBuilder result = new StringBuilder();
- final StringCharacterIterator iterator = new StringCharacterIterator(
- encodedValue);
- char character = iterator.current();
- while (character != CharacterIterator.DONE) {
- if (VAR_ESCAPE_CHARACTER == character) {
- character = iterator.next();
- switch (character) {
- case VAR_ESCAPE_CHARACTER + 0x30:
- // escaped escape character
- result.append(VAR_ESCAPE_CHARACTER);
- break;
- case VAR_BURST_SEPARATOR + 0x30:
- // +0x30 makes these letters for easier reading
- result.append((char) (character - 0x30));
- break;
- case CharacterIterator.DONE:
- // error
- throw new RuntimeException(
- "Communication error: Unexpected end of message");
- default:
- // other escaped character - probably a client-server
- // version mismatch
- throw new RuntimeException(
- "Invalid escaped character from the client - check that the widgetset and server versions match");
- }
- } else {
- // not a special character - add it to the result as is
- result.append(character);
- }
- character = iterator.next();
- }
- return result.toString();
- }
-
- /**
- * Prints the queued (pending) locale definitions to a {@link PrintWriter}
- * in a (UIDL) format that can be sent to the client and used there in
- * formatting dates, times etc.
- *
- * @param outWriter
- */
- private void printLocaleDeclarations(PrintWriter outWriter) {
- /*
- * ----------------------------- Sending Locale sensitive date
- * -----------------------------
- */
-
- // Send locale informations to client
- outWriter.print(", \"locales\":[");
- for (; pendingLocalesIndex < locales.size(); pendingLocalesIndex++) {
-
- final Locale l = generateLocale(locales.get(pendingLocalesIndex));
- // Locale name
- outWriter.print("{\"name\":\"" + l.toString() + "\",");
-
- /*
- * Month names (both short and full)
- */
- final DateFormatSymbols dfs = new DateFormatSymbols(l);
- final String[] short_months = dfs.getShortMonths();
- final String[] months = dfs.getMonths();
- outWriter.print("\"smn\":[\""
- + // ShortMonthNames
- short_months[0] + "\",\"" + short_months[1] + "\",\""
- + short_months[2] + "\",\"" + short_months[3] + "\",\""
- + short_months[4] + "\",\"" + short_months[5] + "\",\""
- + short_months[6] + "\",\"" + short_months[7] + "\",\""
- + short_months[8] + "\",\"" + short_months[9] + "\",\""
- + short_months[10] + "\",\"" + short_months[11] + "\""
- + "],");
- outWriter.print("\"mn\":[\""
- + // MonthNames
- months[0] + "\",\"" + months[1] + "\",\"" + months[2]
- + "\",\"" + months[3] + "\",\"" + months[4] + "\",\""
- + months[5] + "\",\"" + months[6] + "\",\"" + months[7]
- + "\",\"" + months[8] + "\",\"" + months[9] + "\",\""
- + months[10] + "\",\"" + months[11] + "\"" + "],");
-
- /*
- * Weekday names (both short and full)
- */
- final String[] short_days = dfs.getShortWeekdays();
- final String[] days = dfs.getWeekdays();
- outWriter.print("\"sdn\":[\""
- + // ShortDayNames
- short_days[1] + "\",\"" + short_days[2] + "\",\""
- + short_days[3] + "\",\"" + short_days[4] + "\",\""
- + short_days[5] + "\",\"" + short_days[6] + "\",\""
- + short_days[7] + "\"" + "],");
- outWriter.print("\"dn\":[\""
- + // DayNames
- days[1] + "\",\"" + days[2] + "\",\"" + days[3] + "\",\""
- + days[4] + "\",\"" + days[5] + "\",\"" + days[6] + "\",\""
- + days[7] + "\"" + "],");
-
- /*
- * First day of week (0 = sunday, 1 = monday)
- */
- final Calendar cal = new GregorianCalendar(l);
- outWriter.print("\"fdow\":" + (cal.getFirstDayOfWeek() - 1) + ",");
-
- /*
- * Date formatting (MM/DD/YYYY etc.)
- */
-
- DateFormat dateFormat = DateFormat.getDateTimeInstance(
- DateFormat.SHORT, DateFormat.SHORT, l);
- if (!(dateFormat instanceof SimpleDateFormat)) {
- getLogger().warning(
- "Unable to get default date pattern for locale "
- + l.toString());
- dateFormat = new SimpleDateFormat();
- }
- final String df = ((SimpleDateFormat) dateFormat).toPattern();
-
- int timeStart = df.indexOf("H");
- if (timeStart < 0) {
- timeStart = df.indexOf("h");
- }
- final int ampm_first = df.indexOf("a");
- // E.g. in Korean locale AM/PM is before h:mm
- // TODO should take that into consideration on client-side as well,
- // now always h:mm a
- if (ampm_first > 0 && ampm_first < timeStart) {
- timeStart = ampm_first;
- }
- // Hebrew locale has time before the date
- final boolean timeFirst = timeStart == 0;
- String dateformat;
- if (timeFirst) {
- int dateStart = df.indexOf(' ');
- if (ampm_first > dateStart) {
- dateStart = df.indexOf(' ', ampm_first);
- }
- dateformat = df.substring(dateStart + 1);
- } else {
- dateformat = df.substring(0, timeStart - 1);
- }
-
- outWriter.print("\"df\":\"" + dateformat.trim() + "\",");
-
- /*
- * Time formatting (24 or 12 hour clock and AM/PM suffixes)
- */
- final String timeformat = df.substring(timeStart, df.length());
- /*
- * Doesn't return second or milliseconds.
- *
- * We use timeformat to determine 12/24-hour clock
- */
- final boolean twelve_hour_clock = timeformat.indexOf("a") > -1;
- // TODO there are other possibilities as well, like 'h' in french
- // (ignore them, too complicated)
- final String hour_min_delimiter = timeformat.indexOf(".") > -1 ? "."
- : ":";
- // outWriter.print("\"tf\":\"" + timeformat + "\",");
- outWriter.print("\"thc\":" + twelve_hour_clock + ",");
- outWriter.print("\"hmd\":\"" + hour_min_delimiter + "\"");
- if (twelve_hour_clock) {
- final String[] ampm = dfs.getAmPmStrings();
- outWriter.print(",\"ampm\":[\"" + ampm[0] + "\",\"" + ampm[1]
- + "\"]");
- }
- outWriter.print("}");
- if (pendingLocalesIndex < locales.size() - 1) {
- outWriter.print(",");
- }
- }
- outWriter.print("]"); // Close locales
- }
-
- /**
- * Ends the Application.
- *
- * The browser is redirected to the Application logout URL set with
- * {@link Application#setLogoutURL(String)}, or to the application URL if no
- * logout URL is given.
- *
- * @param request
- * the request instance.
- * @param response
- * the response to write to.
- * @param application
- * the Application to end.
- * @throws IOException
- * if the writing failed due to input/output error.
- */
- private void endApplication(WrappedRequest request,
- WrappedResponse response, Application application)
- throws IOException {
-
- String logoutUrl = application.getLogoutURL();
- if (logoutUrl == null) {
- logoutUrl = application.getURL().toString();
- }
- // clients JS app is still running, send a special json file to tell
- // client that application has quit and where to point browser now
- // Set the response type
- final OutputStream out = response.getOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
- openJsonMessage(outWriter, response);
- outWriter.print("\"redirect\":{");
- outWriter.write("\"url\":\"" + logoutUrl + "\"}");
- closeJsonMessage(outWriter);
- outWriter.flush();
- outWriter.close();
- out.flush();
- }
-
- protected void closeJsonMessage(PrintWriter outWriter) {
- outWriter.print("}]");
- }
-
- /**
- * Writes the opening of JSON message to be sent to client.
- *
- * @param outWriter
- * @param response
- */
- protected void openJsonMessage(PrintWriter outWriter,
- WrappedResponse response) {
- // Sets the response type
- response.setContentType("application/json; charset=UTF-8");
- // some dirt to prevent cross site scripting
- outWriter.print("for(;;);[{");
- }
-
- /**
- * Returns dirty components which are in given window. Components in an
- * invisible subtrees are omitted.
- *
- * @param w
- * root window for which dirty components is to be fetched
- * @return
- */
- private ArrayList<ClientConnector> getDirtyVisibleConnectors(
- ConnectorTracker connectorTracker) {
- ArrayList<ClientConnector> dirtyConnectors = new ArrayList<ClientConnector>();
- for (ClientConnector c : connectorTracker.getDirtyConnectors()) {
- if (isVisible(c)) {
- dirtyConnectors.add(c);
- }
- }
-
- return dirtyConnectors;
- }
-
- /**
- * Queues a locale to be sent to the client (browser) for date and time
- * entry etc. All locale specific information is derived from server-side
- * {@link Locale} instances and sent to the client when needed, eliminating
- * the need to use the {@link Locale} class and all the framework behind it
- * on the client.
- *
- * @see Locale#toString()
- *
- * @param value
- */
- public void requireLocale(String value) {
- if (locales == null) {
- locales = new ArrayList<String>();
- locales.add(application.getLocale().toString());
- pendingLocalesIndex = 0;
- }
- if (!locales.contains(value)) {
- locales.add(value);
- }
- }
-
- /**
- * Constructs a {@link Locale} instance to be sent to the client based on a
- * short locale description string.
- *
- * @see #requireLocale(String)
- *
- * @param value
- * @return
- */
- private Locale generateLocale(String value) {
- final String[] temp = value.split("_");
- if (temp.length == 1) {
- return new Locale(temp[0]);
- } else if (temp.length == 2) {
- return new Locale(temp[0], temp[1]);
- } else {
- return new Locale(temp[0], temp[1], temp[2]);
- }
- }
-
- protected class InvalidUIDLSecurityKeyException extends
- GeneralSecurityException {
-
- InvalidUIDLSecurityKeyException(String message) {
- super(message);
- }
-
- }
-
- private final HashMap<Class<? extends ClientConnector>, Integer> typeToKey = new HashMap<Class<? extends ClientConnector>, Integer>();
- private int nextTypeKey = 0;
-
- private BootstrapHandler bootstrapHandler;
-
- String getTagForType(Class<? extends ClientConnector> class1) {
- Integer id = typeToKey.get(class1);
- if (id == null) {
- id = nextTypeKey++;
- typeToKey.put(class1, id);
- getLogger().log(Level.FINE,
- "Mapping " + class1.getName() + " to " + id);
- }
- return id.toString();
- }
-
- /**
- * Helper class for terminal to keep track of data that client is expected
- * to know.
- *
- * TODO make customlayout templates (from theme) to be cached here.
- */
- class ClientCache implements Serializable {
-
- private final Set<Object> res = new HashSet<Object>();
-
- /**
- *
- * @param paintable
- * @return true if the given class was added to cache
- */
- boolean cache(Object object) {
- return res.add(object);
- }
-
- public void clear() {
- res.clear();
- }
-
- }
-
- public String getStreamVariableTargetUrl(ClientConnector owner,
- String name, StreamVariable value) {
- /*
- * We will use the same APP/* URI space as ApplicationResources but
- * prefix url with UPLOAD
- *
- * eg. APP/UPLOAD/[ROOTID]/[PID]/[NAME]/[SECKEY]
- *
- * SECKEY is created on each paint to make URL's unpredictable (to
- * prevent CSRF attacks).
- *
- * NAME and PID from URI forms a key to fetch StreamVariable when
- * handling post
- */
- String paintableId = owner.getConnectorId();
- int rootId = owner.getRoot().getRootId();
- String key = rootId + "/" + paintableId + "/" + name;
-
- if (pidToNameToStreamVariable == null) {
- pidToNameToStreamVariable = new HashMap<String, Map<String, StreamVariable>>();
- }
- Map<String, StreamVariable> nameToStreamVariable = pidToNameToStreamVariable
- .get(paintableId);
- if (nameToStreamVariable == null) {
- nameToStreamVariable = new HashMap<String, StreamVariable>();
- pidToNameToStreamVariable.put(paintableId, nameToStreamVariable);
- }
- nameToStreamVariable.put(name, value);
-
- if (streamVariableToSeckey == null) {
- streamVariableToSeckey = new HashMap<StreamVariable, String>();
- }
- String seckey = streamVariableToSeckey.get(value);
- if (seckey == null) {
- seckey = UUID.randomUUID().toString();
- streamVariableToSeckey.put(value, seckey);
- }
-
- return ApplicationConnection.APP_PROTOCOL_PREFIX
- + ServletPortletHelper.UPLOAD_URL_PREFIX + key + "/" + seckey;
-
- }
-
- public void cleanStreamVariable(ClientConnector owner, String name) {
- Map<String, StreamVariable> nameToStreamVar = pidToNameToStreamVariable
- .get(owner.getConnectorId());
- nameToStreamVar.remove(name);
- if (nameToStreamVar.isEmpty()) {
- pidToNameToStreamVariable.remove(owner.getConnectorId());
- }
- }
-
- /**
- * Gets the bootstrap handler that should be used for generating the pages
- * bootstrapping applications for this communication manager.
- *
- * @return the bootstrap handler to use
- */
- private BootstrapHandler getBootstrapHandler() {
- if (bootstrapHandler == null) {
- bootstrapHandler = createBootstrapHandler();
- }
-
- return bootstrapHandler;
- }
-
- protected abstract BootstrapHandler createBootstrapHandler();
-
- protected boolean handleApplicationRequest(WrappedRequest request,
- WrappedResponse response) throws IOException {
- return application.handleRequest(request, response);
- }
-
- public void handleBrowserDetailsRequest(WrappedRequest request,
- WrappedResponse response, Application application)
- throws IOException {
-
- // if we do not yet have a currentRoot, it should be initialized
- // shortly, and we should send the initial UIDL
- boolean sendUIDL = Root.getCurrent() == null;
-
- try {
- CombinedRequest combinedRequest = new CombinedRequest(request);
-
- Root root = application.getRootForRequest(combinedRequest);
- response.setContentType("application/json; charset=UTF-8");
-
- // Use the same logic as for determined roots
- BootstrapHandler bootstrapHandler = getBootstrapHandler();
- BootstrapContext context = bootstrapHandler.createContext(
- combinedRequest, response, application, root.getRootId());
-
- String widgetset = context.getWidgetsetName();
- String theme = context.getThemeName();
- String themeUri = bootstrapHandler.getThemeUri(context, theme);
-
- // TODO These are not required if it was only the init of the root
- // that was delayed
- JSONObject params = new JSONObject();
- params.put("widgetset", widgetset);
- params.put("themeUri", themeUri);
- // Root id might have changed based on e.g. window.name
- params.put(ApplicationConnection.ROOT_ID_PARAMETER,
- root.getRootId());
- if (sendUIDL) {
- String initialUIDL = getInitialUIDL(combinedRequest, root);
- params.put("uidl", initialUIDL);
- }
-
- // NOTE! GateIn requires, for some weird reason, getOutputStream
- // to be used instead of getWriter() (it seems to interpret
- // application/json as a binary content type)
- final OutputStream out = response.getOutputStream();
- final PrintWriter outWriter = new PrintWriter(new BufferedWriter(
- new OutputStreamWriter(out, "UTF-8")));
-
- outWriter.write(params.toString());
- // NOTE GateIn requires the buffers to be flushed to work
- outWriter.flush();
- out.flush();
- } catch (RootRequiresMoreInformationException e) {
- // Requiring more information at this point is not allowed
- // TODO handle in a better way
- throw new RuntimeException(e);
- } catch (JSONException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- /**
- * Generates the initial UIDL message that can e.g. be included in a html
- * page to avoid a separate round trip just for getting the UIDL.
- *
- * @param request
- * the request that caused the initialization
- * @param root
- * the root for which the UIDL should be generated
- * @return a string with the initial UIDL message
- * @throws PaintException
- * if an exception occurs while painting
- * @throws JSONException
- * if an exception occurs while encoding output
- */
- protected String getInitialUIDL(WrappedRequest request, Root root)
- throws PaintException, JSONException {
- // TODO maybe unify writeUidlResponse()?
- StringWriter sWriter = new StringWriter();
- PrintWriter pWriter = new PrintWriter(sWriter);
- pWriter.print("{");
- if (isXSRFEnabled(root.getApplication())) {
- pWriter.print(getSecurityKeyUIDL(request));
- }
- writeUidlResponse(request, true, pWriter, root, false);
- pWriter.print("}");
- String initialUIDL = sWriter.toString();
- getLogger().log(Level.FINE, "Initial UIDL:" + initialUIDL);
- return initialUIDL;
- }
-
- /**
- * Serve a connector resource from the classpath if the resource has
- * previously been registered by calling
- * {@link #registerResource(String, Class)}. Sending arbitrary files from
- * the classpath is prevented by only accepting resource names that have
- * explicitly been registered. Resources can currently only be registered by
- * including a {@link JavaScript} or {@link StyleSheet} annotation on a
- * Connector class.
- *
- * @param request
- * @param response
- *
- * @throws IOException
- */
- public void serveConnectorResource(WrappedRequest request,
- WrappedResponse response) throws IOException {
-
- String pathInfo = request.getRequestPathInfo();
- // + 2 to also remove beginning and ending slashes
- String resourceName = pathInfo
- .substring(ApplicationConnection.CONNECTOR_RESOURCE_PREFIX
- .length() + 2);
-
- final String mimetype = response.getDeploymentConfiguration()
- .getMimeType(resourceName);
-
- // Security check: avoid accidentally serving from the root of the
- // classpath instead of relative to the context class
- if (resourceName.startsWith("/")) {
- getLogger().warning(
- "Connector resource request starting with / rejected: "
- + resourceName);
- response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
- return;
- }
-
- // Check that the resource name has been registered
- Class<?> context;
- synchronized (connectorResourceContexts) {
- context = connectorResourceContexts.get(resourceName);
- }
-
- // Security check: don't serve resource if the name hasn't been
- // registered in the map
- if (context == null) {
- getLogger().warning(
- "Connector resource request for unknown resource rejected: "
- + resourceName);
- response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
- return;
- }
-
- // Resolve file relative to the location of the context class
- InputStream in = context.getResourceAsStream(resourceName);
- if (in == null) {
- getLogger().warning(
- resourceName + " defined by " + context.getName()
- + " not found. Verify that the file "
- + context.getPackage().getName().replace('.', '/')
- + '/' + resourceName
- + " is available on the classpath.");
- response.sendError(HttpServletResponse.SC_NOT_FOUND, resourceName);
- return;
- }
-
- // TODO Check and set cache headers
-
- OutputStream out = null;
- try {
- if (mimetype != null) {
- response.setContentType(mimetype);
- }
-
- out = response.getOutputStream();
-
- final byte[] buffer = new byte[Constants.DEFAULT_BUFFER_SIZE];
-
- int bytesRead = 0;
- while ((bytesRead = in.read(buffer)) > 0) {
- out.write(buffer, 0, bytesRead);
- }
- out.flush();
- } finally {
- try {
- in.close();
- } catch (Exception e) {
- // Do nothing
- }
- if (out != null) {
- try {
- out.close();
- } catch (Exception e) {
- // Do nothing
- }
- }
- }
- }
-
- /**
- * Handles file upload request submitted via Upload component.
- *
- * @param root
- * The root for this request
- *
- * @see #getStreamVariableTargetUrl(ReceiverOwner, String, StreamVariable)
- *
- * @param request
- * @param response
- * @throws IOException
- * @throws InvalidUIDLSecurityKeyException
- */
- public void handleFileUpload(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException, InvalidUIDLSecurityKeyException {
-
- /*
- * URI pattern: APP/UPLOAD/[ROOTID]/[PID]/[NAME]/[SECKEY] See
- * #createReceiverUrl
- */
-
- String pathInfo = request.getRequestPathInfo();
- // strip away part until the data we are interested starts
- int startOfData = pathInfo
- .indexOf(ServletPortletHelper.UPLOAD_URL_PREFIX)
- + ServletPortletHelper.UPLOAD_URL_PREFIX.length();
- String uppUri = pathInfo.substring(startOfData);
- String[] parts = uppUri.split("/", 4); // 0= rootid, 1 = cid, 2= name, 3
- // = sec key
- String rootId = parts[0];
- String connectorId = parts[1];
- String variableName = parts[2];
- Root root = application.getRootById(Integer.parseInt(rootId));
- Root.setCurrent(root);
-
- StreamVariable streamVariable = getStreamVariable(connectorId,
- variableName);
- String secKey = streamVariableToSeckey.get(streamVariable);
- if (secKey.equals(parts[3])) {
-
- ClientConnector source = getConnector(root, connectorId);
- String contentType = request.getContentType();
- if (contentType.contains("boundary")) {
- // Multipart requests contain boundary string
- doHandleSimpleMultipartFileUpload(request, response,
- streamVariable, variableName, source,
- contentType.split("boundary=")[1]);
- } else {
- // if boundary string does not exist, the posted file is from
- // XHR2.post(File)
- doHandleXhrFilePost(request, response, streamVariable,
- variableName, source, request.getContentLength());
- }
- } else {
- throw new InvalidUIDLSecurityKeyException(
- "Security key in upload post did not match!");
- }
-
- }
-
- public StreamVariable getStreamVariable(String connectorId,
- String variableName) {
- Map<String, StreamVariable> map = pidToNameToStreamVariable
- .get(connectorId);
- if (map == null) {
- return null;
- }
- StreamVariable streamVariable = map.get(variableName);
- return streamVariable;
- }
-
- /**
- * Stream that extracts content from another stream until the boundary
- * string is encountered.
- *
- * Public only for unit tests, should be considered private for all other
- * purposes.
- */
- public static class SimpleMultiPartInputStream extends InputStream {
-
- /**
- * Counter of how many characters have been matched to boundary string
- * from the stream
- */
- int matchedCount = -1;
-
- /**
- * Used as pointer when returning bytes after partly matched boundary
- * string.
- */
- int curBoundaryIndex = 0;
- /**
- * The byte found after a "promising start for boundary"
- */
- private int bufferedByte = -1;
- private boolean atTheEnd = false;
-
- private final char[] boundary;
-
- private final InputStream realInputStream;
-
- public SimpleMultiPartInputStream(InputStream realInputStream,
- String boundaryString) {
- boundary = (CRLF + DASHDASH + boundaryString).toCharArray();
- this.realInputStream = realInputStream;
- }
-
- @Override
- public int read() throws IOException {
- if (atTheEnd) {
- // End boundary reached, nothing more to read
- return -1;
- } else if (bufferedByte >= 0) {
- /* Purge partially matched boundary if there was such */
- return getBuffered();
- } else if (matchedCount != -1) {
- /*
- * Special case where last "failed" matching ended with first
- * character from boundary string
- */
- return matchForBoundary();
- } else {
- int fromActualStream = realInputStream.read();
- if (fromActualStream == -1) {
- // unexpected end of stream
- throw new IOException(
- "The multipart stream ended unexpectedly");
- }
- if (boundary[0] == fromActualStream) {
- /*
- * If matches the first character in boundary string, start
- * checking if the boundary is fetched.
- */
- return matchForBoundary();
- }
- return fromActualStream;
- }
- }
-
- /**
- * Reads the input to expect a boundary string. Expects that the first
- * character has already been matched.
- *
- * @return -1 if the boundary was matched, else returns the first byte
- * from boundary
- * @throws IOException
- */
- private int matchForBoundary() throws IOException {
- matchedCount = 0;
- /*
- * Going to "buffered mode". Read until full boundary match or a
- * different character.
- */
- while (true) {
- matchedCount++;
- if (matchedCount == boundary.length) {
- /*
- * The whole boundary matched so we have reached the end of
- * file
- */
- atTheEnd = true;
- return -1;
- }
- int fromActualStream = realInputStream.read();
- if (fromActualStream != boundary[matchedCount]) {
- /*
- * Did not find full boundary, cache the mismatching byte
- * and start returning the partially matched boundary.
- */
- bufferedByte = fromActualStream;
- return getBuffered();
- }
- }
- }
-
- /**
- * Returns the partly matched boundary string and the byte following
- * that.
- *
- * @return
- * @throws IOException
- */
- private int getBuffered() throws IOException {
- int b;
- if (matchedCount == 0) {
- // The boundary has been returned, return the buffered byte.
- b = bufferedByte;
- bufferedByte = -1;
- matchedCount = -1;
- } else {
- b = boundary[curBoundaryIndex++];
- if (curBoundaryIndex == matchedCount) {
- // The full boundary has been returned, remaining is the
- // char that did not match the boundary.
-
- curBoundaryIndex = 0;
- if (bufferedByte != boundary[0]) {
- /*
- * next call for getBuffered will return the
- * bufferedByte that came after the partial boundary
- * match
- */
- matchedCount = 0;
- } else {
- /*
- * Special case where buffered byte again matches the
- * boundaryString. This could be the start of the real
- * end boundary.
- */
- matchedCount = 0;
- bufferedByte = -1;
- }
- }
- }
- if (b == -1) {
- throw new IOException("The multipart stream ended unexpectedly");
- }
- return b;
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(AbstractCommunicationManager.class.getName());
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java b/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java
deleted file mode 100644
index 7b51712904..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.lang.reflect.Constructor;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.ServiceLoader;
-
-import com.vaadin.terminal.DeploymentConfiguration;
-
-public abstract class AbstractDeploymentConfiguration implements
- DeploymentConfiguration {
-
- private final Class<?> systemPropertyBaseClass;
- private final Properties applicationProperties = new Properties();
- private AddonContext addonContext;
-
- public AbstractDeploymentConfiguration(Class<?> systemPropertyBaseClass) {
- this.systemPropertyBaseClass = systemPropertyBaseClass;
- }
-
- @Override
- public String getApplicationOrSystemProperty(String propertyName,
- String defaultValue) {
-
- String val = null;
-
- // Try application properties
- val = getApplicationProperty(propertyName);
- if (val != null) {
- return val;
- }
-
- // Try system properties
- val = getSystemProperty(propertyName);
- if (val != null) {
- return val;
- }
-
- return defaultValue;
- }
-
- /**
- * Gets an system property value.
- *
- * @param parameterName
- * the Name or the parameter.
- * @return String value or null if not found
- */
- protected String getSystemProperty(String parameterName) {
- String val = null;
-
- String pkgName;
- final Package pkg = systemPropertyBaseClass.getPackage();
- if (pkg != null) {
- pkgName = pkg.getName();
- } else {
- final String className = systemPropertyBaseClass.getName();
- pkgName = new String(className.toCharArray(), 0,
- className.lastIndexOf('.'));
- }
- val = System.getProperty(pkgName + "." + parameterName);
- if (val != null) {
- return val;
- }
-
- // Try lowercased system properties
- val = System.getProperty(pkgName + "." + parameterName.toLowerCase());
- return val;
- }
-
- @Override
- public ClassLoader getClassLoader() {
- final String classLoaderName = getApplicationOrSystemProperty(
- "ClassLoader", null);
- ClassLoader classLoader;
- if (classLoaderName == null) {
- classLoader = getClass().getClassLoader();
- } else {
- try {
- final Class<?> classLoaderClass = getClass().getClassLoader()
- .loadClass(classLoaderName);
- final Constructor<?> c = classLoaderClass
- .getConstructor(new Class[] { ClassLoader.class });
- classLoader = (ClassLoader) c
- .newInstance(new Object[] { getClass().getClassLoader() });
- } catch (final Exception e) {
- throw new RuntimeException(
- "Could not find specified class loader: "
- + classLoaderName, e);
- }
- }
- return classLoader;
- }
-
- /**
- * Gets an application property value.
- *
- * @param parameterName
- * the Name or the parameter.
- * @return String value or null if not found
- */
- protected String getApplicationProperty(String parameterName) {
-
- String val = applicationProperties.getProperty(parameterName);
- if (val != null) {
- return val;
- }
-
- // Try lower case application properties for backward compatibility with
- // 3.0.2 and earlier
- val = applicationProperties.getProperty(parameterName.toLowerCase());
-
- return val;
- }
-
- @Override
- public Properties getInitParameters() {
- return applicationProperties;
- }
-
- @Override
- public Iterator<AddonContextListener> getAddonContextListeners() {
- // Called once for init and then no more, so there's no point in caching
- // the instance
- ServiceLoader<AddonContextListener> contextListenerLoader = ServiceLoader
- .load(AddonContextListener.class, getClassLoader());
- return contextListenerLoader.iterator();
- }
-
- @Override
- public void setAddonContext(AddonContext addonContext) {
- this.addonContext = addonContext;
- }
-
- @Override
- public AddonContext getAddonContext() {
- return addonContext;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractStreamingEvent.java b/src/com/vaadin/terminal/gwt/server/AbstractStreamingEvent.java
deleted file mode 100644
index d3474e736e..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractStreamingEvent.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.terminal.StreamVariable.StreamingEvent;
-
-/**
- * Abstract base class for StreamingEvent implementations.
- */
-@SuppressWarnings("serial")
-abstract class AbstractStreamingEvent implements StreamingEvent {
- private final String type;
- private final String filename;
- private final long contentLength;
- private final long bytesReceived;
-
- @Override
- public final String getFileName() {
- return filename;
- }
-
- @Override
- public final String getMimeType() {
- return type;
- }
-
- protected AbstractStreamingEvent(String filename, String type, long length,
- long bytesReceived) {
- this.filename = filename;
- this.type = type;
- contentLength = length;
- this.bytesReceived = bytesReceived;
- }
-
- @Override
- public final long getContentLength() {
- return contentLength;
- }
-
- @Override
- public final long getBytesReceived() {
- return bytesReceived;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java b/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java
deleted file mode 100644
index 3a33621d10..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-
-import com.vaadin.Application;
-import com.vaadin.service.ApplicationContext;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-
-/**
- * Base class for web application contexts (including portlet contexts) that
- * handles the common tasks.
- */
-public abstract class AbstractWebApplicationContext implements
- ApplicationContext, HttpSessionBindingListener, Serializable {
-
- protected Collection<TransactionListener> listeners = Collections
- .synchronizedList(new LinkedList<TransactionListener>());
-
- protected final HashSet<Application> applications = new HashSet<Application>();
-
- protected WebBrowser browser = new WebBrowser();
-
- protected HashMap<Application, AbstractCommunicationManager> applicationToAjaxAppMgrMap = new HashMap<Application, AbstractCommunicationManager>();
-
- private long totalSessionTime = 0;
-
- private long lastRequestTime = -1;
-
- @Override
- public void addTransactionListener(TransactionListener listener) {
- if (listener != null) {
- listeners.add(listener);
- }
- }
-
- @Override
- public void removeTransactionListener(TransactionListener listener) {
- listeners.remove(listener);
- }
-
- /**
- * Sends a notification that a transaction is starting.
- *
- * @param application
- * The application associated with the transaction.
- * @param request
- * the HTTP or portlet request that triggered the transaction.
- */
- protected void startTransaction(Application application, Object request) {
- ArrayList<TransactionListener> currentListeners;
- synchronized (listeners) {
- currentListeners = new ArrayList<TransactionListener>(listeners);
- }
- for (TransactionListener listener : currentListeners) {
- listener.transactionStart(application, request);
- }
- }
-
- /**
- * Sends a notification that a transaction has ended.
- *
- * @param application
- * The application associated with the transaction.
- * @param request
- * the HTTP or portlet request that triggered the transaction.
- */
- protected void endTransaction(Application application, Object request) {
- LinkedList<Exception> exceptions = null;
-
- ArrayList<TransactionListener> currentListeners;
- synchronized (listeners) {
- currentListeners = new ArrayList<TransactionListener>(listeners);
- }
-
- for (TransactionListener listener : currentListeners) {
- try {
- listener.transactionEnd(application, request);
- } catch (final RuntimeException t) {
- if (exceptions == null) {
- exceptions = new LinkedList<Exception>();
- }
- exceptions.add(t);
- }
- }
-
- // If any runtime exceptions occurred, throw a combined exception
- if (exceptions != null) {
- final StringBuffer msg = new StringBuffer();
- for (Exception e : exceptions) {
- if (msg.length() == 0) {
- msg.append("\n\n--------------------------\n\n");
- }
- msg.append(e.getMessage() + "\n");
- final StringWriter trace = new StringWriter();
- e.printStackTrace(new PrintWriter(trace, true));
- msg.append(trace.toString());
- }
- throw new RuntimeException(msg.toString());
- }
- }
-
- /**
- * @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)
- */
- @Override
- public void valueBound(HttpSessionBindingEvent arg0) {
- // We are not interested in bindings
- }
-
- /**
- * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(HttpSessionBindingEvent)
- */
- @Override
- public void valueUnbound(HttpSessionBindingEvent event) {
- // If we are going to be unbound from the session, the session must be
- // closing
- try {
- while (!applications.isEmpty()) {
- final Application app = applications.iterator().next();
- app.close();
- removeApplication(app);
- }
- } catch (Exception e) {
- // This should never happen but is possible with rare
- // configurations (e.g. robustness tests). If you have one
- // thread doing HTTP socket write and another thread trying to
- // remove same application here. Possible if you got e.g. session
- // lifetime 1 min but socket write may take longer than 1 min.
- // FIXME: Handle exception
- getLogger().log(Level.SEVERE,
- "Could not remove application, leaking memory.", e);
- }
- }
-
- /**
- * Get the web browser associated with this application context.
- *
- * Because application context is related to the http session and server
- * maintains one session per browser-instance, each context has exactly one
- * web browser associated with it.
- *
- * @return
- */
- public WebBrowser getBrowser() {
- return browser;
- }
-
- @Override
- public Collection<Application> getApplications() {
- return Collections.unmodifiableCollection(applications);
- }
-
- protected void removeApplication(Application application) {
- applications.remove(application);
- applicationToAjaxAppMgrMap.remove(application);
- }
-
- @Override
- public String generateApplicationResourceURL(ApplicationResource resource,
- String mapKey) {
-
- final String filename = resource.getFilename();
- if (filename == null) {
- return ApplicationConnection.APP_PROTOCOL_PREFIX
- + ApplicationConnection.APP_REQUEST_PATH + mapKey + "/";
- } else {
- // #7738 At least Tomcat and JBoss refuses requests containing
- // encoded slashes or backslashes in URLs. Application resource URLs
- // should really be passed in another way than as part of the path
- // in the future.
- String encodedFileName = urlEncode(filename).replace("%2F", "/")
- .replace("%5C", "\\");
- return ApplicationConnection.APP_PROTOCOL_PREFIX
- + ApplicationConnection.APP_REQUEST_PATH + mapKey + "/"
- + encodedFileName;
- }
-
- }
-
- static String urlEncode(String filename) {
- try {
- return URLEncoder.encode(filename, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(
- "UTF-8 charset not available (\"this should never happen\")",
- e);
- }
- }
-
- @Override
- public boolean isApplicationResourceURL(URL context, String relativeUri) {
- // If the relative uri is null, we are ready
- if (relativeUri == null) {
- return false;
- }
-
- // Resolves the prefix
- String prefix = relativeUri;
- final int index = relativeUri.indexOf('/');
- if (index >= 0) {
- prefix = relativeUri.substring(0, index);
- }
-
- // Handles the resource requests
- return (prefix.equals("APP"));
- }
-
- @Override
- public String getURLKey(URL context, String relativeUri) {
- final int index = relativeUri.indexOf('/');
- final int next = relativeUri.indexOf('/', index + 1);
- if (next < 0) {
- return null;
- }
- return relativeUri.substring(index + 1, next);
- }
-
- /**
- * @return The total time spent servicing requests in this session.
- */
- public long getTotalSessionTime() {
- return totalSessionTime;
- }
-
- /**
- * Sets the time spent servicing the last request in the session and updates
- * the total time spent servicing requests in this session.
- *
- * @param time
- * the time spent in the last request.
- */
- public void setLastRequestTime(long time) {
- lastRequestTime = time;
- totalSessionTime += time;
- }
-
- /**
- * @return the time spent servicing the last request in this session.
- */
- public long getLastRequestTime() {
- return lastRequestTime;
- }
-
- private Logger getLogger() {
- return Logger.getLogger(AbstractWebApplicationContext.class.getName());
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/AddonContext.java b/src/com/vaadin/terminal/gwt/server/AddonContext.java
deleted file mode 100644
index 41e9046e22..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AddonContext.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import com.vaadin.Application;
-import com.vaadin.event.EventRouter;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.tools.ReflectTools;
-
-public class AddonContext {
- private static final Method APPLICATION_STARTED_METHOD = ReflectTools
- .findMethod(ApplicationStartedListener.class, "applicationStarted",
- ApplicationStartedEvent.class);
-
- private final DeploymentConfiguration deploymentConfiguration;
-
- private final EventRouter eventRouter = new EventRouter();
-
- private List<BootstrapListener> bootstrapListeners = new ArrayList<BootstrapListener>();
-
- private List<AddonContextListener> initedListeners = new ArrayList<AddonContextListener>();
-
- public AddonContext(DeploymentConfiguration deploymentConfiguration) {
- this.deploymentConfiguration = deploymentConfiguration;
- deploymentConfiguration.setAddonContext(this);
- }
-
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- public void init() {
- AddonContextEvent event = new AddonContextEvent(this);
- Iterator<AddonContextListener> listeners = deploymentConfiguration
- .getAddonContextListeners();
- while (listeners.hasNext()) {
- AddonContextListener listener = listeners.next();
- listener.contextCreated(event);
- initedListeners.add(listener);
- }
- }
-
- public void destroy() {
- AddonContextEvent event = new AddonContextEvent(this);
- for (AddonContextListener listener : initedListeners) {
- listener.contextDestoryed(event);
- }
- }
-
- public void addBootstrapListener(BootstrapListener listener) {
- bootstrapListeners.add(listener);
- }
-
- public void applicationStarted(Application application) {
- eventRouter.fireEvent(new ApplicationStartedEvent(this, application));
- for (BootstrapListener l : bootstrapListeners) {
- application.addBootstrapListener(l);
- }
- }
-
- public void addApplicationStartedListener(
- ApplicationStartedListener applicationStartListener) {
- eventRouter.addListener(ApplicationStartedEvent.class,
- applicationStartListener, APPLICATION_STARTED_METHOD);
- }
-
- public void removeApplicationStartedListener(
- ApplicationStartedListener applicationStartListener) {
- eventRouter.removeListener(ApplicationStartedEvent.class,
- applicationStartListener, APPLICATION_STARTED_METHOD);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AddonContextEvent.java b/src/com/vaadin/terminal/gwt/server/AddonContextEvent.java
deleted file mode 100644
index 33f681499f..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AddonContextEvent.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventObject;
-
-public class AddonContextEvent extends EventObject {
-
- public AddonContextEvent(AddonContext source) {
- super(source);
- }
-
- public AddonContext getAddonContext() {
- return (AddonContext) getSource();
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/AddonContextListener.java b/src/com/vaadin/terminal/gwt/server/AddonContextListener.java
deleted file mode 100644
index 93e7df4ede..0000000000
--- a/src/com/vaadin/terminal/gwt/server/AddonContextListener.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventListener;
-
-public interface AddonContextListener extends EventListener {
- public void contextCreated(AddonContextEvent event);
-
- public void contextDestoryed(AddonContextEvent event);
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java b/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java
deleted file mode 100644
index 788c48267e..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import javax.portlet.PortletConfig;
-import javax.portlet.PortletException;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.gwt.server.ServletPortletHelper.ApplicationClassException;
-
-/**
- * TODO Write documentation, fix JavaDoc tags.
- *
- * @author peholmst
- */
-public class ApplicationPortlet2 extends AbstractApplicationPortlet {
-
- private Class<? extends Application> applicationClass;
-
- @Override
- public void init(PortletConfig config) throws PortletException {
- super.init(config);
- try {
- applicationClass = ServletPortletHelper
- .getApplicationClass(getDeploymentConfiguration());
- } catch (ApplicationClassException e) {
- throw new PortletException(e);
- }
- }
-
- @Override
- protected Class<? extends Application> getApplicationClass() {
- return applicationClass;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationResourceHandler.java b/src/com/vaadin/terminal/gwt/server/ApplicationResourceHandler.java
deleted file mode 100644
index 42726c933e..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ApplicationResourceHandler.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.servlet.http.HttpServletResponse;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.DownloadStream;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-
-public class ApplicationResourceHandler implements RequestHandler {
- private static final Pattern APP_RESOURCE_PATTERN = Pattern
- .compile("^/?APP/(\\d+)/.*");
-
- @Override
- public boolean handleRequest(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException {
- // Check for application resources
- String requestPath = request.getRequestPathInfo();
- if (requestPath == null) {
- return false;
- }
- Matcher resourceMatcher = APP_RESOURCE_PATTERN.matcher(requestPath);
-
- if (resourceMatcher.matches()) {
- ApplicationResource resource = application
- .getResource(resourceMatcher.group(1));
- if (resource != null) {
- DownloadStream stream = resource.getStream();
- if (stream != null) {
- stream.setCacheTime(resource.getCacheTime());
- stream.writeTo(response);
- return true;
- }
- }
- // We get here if the url looks like an application resource but no
- // resource can be served
- response.sendError(HttpServletResponse.SC_NOT_FOUND,
- request.getRequestPathInfo() + " can not be found");
- return true;
- }
-
- return false;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/ApplicationServlet.java
deleted file mode 100644
index 1af49e0da0..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ApplicationServlet.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.gwt.server.ServletPortletHelper.ApplicationClassException;
-
-/**
- * This servlet connects a Vaadin Application to Web.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-
-@SuppressWarnings("serial")
-public class ApplicationServlet extends AbstractApplicationServlet {
-
- // Private fields
- private Class<? extends Application> applicationClass;
-
- /**
- * Called by the servlet container to indicate to a servlet that the servlet
- * is being placed into service.
- *
- * @param servletConfig
- * the object containing the servlet's configuration and
- * initialization parameters
- * @throws javax.servlet.ServletException
- * if an exception has occurred that interferes with the
- * servlet's normal operation.
- */
- @Override
- public void init(javax.servlet.ServletConfig servletConfig)
- throws javax.servlet.ServletException {
- super.init(servletConfig);
-
- // Loads the application class using the classloader defined in the
- // deployment configuration
-
- try {
- applicationClass = ServletPortletHelper
- .getApplicationClass(getDeploymentConfiguration());
- } catch (ApplicationClassException e) {
- throw new ServletException(e);
- }
- }
-
- @Override
- protected Application getNewApplication(HttpServletRequest request)
- throws ServletException {
-
- // Creates a new application instance
- try {
- final Application application = getApplicationClass().newInstance();
-
- return application;
- } catch (final IllegalAccessException e) {
- throw new ServletException("getNewApplication failed", e);
- } catch (final InstantiationException e) {
- throw new ServletException("getNewApplication failed", e);
- } catch (ClassNotFoundException e) {
- throw new ServletException("getNewApplication failed", e);
- }
- }
-
- @Override
- protected Class<? extends Application> getApplicationClass()
- throws ClassNotFoundException {
- return applicationClass;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationStartedEvent.java b/src/com/vaadin/terminal/gwt/server/ApplicationStartedEvent.java
deleted file mode 100644
index 339b88222e..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ApplicationStartedEvent.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventObject;
-
-import com.vaadin.Application;
-
-public class ApplicationStartedEvent extends EventObject {
- private final Application application;
-
- public ApplicationStartedEvent(AddonContext context,
- Application application) {
- super(context);
- this.application = application;
- }
-
- public AddonContext getContext() {
- return (AddonContext) getSource();
- }
-
- public Application getApplication() {
- return application;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationStartedListener.java b/src/com/vaadin/terminal/gwt/server/ApplicationStartedListener.java
deleted file mode 100644
index 87884a0fda..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ApplicationStartedListener.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventListener;
-
-public interface ApplicationStartedListener extends EventListener {
- public void applicationStarted(ApplicationStartedEvent event);
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapDom.java b/src/com/vaadin/terminal/gwt/server/BootstrapDom.java
deleted file mode 100644
index 4731a5b79f..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapDom.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-public class BootstrapDom {
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapFragmentResponse.java b/src/com/vaadin/terminal/gwt/server/BootstrapFragmentResponse.java
deleted file mode 100644
index bcf098b5aa..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapFragmentResponse.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.List;
-
-import org.jsoup.nodes.Node;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.WrappedRequest;
-
-public class BootstrapFragmentResponse extends BootstrapResponse {
- private final List<Node> fragmentNodes;
-
- public BootstrapFragmentResponse(BootstrapHandler handler,
- WrappedRequest request, List<Node> fragmentNodes,
- Application application, Integer rootId) {
- super(handler, request, application, rootId);
- this.fragmentNodes = fragmentNodes;
- }
-
- public List<Node> getFragmentNodes() {
- return fragmentNodes;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java b/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java
deleted file mode 100644
index e89737337b..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.jsoup.nodes.DataNode;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.DocumentType;
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-import org.jsoup.parser.Tag;
-
-import com.vaadin.Application;
-import com.vaadin.RootRequiresMoreInformationException;
-import com.vaadin.Version;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.external.json.JSONObject;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.ui.Root;
-
-public abstract class BootstrapHandler implements RequestHandler {
-
- protected class BootstrapContext implements Serializable {
-
- private final WrappedResponse response;
- private final BootstrapFragmentResponse bootstrapResponse;
-
- private String widgetsetName;
- private String themeName;
- private String appId;
-
- public BootstrapContext(WrappedResponse response,
- BootstrapFragmentResponse bootstrapResponse) {
- this.response = response;
- this.bootstrapResponse = bootstrapResponse;
- }
-
- public WrappedResponse getResponse() {
- return response;
- }
-
- public WrappedRequest getRequest() {
- return bootstrapResponse.getRequest();
- }
-
- public Application getApplication() {
- return bootstrapResponse.getApplication();
- }
-
- public Integer getRootId() {
- return bootstrapResponse.getRootId();
- }
-
- public Root getRoot() {
- return bootstrapResponse.getRoot();
- }
-
- public String getWidgetsetName() {
- if (widgetsetName == null) {
- Root root = getRoot();
- if (root != null) {
- widgetsetName = getWidgetsetForRoot(this);
- }
- }
- return widgetsetName;
- }
-
- public String getThemeName() {
- if (themeName == null) {
- Root root = getRoot();
- if (root != null) {
- themeName = findAndEscapeThemeName(this);
- }
- }
- return themeName;
- }
-
- public String getAppId() {
- if (appId == null) {
- appId = getApplicationId(this);
- }
- return appId;
- }
-
- public BootstrapFragmentResponse getBootstrapResponse() {
- return bootstrapResponse;
- }
-
- }
-
- @Override
- public boolean handleRequest(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException {
-
- // TODO Should all urls be handled here?
- Integer rootId = null;
- try {
- Root root = application.getRootForRequest(request);
- if (root == null) {
- writeError(response, new Throwable("No Root found"));
- return true;
- }
-
- rootId = Integer.valueOf(root.getRootId());
- } catch (RootRequiresMoreInformationException e) {
- // Just keep going without rootId
- }
-
- try {
- BootstrapContext context = createContext(request, response,
- application, rootId);
- setupMainDiv(context);
-
- BootstrapFragmentResponse fragmentResponse = context
- .getBootstrapResponse();
- application.modifyBootstrapResponse(fragmentResponse);
-
- String html = getBootstrapHtml(context);
-
- writeBootstrapPage(response, html);
- } catch (JSONException e) {
- writeError(response, e);
- }
-
- return true;
- }
-
- private String getBootstrapHtml(BootstrapContext context) {
- WrappedRequest request = context.getRequest();
- WrappedResponse response = context.getResponse();
- DeploymentConfiguration deploymentConfiguration = request
- .getDeploymentConfiguration();
-
- BootstrapFragmentResponse fragmentResponse = context
- .getBootstrapResponse();
-
- if (deploymentConfiguration.isStandalone(request)) {
- Map<String, Object> headers = new LinkedHashMap<String, Object>();
- Document document = Document.createShell("");
- BootstrapPageResponse pageResponse = new BootstrapPageResponse(
- this, request, document, headers, context.getApplication(),
- context.getRootId());
- List<Node> fragmentNodes = fragmentResponse.getFragmentNodes();
- Element body = document.body();
- for (Node node : fragmentNodes) {
- body.appendChild(node);
- }
-
- setupStandaloneDocument(context, pageResponse);
- context.getApplication().modifyBootstrapResponse(pageResponse);
-
- sendBootstrapHeaders(response, headers);
-
- return document.outerHtml();
- } else {
- StringBuilder sb = new StringBuilder();
- for (Node node : fragmentResponse.getFragmentNodes()) {
- if (sb.length() != 0) {
- sb.append('\n');
- }
- sb.append(node.outerHtml());
- }
-
- return sb.toString();
- }
- }
-
- private void sendBootstrapHeaders(WrappedResponse response,
- Map<String, Object> headers) {
- Set<Entry<String, Object>> entrySet = headers.entrySet();
- for (Entry<String, Object> header : entrySet) {
- Object value = header.getValue();
- if (value instanceof String) {
- response.setHeader(header.getKey(), (String) value);
- } else if (value instanceof Long) {
- response.setDateHeader(header.getKey(),
- ((Long) value).longValue());
- } else {
- throw new RuntimeException("Unsupported header value: " + value);
- }
- }
- }
-
- private void writeBootstrapPage(WrappedResponse response, String html)
- throws IOException {
- response.setContentType("text/html");
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
- response.getOutputStream(), "UTF-8"));
- writer.append(html);
- writer.close();
- }
-
- private void setupStandaloneDocument(BootstrapContext context,
- BootstrapPageResponse response) {
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
- response.setDateHeader("Expires", 0);
-
- Document document = response.getDocument();
-
- DocumentType doctype = new DocumentType("html",
- "-//W3C//DTD XHTML 1.0 Transitional//EN",
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
- document.baseUri());
- document.child(0).before(doctype);
- document.body().parent().attr("xmlns", "http://www.w3.org/1999/xhtml");
-
- Element head = document.head();
- head.appendElement("meta").attr("http-equiv", "Content-Type")
- .attr("content", "text/html; charset=utf-8");
-
- // Chrome frame in all versions of IE (only if Chrome frame is
- // installed)
- head.appendElement("meta").attr("http-equiv", "X-UA-Compatible")
- .attr("content", "chrome=1");
-
- Root root = context.getRoot();
- String title = ((root == null || root.getCaption() == null) ? "" : root
- .getCaption());
- head.appendElement("title").appendText(title);
-
- head.appendElement("style").attr("type", "text/css")
- .appendText("html, body {height:100%;margin:0;}");
-
- // Add favicon links
- String themeName = context.getThemeName();
- if (themeName != null) {
- String themeUri = getThemeUri(context, themeName);
- head.appendElement("link").attr("rel", "shortcut icon")
- .attr("type", "image/vnd.microsoft.icon")
- .attr("href", themeUri + "/favicon.ico");
- head.appendElement("link").attr("rel", "icon")
- .attr("type", "image/vnd.microsoft.icon")
- .attr("href", themeUri + "/favicon.ico");
- }
-
- Element body = document.body();
- body.attr("scroll", "auto");
- body.addClass(ApplicationConnection.GENERATED_BODY_CLASSNAME);
- }
-
- public BootstrapContext createContext(WrappedRequest request,
- WrappedResponse response, Application application, Integer rootId) {
- BootstrapContext context = new BootstrapContext(response,
- new BootstrapFragmentResponse(this, request,
- new ArrayList<Node>(), application, rootId));
- return context;
- }
-
- protected String getMainDivStyle(BootstrapContext context) {
- return null;
- }
-
- /**
- * Creates and returns a unique ID for the DIV where the application is to
- * be rendered.
- *
- * @param context
- *
- * @return the id to use in the DOM
- */
- protected abstract String getApplicationId(BootstrapContext context);
-
- public String getWidgetsetForRoot(BootstrapContext context) {
- Root root = context.getRoot();
- WrappedRequest request = context.getRequest();
-
- String widgetset = root.getApplication().getWidgetsetForRoot(root);
- if (widgetset == null) {
- widgetset = request.getDeploymentConfiguration()
- .getConfiguredWidgetset(request);
- }
-
- widgetset = AbstractApplicationServlet.stripSpecialChars(widgetset);
- return widgetset;
- }
-
- /**
- * Method to write the div element into which that actual Vaadin application
- * is rendered.
- * <p>
- * Override this method if you want to add some custom html around around
- * the div element into which the actual Vaadin application will be
- * rendered.
- *
- * @param context
- *
- * @throws IOException
- * @throws JSONException
- */
- private void setupMainDiv(BootstrapContext context) throws IOException,
- JSONException {
- String style = getMainDivStyle(context);
-
- /*- Add classnames;
- * .v-app
- * .v-app-loading
- * .v-app-<simpleName for app class>
- *- Additionally added from javascript:
- * .v-theme-<themeName, remove non-alphanum>
- */
-
- String appClass = "v-app-"
- + context.getApplication().getClass().getSimpleName();
-
- String classNames = "v-app " + appClass;
- List<Node> fragmentNodes = context.getBootstrapResponse()
- .getFragmentNodes();
-
- Element mainDiv = new Element(Tag.valueOf("div"), "");
- mainDiv.attr("id", context.getAppId());
- mainDiv.addClass(classNames);
- if (style != null && style.length() != 0) {
- mainDiv.attr("style", style);
- }
- mainDiv.appendElement("div").addClass("v-app-loading");
- mainDiv.appendElement("noscript")
- .append("You have to enable javascript in your browser to use an application built with Vaadin.");
- fragmentNodes.add(mainDiv);
-
- WrappedRequest request = context.getRequest();
-
- DeploymentConfiguration deploymentConfiguration = request
- .getDeploymentConfiguration();
- String staticFileLocation = deploymentConfiguration
- .getStaticFileLocation(request);
-
- fragmentNodes
- .add(new Element(Tag.valueOf("iframe"), "")
- .attr("tabIndex", "-1")
- .attr("id", "__gwt_historyFrame")
- .attr("style",
- "position:absolute;width:0;height:0;border:0;overflow:hidden")
- .attr("src", "javascript:false"));
-
- String bootstrapLocation = staticFileLocation
- + "/VAADIN/vaadinBootstrap.js";
- fragmentNodes.add(new Element(Tag.valueOf("script"), "").attr("type",
- "text/javascript").attr("src", bootstrapLocation));
- Element mainScriptTag = new Element(Tag.valueOf("script"), "").attr(
- "type", "text/javascript");
-
- StringBuilder builder = new StringBuilder();
- builder.append("//<![CDATA[\n");
- builder.append("if (!window.vaadin) alert("
- + JSONObject.quote("Failed to load the bootstrap javascript: "
- + bootstrapLocation) + ");\n");
-
- appendMainScriptTagContents(context, builder);
-
- builder.append("//]]>");
- mainScriptTag.appendChild(new DataNode(builder.toString(),
- mainScriptTag.baseUri()));
- fragmentNodes.add(mainScriptTag);
-
- }
-
- protected void appendMainScriptTagContents(BootstrapContext context,
- StringBuilder builder) throws JSONException, IOException {
- JSONObject defaults = getDefaultParameters(context);
- JSONObject appConfig = getApplicationParameters(context);
-
- boolean isDebug = !context.getApplication().isProductionMode();
-
- builder.append("vaadin.setDefaults(");
- appendJsonObject(builder, defaults, isDebug);
- builder.append(");\n");
-
- builder.append("vaadin.initApplication(\"");
- builder.append(context.getAppId());
- builder.append("\",");
- appendJsonObject(builder, appConfig, isDebug);
- builder.append(");\n");
- }
-
- private static void appendJsonObject(StringBuilder builder,
- JSONObject jsonObject, boolean isDebug) throws JSONException {
- if (isDebug) {
- builder.append(jsonObject.toString(4));
- } else {
- builder.append(jsonObject.toString());
- }
- }
-
- protected JSONObject getApplicationParameters(BootstrapContext context)
- throws JSONException, PaintException {
- Application application = context.getApplication();
- Integer rootId = context.getRootId();
-
- JSONObject appConfig = new JSONObject();
-
- if (rootId != null) {
- appConfig.put(ApplicationConnection.ROOT_ID_PARAMETER, rootId);
- }
-
- if (context.getThemeName() != null) {
- appConfig.put("themeUri",
- getThemeUri(context, context.getThemeName()));
- }
-
- JSONObject versionInfo = new JSONObject();
- versionInfo.put("vaadinVersion", Version.getFullVersion());
- versionInfo.put("applicationVersion", application.getVersion());
- appConfig.put("versionInfo", versionInfo);
-
- appConfig.put("widgetset", context.getWidgetsetName());
-
- if (rootId == null || application.isRootInitPending(rootId.intValue())) {
- appConfig.put("initialPath", context.getRequest()
- .getRequestPathInfo());
-
- Map<String, String[]> parameterMap = context.getRequest()
- .getParameterMap();
- appConfig.put("initialParams", parameterMap);
- } else {
- // write the initial UIDL into the config
- appConfig.put("uidl",
- getInitialUIDL(context.getRequest(), context.getRoot()));
- }
-
- return appConfig;
- }
-
- protected JSONObject getDefaultParameters(BootstrapContext context)
- throws JSONException {
- JSONObject defaults = new JSONObject();
-
- WrappedRequest request = context.getRequest();
- Application application = context.getApplication();
-
- // Get system messages
- Application.SystemMessages systemMessages = AbstractApplicationServlet
- .getSystemMessages(application.getClass());
- if (systemMessages != null) {
- // Write the CommunicationError -message to client
- JSONObject comErrMsg = new JSONObject();
- comErrMsg.put("caption",
- systemMessages.getCommunicationErrorCaption());
- comErrMsg.put("message",
- systemMessages.getCommunicationErrorMessage());
- comErrMsg.put("url", systemMessages.getCommunicationErrorURL());
-
- defaults.put("comErrMsg", comErrMsg);
-
- JSONObject authErrMsg = new JSONObject();
- authErrMsg.put("caption",
- systemMessages.getAuthenticationErrorCaption());
- authErrMsg.put("message",
- systemMessages.getAuthenticationErrorMessage());
- authErrMsg.put("url", systemMessages.getAuthenticationErrorURL());
-
- defaults.put("authErrMsg", authErrMsg);
- }
-
- DeploymentConfiguration deploymentConfiguration = request
- .getDeploymentConfiguration();
- String staticFileLocation = deploymentConfiguration
- .getStaticFileLocation(request);
- String widgetsetBase = staticFileLocation + "/"
- + AbstractApplicationServlet.WIDGETSET_DIRECTORY_PATH;
- defaults.put("widgetsetBase", widgetsetBase);
-
- if (!application.isProductionMode()) {
- defaults.put("debug", true);
- }
-
- if (deploymentConfiguration.isStandalone(request)) {
- defaults.put("standalone", true);
- }
-
- defaults.put("appUri", getAppUri(context));
-
- return defaults;
- }
-
- protected abstract String getAppUri(BootstrapContext context);
-
- /**
- * Get the URI for the application theme.
- *
- * A portal-wide default theme is fetched from the portal shared resource
- * directory (if any), other themes from the portlet.
- *
- * @param context
- * @param themeName
- *
- * @return
- */
- public String getThemeUri(BootstrapContext context, String themeName) {
- WrappedRequest request = context.getRequest();
- final String staticFilePath = request.getDeploymentConfiguration()
- .getStaticFileLocation(request);
- return staticFilePath + "/"
- + AbstractApplicationServlet.THEME_DIRECTORY_PATH + themeName;
- }
-
- /**
- * Override if required
- *
- * @param context
- * @return
- */
- public String getThemeName(BootstrapContext context) {
- return context.getApplication().getThemeForRoot(context.getRoot());
- }
-
- /**
- * Don not override.
- *
- * @param context
- * @return
- */
- public String findAndEscapeThemeName(BootstrapContext context) {
- String themeName = getThemeName(context);
- if (themeName == null) {
- WrappedRequest request = context.getRequest();
- themeName = request.getDeploymentConfiguration()
- .getConfiguredTheme(request);
- }
-
- // XSS preventation, theme names shouldn't contain special chars anyway.
- // The servlet denies them via url parameter.
- themeName = AbstractApplicationServlet.stripSpecialChars(themeName);
-
- return themeName;
- }
-
- protected void writeError(WrappedResponse response, Throwable e)
- throws IOException {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
- e.getLocalizedMessage());
- }
-
- /**
- * Gets the initial UIDL message to send to the client.
- *
- * @param request
- * the originating request
- * @param root
- * the root for which the UIDL should be generated
- * @return a string with the initial UIDL message
- * @throws PaintException
- * if an exception occurs while painting the components
- * @throws JSONException
- * if an exception occurs while formatting the output
- */
- protected abstract String getInitialUIDL(WrappedRequest request, Root root)
- throws PaintException, JSONException;
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapListener.java b/src/com/vaadin/terminal/gwt/server/BootstrapListener.java
deleted file mode 100644
index d80e626cc1..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapListener.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventListener;
-
-public interface BootstrapListener extends EventListener {
- public void modifyBootstrapFragment(BootstrapFragmentResponse response);
-
- public void modifyBootstrapPage(BootstrapPageResponse response);
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapPageResponse.java b/src/com/vaadin/terminal/gwt/server/BootstrapPageResponse.java
deleted file mode 100644
index 802238ac62..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapPageResponse.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.Map;
-
-import org.jsoup.nodes.Document;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.WrappedRequest;
-
-public class BootstrapPageResponse extends BootstrapResponse {
-
- private final Map<String, Object> headers;
- private final Document document;
-
- public BootstrapPageResponse(BootstrapHandler handler,
- WrappedRequest request, Document document,
- Map<String, Object> headers, Application application, Integer rootId) {
- super(handler, request, application, rootId);
- this.headers = headers;
- this.document = document;
- }
-
- public void setHeader(String name, String value) {
- headers.put(name, value);
- }
-
- public void setDateHeader(String name, long timestamp) {
- headers.put(name, Long.valueOf(timestamp));
- }
-
- public Document getDocument() {
- return document;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java b/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java
deleted file mode 100644
index 88bd58593d..0000000000
--- a/src/com/vaadin/terminal/gwt/server/BootstrapResponse.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.EventObject;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.ui.Root;
-
-public abstract class BootstrapResponse extends EventObject {
- private final WrappedRequest request;
- private final Application application;
- private final Integer rootId;
-
- public BootstrapResponse(BootstrapHandler handler, WrappedRequest request,
- Application application, Integer rootId) {
- super(handler);
- this.request = request;
- this.application = application;
- this.rootId = rootId;
- }
-
- public BootstrapHandler getBootstrapHandler() {
- return (BootstrapHandler) getSource();
- }
-
- public WrappedRequest getRequest() {
- return request;
- }
-
- public Application getApplication() {
- return application;
- }
-
- public Integer getRootId() {
- return rootId;
- }
-
- public Root getRoot() {
- return Root.getCurrent();
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ChangeVariablesErrorEvent.java b/src/com/vaadin/terminal/gwt/server/ChangeVariablesErrorEvent.java
deleted file mode 100644
index 8f0c80332f..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ChangeVariablesErrorEvent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.util.Map;
-
-import com.vaadin.ui.AbstractComponent.ComponentErrorEvent;
-import com.vaadin.ui.Component;
-
-@SuppressWarnings("serial")
-public class ChangeVariablesErrorEvent implements ComponentErrorEvent {
-
- private Throwable throwable;
- private Component component;
-
- private Map<String, Object> variableChanges;
-
- public ChangeVariablesErrorEvent(Component component, Throwable throwable,
- Map<String, Object> variableChanges) {
- this.component = component;
- this.throwable = throwable;
- this.variableChanges = variableChanges;
- }
-
- @Override
- public Throwable getThrowable() {
- return throwable;
- }
-
- public Component getComponent() {
- return component;
- }
-
- public Map<String, Object> getVariableChanges() {
- return variableChanges;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/ClientConnector.java b/src/com/vaadin/terminal/gwt/server/ClientConnector.java
deleted file mode 100644
index 4f74cfe4bb..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ClientConnector.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.util.Collection;
-import java.util.List;
-
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.communication.SharedState;
-import com.vaadin.terminal.AbstractClientConnector;
-import com.vaadin.terminal.Extension;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.Root;
-
-/**
- * Interface implemented by all connectors that are capable of communicating
- * with the client side
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- *
- */
-public interface ClientConnector extends Connector, RpcTarget {
- /**
- * Returns the list of pending server to client RPC calls and clears the
- * list.
- *
- * @return an unmodifiable ordered list of pending server to client method
- * calls (not null)
- */
- public List<ClientMethodInvocation> retrievePendingRpcCalls();
-
- /**
- * Checks if the communicator is enabled. An enabled communicator is allowed
- * to receive messages from its counter-part.
- *
- * @return true if the connector can receive messages, false otherwise
- */
- public boolean isConnectorEnabled();
-
- /**
- * Returns the type of the shared state for this connector
- *
- * @return The type of the state. Must never return null.
- */
- public Class<? extends SharedState> getStateType();
-
- @Override
- public ClientConnector getParent();
-
- /**
- * Requests that the connector should be repainted as soon as possible.
- */
- public void requestRepaint();
-
- /**
- * Causes a repaint of this connector, and all connectors below it.
- *
- * This should only be used in special cases, e.g when the state of a
- * descendant depends on the state of an ancestor.
- */
- public void requestRepaintAll();
-
- /**
- * Sets the parent connector of the connector.
- *
- * <p>
- * This method automatically calls {@link #attach()} if the connector
- * becomes attached to the application, regardless of whether it was
- * attached previously. Conversely, if the parent is {@code null} and the
- * connector is attached to the application, {@link #detach()} is called for
- * the connector.
- * </p>
- * <p>
- * This method is rarely called directly. One of the
- * {@link ComponentContainer#addComponent(Component)} or
- * {@link AbstractClientConnector#addExtension(Extension)} methods are
- * normally used for adding connectors to a parent and they will call this
- * method implicitly.
- * </p>
- *
- * <p>
- * It is not possible to change the parent without first setting the parent
- * to {@code null}.
- * </p>
- *
- * @param parent
- * the parent connector
- * @throws IllegalStateException
- * if a parent is given even though the connector already has a
- * parent
- */
- public void setParent(ClientConnector parent);
-
- /**
- * Notifies the connector that it is connected to an application.
- *
- * <p>
- * The caller of this method is {@link #setParent(ClientConnector)} if the
- * parent is itself already attached to the application. If not, the parent
- * will call the {@link #attach()} for all its children when it is attached
- * to the application. This method is always called before the connector's
- * data is sent to the client-side for the first time.
- * </p>
- *
- * <p>
- * The attachment logic is implemented in {@link AbstractClientConnector}.
- * </p>
- */
- public void attach();
-
- /**
- * Notifies the component that it is detached from the application.
- *
- * <p>
- * The caller of this method is {@link #setParent(ClientConnector)} if the
- * parent is in the application. When the parent is detached from the
- * application it is its response to call {@link #detach()} for all the
- * children and to detach itself from the terminal.
- * </p>
- */
- public void detach();
-
- /**
- * Get a read-only collection of all extensions attached to this connector.
- *
- * @return a collection of extensions
- */
- public Collection<Extension> getExtensions();
-
- /**
- * Remove an extension from this connector.
- *
- * @param extension
- * the extension to remove.
- */
- public void removeExtension(Extension extension);
-
- /**
- * Returns the root this connector is attached to
- *
- * @return The Root this connector is attached to or null if it is not
- * attached to any Root
- */
- public Root getRoot();
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ClientMethodInvocation.java b/src/com/vaadin/terminal/gwt/server/ClientMethodInvocation.java
deleted file mode 100644
index 64ea288665..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ClientMethodInvocation.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-
-/**
- * Internal class for keeping track of pending server to client method
- * invocations for a Connector.
- *
- * @since 7.0
- */
-public class ClientMethodInvocation implements Serializable,
- Comparable<ClientMethodInvocation> {
- private final ClientConnector connector;
- private final String interfaceName;
- private final String methodName;
- private final Object[] parameters;
- private Type[] parameterTypes;
-
- // used for sorting calls between different connectors in the same Root
- private final long sequenceNumber;
- // TODO may cause problems when clustering etc.
- private static long counter = 0;
-
- public ClientMethodInvocation(ClientConnector connector,
- String interfaceName, Method method, Object[] parameters) {
- this.connector = connector;
- this.interfaceName = interfaceName;
- methodName = method.getName();
- parameterTypes = method.getGenericParameterTypes();
- this.parameters = (null != parameters) ? parameters : new Object[0];
- sequenceNumber = ++counter;
- }
-
- public Type[] getParameterTypes() {
- return parameterTypes;
- }
-
- public ClientConnector getConnector() {
- return connector;
- }
-
- public String getInterfaceName() {
- return interfaceName;
- }
-
- public String getMethodName() {
- return methodName;
- }
-
- public Object[] getParameters() {
- return parameters;
- }
-
- protected long getSequenceNumber() {
- return sequenceNumber;
- }
-
- @Override
- public int compareTo(ClientMethodInvocation o) {
- if (null == o) {
- return 0;
- }
- return Long.signum(getSequenceNumber() - o.getSequenceNumber());
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java
deleted file mode 100644
index 3cc3a8cb64..0000000000
--- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.servlet.ServletContext;
-
-import com.vaadin.Application;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.ui.Root;
-
-/**
- * Application manager processes changes and paints for single application
- * instance.
- *
- * This class handles applications running as servlets.
- *
- * @see AbstractCommunicationManager
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@SuppressWarnings("serial")
-public class CommunicationManager extends AbstractCommunicationManager {
-
- /**
- * @deprecated use {@link #CommunicationManager(Application)} instead
- * @param application
- * @param applicationServlet
- */
- @Deprecated
- public CommunicationManager(Application application,
- AbstractApplicationServlet applicationServlet) {
- super(application);
- }
-
- /**
- * TODO New constructor - document me!
- *
- * @param application
- */
- public CommunicationManager(Application application) {
- super(application);
- }
-
- @Override
- protected BootstrapHandler createBootstrapHandler() {
- return new BootstrapHandler() {
- @Override
- protected String getApplicationId(BootstrapContext context) {
- String appUrl = getAppUri(context);
-
- String appId = appUrl;
- if ("".equals(appUrl)) {
- appId = "ROOT";
- }
- appId = appId.replaceAll("[^a-zA-Z0-9]", "");
- // Add hashCode to the end, so that it is still (sort of)
- // predictable, but indicates that it should not be used in CSS
- // and
- // such:
- int hashCode = appId.hashCode();
- if (hashCode < 0) {
- hashCode = -hashCode;
- }
- appId = appId + "-" + hashCode;
- return appId;
- }
-
- @Override
- protected String getAppUri(BootstrapContext context) {
- /* Fetch relative url to application */
- // don't use server and port in uri. It may cause problems with
- // some
- // virtual server configurations which lose the server name
- Application application = context.getApplication();
- URL url = application.getURL();
- String appUrl = url.getPath();
- if (appUrl.endsWith("/")) {
- appUrl = appUrl.substring(0, appUrl.length() - 1);
- }
- return appUrl;
- }
-
- @Override
- public String getThemeName(BootstrapContext context) {
- String themeName = context.getRequest().getParameter(
- AbstractApplicationServlet.URL_PARAMETER_THEME);
- if (themeName == null) {
- themeName = super.getThemeName(context);
- }
- return themeName;
- }
-
- @Override
- protected String getInitialUIDL(WrappedRequest request, Root root)
- throws PaintException, JSONException {
- return CommunicationManager.this.getInitialUIDL(request, root);
- }
- };
- }
-
- @Override
- protected InputStream getThemeResourceAsStream(Root root, String themeName,
- String resource) {
- WebApplicationContext context = (WebApplicationContext) root
- .getApplication().getContext();
- ServletContext servletContext = context.getHttpSession()
- .getServletContext();
- return servletContext.getResourceAsStream("/"
- + AbstractApplicationServlet.THEME_DIRECTORY_PATH + themeName
- + "/" + resource);
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java b/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
deleted file mode 100644
index 171d440796..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.terminal.Sizeable.Unit;
-import com.vaadin.ui.AbstractOrderedLayout;
-import com.vaadin.ui.AbstractSplitPanel;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.CustomComponent;
-import com.vaadin.ui.Form;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.GridLayout.Area;
-import com.vaadin.ui.Layout;
-import com.vaadin.ui.Panel;
-import com.vaadin.ui.TabSheet;
-import com.vaadin.ui.VerticalLayout;
-import com.vaadin.ui.Window;
-
-@SuppressWarnings({ "serial", "deprecation" })
-public class ComponentSizeValidator implements Serializable {
-
- private final static int LAYERS_SHOWN = 4;
-
- /**
- * Recursively checks given component and its subtree for invalid layout
- * setups. Prints errors to std err stream.
- *
- * @param component
- * component to check
- * @return set of first level errors found
- */
- public static List<InvalidLayout> validateComponentRelativeSizes(
- Component component, List<InvalidLayout> errors,
- InvalidLayout parent) {
-
- boolean invalidHeight = !checkHeights(component);
- boolean invalidWidth = !checkWidths(component);
-
- if (invalidHeight || invalidWidth) {
- InvalidLayout error = new InvalidLayout(component, invalidHeight,
- invalidWidth);
- if (parent != null) {
- parent.addError(error);
- } else {
- if (errors == null) {
- errors = new LinkedList<InvalidLayout>();
- }
- errors.add(error);
- }
- parent = error;
- }
-
- if (component instanceof Panel) {
- Panel panel = (Panel) component;
- errors = validateComponentRelativeSizes(panel.getContent(), errors,
- parent);
- } else if (component instanceof ComponentContainer) {
- ComponentContainer lo = (ComponentContainer) component;
- Iterator<Component> it = lo.getComponentIterator();
- while (it.hasNext()) {
- errors = validateComponentRelativeSizes(it.next(), errors,
- parent);
- }
- } else if (component instanceof Form) {
- Form form = (Form) component;
- if (form.getLayout() != null) {
- errors = validateComponentRelativeSizes(form.getLayout(),
- errors, parent);
- }
- if (form.getFooter() != null) {
- errors = validateComponentRelativeSizes(form.getFooter(),
- errors, parent);
- }
- }
-
- return errors;
- }
-
- private static void printServerError(String msg,
- Stack<ComponentInfo> attributes, boolean widthError,
- PrintStream errorStream) {
- StringBuffer err = new StringBuffer();
- err.append("Vaadin DEBUG\n");
-
- StringBuilder indent = new StringBuilder("");
- ComponentInfo ci;
- if (attributes != null) {
- while (attributes.size() > LAYERS_SHOWN) {
- attributes.pop();
- }
- while (!attributes.empty()) {
- ci = attributes.pop();
- showComponent(ci.component, ci.info, err, indent, widthError);
- }
- }
-
- err.append("Layout problem detected: ");
- err.append(msg);
- err.append("\n");
- err.append("Relative sizes were replaced by undefined sizes, components may not render as expected.\n");
- errorStream.println(err);
-
- }
-
- public static boolean checkHeights(Component component) {
- try {
- if (!hasRelativeHeight(component)) {
- return true;
- }
- if (component instanceof Window) {
- return true;
- }
- if (component.getParent() == null) {
- return true;
- }
-
- return parentCanDefineHeight(component);
- } catch (Exception e) {
- getLogger().log(Level.FINER,
- "An exception occurred while validating sizes.", e);
- return true;
- }
- }
-
- public static boolean checkWidths(Component component) {
- try {
- if (!hasRelativeWidth(component)) {
- return true;
- }
- if (component instanceof Window) {
- return true;
- }
- if (component.getParent() == null) {
- return true;
- }
-
- return parentCanDefineWidth(component);
- } catch (Exception e) {
- getLogger().log(Level.FINER,
- "An exception occurred while validating sizes.", e);
- return true;
- }
- }
-
- public static class InvalidLayout implements Serializable {
-
- private final Component component;
-
- private final boolean invalidHeight;
- private final boolean invalidWidth;
-
- private final Vector<InvalidLayout> subErrors = new Vector<InvalidLayout>();
-
- public InvalidLayout(Component component, boolean height, boolean width) {
- this.component = component;
- invalidHeight = height;
- invalidWidth = width;
- }
-
- public void addError(InvalidLayout error) {
- subErrors.add(error);
- }
-
- public void reportErrors(PrintWriter clientJSON,
- AbstractCommunicationManager communicationManager,
- PrintStream serverErrorStream) {
- clientJSON.write("{");
-
- Component parent = component.getParent();
- String paintableId = component.getConnectorId();
-
- clientJSON.print("id:\"" + paintableId + "\"");
-
- if (invalidHeight) {
- Stack<ComponentInfo> attributes = null;
- String msg = "";
- // set proper error messages
- if (parent instanceof AbstractOrderedLayout) {
- AbstractOrderedLayout ol = (AbstractOrderedLayout) parent;
- boolean vertical = false;
-
- if (ol instanceof VerticalLayout) {
- vertical = true;
- }
-
- if (vertical) {
- msg = "Component with relative height inside a VerticalLayout with no height defined.";
- attributes = getHeightAttributes(component);
- } else {
- msg = "At least one of a HorizontalLayout's components must have non relative height if the height of the layout is not defined";
- attributes = getHeightAttributes(component);
- }
- } else if (parent instanceof GridLayout) {
- msg = "At least one of the GridLayout's components in each row should have non relative height if the height of the layout is not defined.";
- attributes = getHeightAttributes(component);
- } else {
- // default error for non sized parent issue
- msg = "A component with relative height needs a parent with defined height.";
- attributes = getHeightAttributes(component);
- }
- printServerError(msg, attributes, false, serverErrorStream);
- clientJSON.print(",\"heightMsg\":\"" + msg + "\"");
- }
- if (invalidWidth) {
- Stack<ComponentInfo> attributes = null;
- String msg = "";
- if (parent instanceof AbstractOrderedLayout) {
- AbstractOrderedLayout ol = (AbstractOrderedLayout) parent;
- boolean horizontal = true;
-
- if (ol instanceof VerticalLayout) {
- horizontal = false;
- }
-
- if (horizontal) {
- msg = "Component with relative width inside a HorizontalLayout with no width defined";
- attributes = getWidthAttributes(component);
- } else {
- msg = "At least one of a VerticalLayout's components must have non relative width if the width of the layout is not defined";
- attributes = getWidthAttributes(component);
- }
- } else if (parent instanceof GridLayout) {
- msg = "At least one of the GridLayout's components in each column should have non relative width if the width of the layout is not defined.";
- attributes = getWidthAttributes(component);
- } else {
- // default error for non sized parent issue
- msg = "A component with relative width needs a parent with defined width.";
- attributes = getWidthAttributes(component);
- }
- clientJSON.print(",\"widthMsg\":\"" + msg + "\"");
- printServerError(msg, attributes, true, serverErrorStream);
- }
- if (subErrors.size() > 0) {
- serverErrorStream.println("Sub errors >>");
- clientJSON.write(", \"subErrors\" : [");
- boolean first = true;
- for (InvalidLayout subError : subErrors) {
- if (!first) {
- clientJSON.print(",");
- } else {
- first = false;
- }
- subError.reportErrors(clientJSON, communicationManager,
- serverErrorStream);
- }
- clientJSON.write("]");
- serverErrorStream.println("<< Sub erros");
- }
- clientJSON.write("}");
- }
- }
-
- private static class ComponentInfo implements Serializable {
- Component component;
- String info;
-
- public ComponentInfo(Component component, String info) {
- this.component = component;
- this.info = info;
- }
-
- }
-
- private static Stack<ComponentInfo> getHeightAttributes(Component component) {
- Stack<ComponentInfo> attributes = new Stack<ComponentInfo>();
- attributes
- .add(new ComponentInfo(component, getHeightString(component)));
- Component parent = component.getParent();
- attributes.add(new ComponentInfo(parent, getHeightString(parent)));
-
- while ((parent = parent.getParent()) != null) {
- attributes.add(new ComponentInfo(parent, getHeightString(parent)));
- }
-
- return attributes;
- }
-
- private static Stack<ComponentInfo> getWidthAttributes(Component component) {
- Stack<ComponentInfo> attributes = new Stack<ComponentInfo>();
- attributes.add(new ComponentInfo(component, getWidthString(component)));
- Component parent = component.getParent();
- attributes.add(new ComponentInfo(parent, getWidthString(parent)));
-
- while ((parent = parent.getParent()) != null) {
- attributes.add(new ComponentInfo(parent, getWidthString(parent)));
- }
-
- return attributes;
- }
-
- private static String getWidthString(Component component) {
- String width = "width: ";
- if (hasRelativeWidth(component)) {
- width += "RELATIVE, " + component.getWidth() + " %";
- } else if (component instanceof Window && component.getParent() == null) {
- width += "MAIN WINDOW";
- } else if (component.getWidth() >= 0) {
- width += "ABSOLUTE, " + component.getWidth() + " "
- + component.getWidthUnits().getSymbol();
- } else {
- width += "UNDEFINED";
- }
-
- return width;
- }
-
- private static String getHeightString(Component component) {
- String height = "height: ";
- if (hasRelativeHeight(component)) {
- height += "RELATIVE, " + component.getHeight() + " %";
- } else if (component instanceof Window && component.getParent() == null) {
- height += "MAIN WINDOW";
- } else if (component.getHeight() > 0) {
- height += "ABSOLUTE, " + component.getHeight() + " "
- + component.getHeightUnits().getSymbol();
- } else {
- height += "UNDEFINED";
- }
-
- return height;
- }
-
- private static void showComponent(Component component, String attribute,
- StringBuffer err, StringBuilder indent, boolean widthError) {
-
- FileLocation createLoc = creationLocations.get(component);
-
- FileLocation sizeLoc;
- if (widthError) {
- sizeLoc = widthLocations.get(component);
- } else {
- sizeLoc = heightLocations.get(component);
- }
-
- err.append(indent);
- indent.append(" ");
- err.append("- ");
-
- err.append(component.getClass().getSimpleName());
- err.append("/").append(Integer.toHexString(component.hashCode()));
-
- if (component.getCaption() != null) {
- err.append(" \"");
- err.append(component.getCaption());
- err.append("\"");
- }
-
- if (component.getDebugId() != null) {
- err.append(" debugId: ");
- err.append(component.getDebugId());
- }
-
- if (createLoc != null) {
- err.append(", created at (" + createLoc.file + ":"
- + createLoc.lineNumber + ")");
-
- }
-
- if (attribute != null) {
- err.append(" (");
- err.append(attribute);
- if (sizeLoc != null) {
- err.append(", set at (" + sizeLoc.file + ":"
- + sizeLoc.lineNumber + ")");
- }
-
- err.append(")");
- }
- err.append("\n");
-
- }
-
- private static boolean hasNonRelativeHeightComponent(
- AbstractOrderedLayout ol) {
- Iterator<Component> it = ol.getComponentIterator();
- while (it.hasNext()) {
- if (!hasRelativeHeight(it.next())) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean parentCanDefineHeight(Component component) {
- Component parent = component.getParent();
- if (parent == null) {
- // main window, valid situation
- return true;
- }
- if (parent.getHeight() < 0) {
- // Undefined height
- if (parent instanceof Window) {
- // Sub window with undefined size has a min-height
- return true;
- }
-
- if (parent instanceof AbstractOrderedLayout) {
- boolean horizontal = true;
- if (parent instanceof VerticalLayout) {
- horizontal = false;
- }
- if (horizontal
- && hasNonRelativeHeightComponent((AbstractOrderedLayout) parent)) {
- return true;
- } else {
- return false;
- }
-
- } else if (parent instanceof GridLayout) {
- GridLayout gl = (GridLayout) parent;
- Area componentArea = gl.getComponentArea(component);
- boolean rowHasHeight = false;
- for (int row = componentArea.getRow1(); !rowHasHeight
- && row <= componentArea.getRow2(); row++) {
- for (int column = 0; !rowHasHeight
- && column < gl.getColumns(); column++) {
- Component c = gl.getComponent(column, row);
- if (c != null) {
- rowHasHeight = !hasRelativeHeight(c);
- }
- }
- }
- if (!rowHasHeight) {
- return false;
- } else {
- // Other components define row height
- return true;
- }
- }
-
- if (parent instanceof Panel || parent instanceof AbstractSplitPanel
- || parent instanceof TabSheet
- || parent instanceof CustomComponent) {
- // height undefined, we know how how component works and no
- // exceptions
- // TODO horiz SplitPanel ??
- return false;
- } else {
- // We cannot generally know if undefined component can serve
- // space for children (like CustomLayout or component built by
- // third party) so we assume they can
- return true;
- }
-
- } else if (hasRelativeHeight(parent)) {
- // Relative height
- if (parent.getParent() != null) {
- return parentCanDefineHeight(parent);
- } else {
- return true;
- }
- } else {
- // Absolute height
- return true;
- }
- }
-
- private static boolean hasRelativeHeight(Component component) {
- return (component.getHeightUnits() == Unit.PERCENTAGE && component
- .getHeight() > 0);
- }
-
- private static boolean hasNonRelativeWidthComponent(AbstractOrderedLayout ol) {
- Iterator<Component> it = ol.getComponentIterator();
- while (it.hasNext()) {
- if (!hasRelativeWidth(it.next())) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean hasRelativeWidth(Component paintable) {
- return paintable.getWidth() > 0
- && paintable.getWidthUnits() == Unit.PERCENTAGE;
- }
-
- public static boolean parentCanDefineWidth(Component component) {
- Component parent = component.getParent();
- if (parent == null) {
- // main window, valid situation
- return true;
- }
- if (parent instanceof Window) {
- // Sub window with undefined size has a min-width
- return true;
- }
-
- if (parent.getWidth() < 0) {
- // Undefined width
-
- if (parent instanceof AbstractOrderedLayout) {
- AbstractOrderedLayout ol = (AbstractOrderedLayout) parent;
- boolean horizontal = true;
- if (ol instanceof VerticalLayout) {
- horizontal = false;
- }
-
- if (!horizontal && hasNonRelativeWidthComponent(ol)) {
- // valid situation, other components defined width
- return true;
- } else {
- return false;
- }
- } else if (parent instanceof GridLayout) {
- GridLayout gl = (GridLayout) parent;
- Area componentArea = gl.getComponentArea(component);
- boolean columnHasWidth = false;
- for (int col = componentArea.getColumn1(); !columnHasWidth
- && col <= componentArea.getColumn2(); col++) {
- for (int row = 0; !columnHasWidth && row < gl.getRows(); row++) {
- Component c = gl.getComponent(col, row);
- if (c != null) {
- columnHasWidth = !hasRelativeWidth(c);
- }
- }
- }
- if (!columnHasWidth) {
- return false;
- } else {
- // Other components define column width
- return true;
- }
- } else if (parent instanceof Form) {
- /*
- * If some other part of the form is not relative it determines
- * the component width
- */
- return hasNonRelativeWidthComponent((Form) parent);
- } else if (parent instanceof AbstractSplitPanel
- || parent instanceof TabSheet
- || parent instanceof CustomComponent) {
- // FIXME Could we use com.vaadin package name here and
- // fail for all component containers?
- // FIXME Actually this should be moved to containers so it can
- // be implemented for custom containers
- // TODO vertical splitpanel with another non relative component?
- return false;
- } else if (parent instanceof Window) {
- // Sub window can define width based on caption
- if (parent.getCaption() != null
- && !parent.getCaption().equals("")) {
- return true;
- } else {
- return false;
- }
- } else if (parent instanceof Panel) {
- // TODO Panel should be able to define width based on caption
- return false;
- } else {
- return true;
- }
- } else if (hasRelativeWidth(parent)) {
- // Relative width
- if (parent.getParent() == null) {
- return true;
- }
-
- return parentCanDefineWidth(parent);
- } else {
- return true;
- }
-
- }
-
- private static boolean hasNonRelativeWidthComponent(Form form) {
- Layout layout = form.getLayout();
- Layout footer = form.getFooter();
-
- if (layout != null && !hasRelativeWidth(layout)) {
- return true;
- }
- if (footer != null && !hasRelativeWidth(footer)) {
- return true;
- }
-
- return false;
- }
-
- private static Map<Object, FileLocation> creationLocations = new HashMap<Object, FileLocation>();
- private static Map<Object, FileLocation> widthLocations = new HashMap<Object, FileLocation>();
- private static Map<Object, FileLocation> heightLocations = new HashMap<Object, FileLocation>();
-
- public static class FileLocation implements Serializable {
- public String method;
- public String file;
- public String className;
- public String classNameSimple;
- public int lineNumber;
-
- public FileLocation(StackTraceElement traceElement) {
- file = traceElement.getFileName();
- className = traceElement.getClassName();
- classNameSimple = className
- .substring(className.lastIndexOf('.') + 1);
- lineNumber = traceElement.getLineNumber();
- method = traceElement.getMethodName();
- }
- }
-
- public static void setCreationLocation(Object object) {
- setLocation(creationLocations, object);
- }
-
- public static void setWidthLocation(Object object) {
- setLocation(widthLocations, object);
- }
-
- public static void setHeightLocation(Object object) {
- setLocation(heightLocations, object);
- }
-
- private static void setLocation(Map<Object, FileLocation> map, Object object) {
- StackTraceElement[] traceLines = Thread.currentThread().getStackTrace();
- for (StackTraceElement traceElement : traceLines) {
- Class<?> cls;
- try {
- String className = traceElement.getClassName();
- if (className.startsWith("java.")
- || className.startsWith("sun.")) {
- continue;
- }
-
- cls = Class.forName(className);
- if (cls == ComponentSizeValidator.class || cls == Thread.class) {
- continue;
- }
-
- if (Component.class.isAssignableFrom(cls)
- && !CustomComponent.class.isAssignableFrom(cls)) {
- continue;
- }
- FileLocation cl = new FileLocation(traceElement);
- map.put(object, cl);
- return;
- } catch (Exception e) {
- // TODO Auto-generated catch block
- getLogger().log(Level.FINER,
- "An exception occurred while validating sizes.", e);
- }
-
- }
- }
-
- private static Logger getLogger() {
- return Logger.getLogger(ComponentSizeValidator.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/Constants.java b/src/com/vaadin/terminal/gwt/server/Constants.java
deleted file mode 100644
index 7efb0205ac..0000000000
--- a/src/com/vaadin/terminal/gwt/server/Constants.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-/**
- * TODO Document me!
- *
- * @author peholmst
- *
- */
-public interface Constants {
-
- static final String NOT_PRODUCTION_MODE_INFO = "\n"
- + "=================================================================\n"
- + "Vaadin is running in DEBUG MODE.\nAdd productionMode=true to web.xml "
- + "to disable debug features.\nTo show debug window, add ?debug to "
- + "your application URL.\n"
- + "=================================================================";
-
- static final String WARNING_XSRF_PROTECTION_DISABLED = "\n"
- + "===========================================================\n"
- + "WARNING: Cross-site request forgery protection is disabled!\n"
- + "===========================================================";
-
- static final String WARNING_RESOURCE_CACHING_TIME_NOT_NUMERIC = "\n"
- + "===========================================================\n"
- + "WARNING: resourceCacheTime has been set to a non integer value "
- + "in web.xml. The default of 1h will be used.\n"
- + "===========================================================";
-
- static final String WIDGETSET_MISMATCH_INFO = "\n"
- + "=================================================================\n"
- + "The widgetset in use does not seem to be built for the Vaadin\n"
- + "version in use. This might cause strange problems - a\n"
- + "recompile/deploy is strongly recommended.\n"
- + " Vaadin version: %s\n"
- + " Widgetset version: %s\n"
- + "=================================================================";
-
- static final String URL_PARAMETER_RESTART_APPLICATION = "restartApplication";
- static final String URL_PARAMETER_CLOSE_APPLICATION = "closeApplication";
- static final String URL_PARAMETER_REPAINT_ALL = "repaintAll";
- static final String URL_PARAMETER_THEME = "theme";
-
- static final String SERVLET_PARAMETER_PRODUCTION_MODE = "productionMode";
- static final String SERVLET_PARAMETER_DISABLE_XSRF_PROTECTION = "disable-xsrf-protection";
- static final String SERVLET_PARAMETER_RESOURCE_CACHE_TIME = "resourceCacheTime";
-
- // Configurable parameter names
- static final String PARAMETER_VAADIN_RESOURCES = "Resources";
-
- static final int DEFAULT_BUFFER_SIZE = 32 * 1024;
-
- static final int MAX_BUFFER_SIZE = 64 * 1024;
-
- final String THEME_DIRECTORY_PATH = "VAADIN/themes/";
-
- static final int DEFAULT_THEME_CACHETIME = 1000 * 60 * 60 * 24;
-
- static final String WIDGETSET_DIRECTORY_PATH = "VAADIN/widgetsets/";
-
- // Name of the default widget set, used if not specified in web.xml
- static final String DEFAULT_WIDGETSET = "com.vaadin.terminal.gwt.DefaultWidgetSet";
-
- // Widget set parameter name
- static final String PARAMETER_WIDGETSET = "widgetset";
-
- static final String ERROR_NO_ROOT_FOUND = "Application did not return a root for the request and did not request extra information either. Something is wrong.";
-
- static final String DEFAULT_THEME_NAME = "reindeer";
-
- static final String INVALID_SECURITY_KEY_MSG = "Invalid security key.";
-
- // portal configuration parameters
- static final String PORTAL_PARAMETER_VAADIN_WIDGETSET = "vaadin.widgetset";
- static final String PORTAL_PARAMETER_VAADIN_RESOURCE_PATH = "vaadin.resources.path";
- static final String PORTAL_PARAMETER_VAADIN_THEME = "vaadin.theme";
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java
deleted file mode 100644
index efb5666efa..0000000000
--- a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.PrintWriter;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.TransferableImpl;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DragSource;
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.event.dd.TargetDetails;
-import com.vaadin.event.dd.TargetDetailsImpl;
-import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
-import com.vaadin.shared.communication.SharedState;
-import com.vaadin.shared.ui.dd.DragEventType;
-import com.vaadin.terminal.Extension;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.terminal.gwt.client.ui.dd.VDragAndDropManager;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Root;
-
-public class DragAndDropService implements VariableOwner, ClientConnector {
-
- private int lastVisitId;
-
- private boolean lastVisitAccepted = false;
-
- private DragAndDropEvent dragEvent;
-
- private final AbstractCommunicationManager manager;
-
- private AcceptCriterion acceptCriterion;
-
- public DragAndDropService(AbstractCommunicationManager manager) {
- this.manager = manager;
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- Object owner = variables.get("dhowner");
-
- // Validate drop handler owner
- if (!(owner instanceof DropTarget)) {
- getLogger()
- .severe("DropHandler owner " + owner
- + " must implement DropTarget");
- return;
- }
- // owner cannot be null here
-
- DropTarget dropTarget = (DropTarget) owner;
- lastVisitId = (Integer) variables.get("visitId");
-
- // request may be dropRequest or request during drag operation (commonly
- // dragover or dragenter)
- boolean dropRequest = isDropRequest(variables);
- if (dropRequest) {
- handleDropRequest(dropTarget, variables);
- } else {
- handleDragRequest(dropTarget, variables);
- }
-
- }
-
- /**
- * Handles a drop request from the VDragAndDropManager.
- *
- * @param dropTarget
- * @param variables
- */
- private void handleDropRequest(DropTarget dropTarget,
- Map<String, Object> variables) {
- DropHandler dropHandler = (dropTarget).getDropHandler();
- if (dropHandler == null) {
- // No dropHandler returned so no drop can be performed.
- getLogger().fine(
- "DropTarget.getDropHandler() returned null for owner: "
- + dropTarget);
- return;
- }
-
- /*
- * Construct the Transferable and the DragDropDetails for the drop
- * operation based on the info passed from the client widgets (drag
- * source for Transferable, drop target for DragDropDetails).
- */
- Transferable transferable = constructTransferable(dropTarget, variables);
- TargetDetails dropData = constructDragDropDetails(dropTarget, variables);
- DragAndDropEvent dropEvent = new DragAndDropEvent(transferable,
- dropData);
- if (dropHandler.getAcceptCriterion().accept(dropEvent)) {
- dropHandler.drop(dropEvent);
- }
- }
-
- /**
- * Handles a drag/move request from the VDragAndDropManager.
- *
- * @param dropTarget
- * @param variables
- */
- private void handleDragRequest(DropTarget dropTarget,
- Map<String, Object> variables) {
- lastVisitId = (Integer) variables.get("visitId");
-
- acceptCriterion = dropTarget.getDropHandler().getAcceptCriterion();
-
- /*
- * Construct the Transferable and the DragDropDetails for the drag
- * operation based on the info passed from the client widgets (drag
- * source for Transferable, current target for DragDropDetails).
- */
- Transferable transferable = constructTransferable(dropTarget, variables);
- TargetDetails dragDropDetails = constructDragDropDetails(dropTarget,
- variables);
-
- dragEvent = new DragAndDropEvent(transferable, dragDropDetails);
-
- lastVisitAccepted = acceptCriterion.accept(dragEvent);
- }
-
- /**
- * Construct DragDropDetails based on variables from client drop target.
- * Uses DragDropDetailsTranslator if available, otherwise a default
- * DragDropDetails implementation is used.
- *
- * @param dropTarget
- * @param variables
- * @return
- */
- @SuppressWarnings("unchecked")
- private TargetDetails constructDragDropDetails(DropTarget dropTarget,
- Map<String, Object> variables) {
- Map<String, Object> rawDragDropDetails = (Map<String, Object>) variables
- .get("evt");
-
- TargetDetails dropData = dropTarget
- .translateDropTargetDetails(rawDragDropDetails);
-
- if (dropData == null) {
- // Create a default DragDropDetails with all the raw variables
- dropData = new TargetDetailsImpl(rawDragDropDetails, dropTarget);
- }
-
- return dropData;
- }
-
- private boolean isDropRequest(Map<String, Object> variables) {
- return getRequestType(variables) == DragEventType.DROP;
- }
-
- private DragEventType getRequestType(Map<String, Object> variables) {
- int type = (Integer) variables.get("type");
- return DragEventType.values()[type];
- }
-
- @SuppressWarnings("unchecked")
- private Transferable constructTransferable(DropTarget dropHandlerOwner,
- Map<String, Object> variables) {
- final Component sourceComponent = (Component) variables
- .get("component");
-
- variables = (Map<String, Object>) variables.get("tra");
-
- Transferable transferable = null;
- if (sourceComponent != null && sourceComponent instanceof DragSource) {
- transferable = ((DragSource) sourceComponent)
- .getTransferable(variables);
- }
- if (transferable == null) {
- transferable = new TransferableImpl(sourceComponent, variables);
- }
-
- return transferable;
- }
-
- @Override
- public boolean isEnabled() {
- return isConnectorEnabled();
- }
-
- @Override
- public boolean isImmediate() {
- return true;
- }
-
- void printJSONResponse(PrintWriter outWriter) throws PaintException {
- if (isDirty()) {
-
- outWriter.print(", \"dd\":");
-
- JsonPaintTarget jsonPaintTarget = new JsonPaintTarget(manager,
- outWriter, false);
- jsonPaintTarget.startTag("dd");
- jsonPaintTarget.addAttribute("visitId", lastVisitId);
- if (acceptCriterion != null) {
- jsonPaintTarget.addAttribute("accepted", lastVisitAccepted);
- acceptCriterion.paintResponse(jsonPaintTarget);
- }
- jsonPaintTarget.endTag("dd");
- jsonPaintTarget.close();
- lastVisitId = -1;
- lastVisitAccepted = false;
- acceptCriterion = null;
- dragEvent = null;
- }
- }
-
- private boolean isDirty() {
- if (lastVisitId > 0) {
- return true;
- }
- return false;
- }
-
- @Override
- public SharedState getState() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public String getConnectorId() {
- return VDragAndDropManager.DD_SERVICE;
- }
-
- @Override
- public boolean isConnectorEnabled() {
- // Drag'n'drop can't be disabled
- return true;
- }
-
- @Override
- public List<ClientMethodInvocation> retrievePendingRpcCalls() {
- return null;
- }
-
- @Override
- public RpcManager getRpcManager(Class<?> rpcInterface) {
- // TODO Use rpc for drag'n'drop
- return null;
- }
-
- @Override
- public Class<? extends SharedState> getStateType() {
- return SharedState.class;
- }
-
- @Override
- public void requestRepaint() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public ClientConnector getParent() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public void requestRepaintAll() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setParent(ClientConnector parent) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void attach() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void detach() {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Collection<Extension> getExtensions() {
- // TODO Auto-generated method stub
- return Collections.emptySet();
- }
-
- @Override
- public void removeExtension(Extension extension) {
- // TODO Auto-generated method stub
- }
-
- private Logger getLogger() {
- return Logger.getLogger(DragAndDropService.class.getName());
- }
-
- @Override
- public Root getRoot() {
- return null;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java
deleted file mode 100644
index cc12c9cc43..0000000000
--- a/src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import com.google.appengine.api.datastore.Blob;
-import com.google.appengine.api.datastore.DatastoreService;
-import com.google.appengine.api.datastore.DatastoreServiceFactory;
-import com.google.appengine.api.datastore.Entity;
-import com.google.appengine.api.datastore.EntityNotFoundException;
-import com.google.appengine.api.datastore.FetchOptions.Builder;
-import com.google.appengine.api.datastore.Key;
-import com.google.appengine.api.datastore.KeyFactory;
-import com.google.appengine.api.datastore.PreparedQuery;
-import com.google.appengine.api.datastore.Query;
-import com.google.appengine.api.datastore.Query.FilterOperator;
-import com.google.appengine.api.memcache.Expiration;
-import com.google.appengine.api.memcache.MemcacheService;
-import com.google.appengine.api.memcache.MemcacheServiceFactory;
-import com.google.apphosting.api.DeadlineExceededException;
-import com.vaadin.service.ApplicationContext;
-
-/**
- * ApplicationServlet to be used when deploying to Google App Engine, in
- * web.xml:
- *
- * <pre>
- * &lt;servlet&gt;
- * &lt;servlet-name&gt;HelloWorld&lt;/servlet-name&gt;
- * &lt;servlet-class&gt;com.vaadin.terminal.gwt.server.GAEApplicationServlet&lt;/servlet-class&gt;
- * &lt;init-param&gt;
- * &lt;param-name&gt;application&lt;/param-name&gt;
- * &lt;param-value&gt;com.vaadin.demo.HelloWorld&lt;/param-value&gt;
- * &lt;/init-param&gt;
- * &lt;/servlet&gt;
- * </pre>
- *
- * Session support must be enabled in appengine-web.xml:
- *
- * <pre>
- * &lt;sessions-enabled&gt;true&lt;/sessions-enabled&gt;
- * </pre>
- *
- * Appengine datastore cleanup can be invoked by calling one of the applications
- * with an additional path "/CLEAN". This can be set up as a cron-job in
- * cron.xml (see appengine documentation for more information):
- *
- * <pre>
- * &lt;cronentries&gt;
- * &lt;cron&gt;
- * &lt;url&gt;/HelloWorld/CLEAN&lt;/url&gt;
- * &lt;description&gt;Clean up sessions&lt;/description&gt;
- * &lt;schedule&gt;every 2 hours&lt;/schedule&gt;
- * &lt;/cron&gt;
- * &lt;/cronentries&gt;
- * </pre>
- *
- * It is recommended (but not mandatory) to extract themes and widgetsets and
- * have App Engine server these statically. Extract VAADIN folder (and it's
- * contents) 'next to' the WEB-INF folder, and add the following to
- * appengine-web.xml:
- *
- * <pre>
- * &lt;static-files&gt;
- * &lt;include path=&quot;/VAADIN/**&quot; /&gt;
- * &lt;/static-files&gt;
- * </pre>
- *
- * Additional limitations:
- * <ul>
- * <li/>Do not change application state when serving an ApplicationResource.
- * <li/>Avoid changing application state in transaction handlers, unless you're
- * confident you fully understand the synchronization issues in App Engine.
- * <li/>The application remains locked while uploading - no progressbar is
- * possible.
- * </ul>
- */
-public class GAEApplicationServlet extends ApplicationServlet {
-
- // memcache mutex is MUTEX_BASE + sessio id
- private static final String MUTEX_BASE = "_vmutex";
-
- // used identify ApplicationContext in memcache and datastore
- private static final String AC_BASE = "_vac";
-
- // UIDL requests will attempt to gain access for this long before telling
- // the client to retry
- private static final int MAX_UIDL_WAIT_MILLISECONDS = 5000;
-
- // Tell client to retry after this delay.
- // Note: currently interpreting Retry-After as ms, not sec
- private static final int RETRY_AFTER_MILLISECONDS = 100;
-
- // Properties used in the datastore
- private static final String PROPERTY_EXPIRES = "expires";
- private static final String PROPERTY_DATA = "data";
-
- // path used for cleanup
- private static final String CLEANUP_PATH = "/CLEAN";
- // max entities to clean at once
- private static final int CLEANUP_LIMIT = 200;
- // appengine session kind
- private static final String APPENGINE_SESSION_KIND = "_ah_SESSION";
- // appengine session expires-parameter
- private static final String PROPERTY_APPENGINE_EXPIRES = "_expires";
-
- protected void sendDeadlineExceededNotification(
- WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException {
- criticalNotification(
- request,
- response,
- "Deadline Exceeded",
- "I'm sorry, but the operation took too long to complete. We'll try reloading to see where we're at, please take note of any unsaved data...",
- "", null);
- }
-
- protected void sendNotSerializableNotification(
- WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException {
- criticalNotification(
- request,
- response,
- "NotSerializableException",
- "I'm sorry, but there seems to be a serious problem, please contact the administrator. And please take note of any unsaved data...",
- "", getApplicationUrl(request).toString()
- + "?restartApplication");
- }
-
- protected void sendCriticalErrorNotification(
- WrappedHttpServletRequest request,
- WrappedHttpServletResponse response) throws IOException {
- criticalNotification(
- request,
- response,
- "Critical error",
- "I'm sorry, but there seems to be a serious problem, please contact the administrator. And please take note of any unsaved data...",
- "", getApplicationUrl(request).toString()
- + "?restartApplication");
- }
-
- @Override
- protected void service(HttpServletRequest unwrappedRequest,
- HttpServletResponse unwrappedResponse) throws ServletException,
- IOException {
- WrappedHttpServletRequest request = new WrappedHttpServletRequest(
- unwrappedRequest, getDeploymentConfiguration());
- WrappedHttpServletResponse response = new WrappedHttpServletResponse(
- unwrappedResponse, getDeploymentConfiguration());
-
- if (isCleanupRequest(request)) {
- cleanDatastore();
- return;
- }
-
- RequestType requestType = getRequestType(request);
-
- if (requestType == RequestType.STATIC_FILE) {
- // no locking needed, let superclass handle
- super.service(request, response);
- cleanSession(request);
- return;
- }
-
- if (requestType == RequestType.APPLICATION_RESOURCE) {
- // no locking needed, let superclass handle
- getApplicationContext(request,
- MemcacheServiceFactory.getMemcacheService());
- super.service(request, response);
- cleanSession(request);
- return;
- }
-
- final HttpSession session = request
- .getSession(requestCanCreateApplication(request, requestType));
- if (session == null) {
- handleServiceSessionExpired(request, response);
- cleanSession(request);
- return;
- }
-
- boolean locked = false;
- MemcacheService memcache = null;
- String mutex = MUTEX_BASE + session.getId();
- memcache = MemcacheServiceFactory.getMemcacheService();
- try {
- // try to get lock
- long started = new Date().getTime();
- // non-UIDL requests will try indefinitely
- while (requestType != RequestType.UIDL
- || new Date().getTime() - started < MAX_UIDL_WAIT_MILLISECONDS) {
- locked = memcache.put(mutex, 1, Expiration.byDeltaSeconds(40),
- MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT);
- if (locked) {
- break;
- }
- try {
- Thread.sleep(RETRY_AFTER_MILLISECONDS);
- } catch (InterruptedException e) {
- getLogger().finer(
- "Thread.sleep() interrupted while waiting for lock. Trying again. "
- + e);
- }
- }
-
- if (!locked) {
- // Not locked; only UIDL can get trough here unlocked: tell
- // client to retry
- response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
- // Note: currently interpreting Retry-After as ms, not sec
- response.setHeader("Retry-After", "" + RETRY_AFTER_MILLISECONDS);
- return;
- }
-
- // de-serialize or create application context, store in session
- ApplicationContext ctx = getApplicationContext(request, memcache);
-
- super.service(request, response);
-
- // serialize
- started = new Date().getTime();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(ctx);
- oos.flush();
- byte[] bytes = baos.toByteArray();
-
- started = new Date().getTime();
-
- String id = AC_BASE + session.getId();
- Date expire = new Date(started
- + (session.getMaxInactiveInterval() * 1000));
- Expiration expires = Expiration.onDate(expire);
-
- memcache.put(id, bytes, expires);
-
- DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
- Entity entity = new Entity(AC_BASE, id);
- entity.setProperty(PROPERTY_EXPIRES, expire.getTime());
- entity.setProperty(PROPERTY_DATA, new Blob(bytes));
- ds.put(entity);
-
- } catch (DeadlineExceededException e) {
- getLogger().warning("DeadlineExceeded for " + session.getId());
- sendDeadlineExceededNotification(request, response);
- } catch (NotSerializableException e) {
- getLogger().log(Level.SEVERE, "Not serializable!", e);
-
- // TODO this notification is usually not shown - should we redirect
- // in some other way - can we?
- sendNotSerializableNotification(request, response);
- } catch (Exception e) {
- getLogger().log(Level.WARNING,
- "An exception occurred while servicing request.", e);
-
- sendCriticalErrorNotification(request, response);
- } finally {
- // "Next, please!"
- if (locked) {
- memcache.delete(mutex);
- }
- cleanSession(request);
- }
- }
-
- protected ApplicationContext getApplicationContext(
- HttpServletRequest request, MemcacheService memcache) {
- HttpSession session = request.getSession();
- String id = AC_BASE + session.getId();
- byte[] serializedAC = (byte[]) memcache.get(id);
- if (serializedAC == null) {
- DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
- Key key = KeyFactory.createKey(AC_BASE, id);
- Entity entity = null;
- try {
- entity = ds.get(key);
- } catch (EntityNotFoundException e) {
- // Ok, we were a bit optimistic; we'll create a new one later
- }
- if (entity != null) {
- Blob blob = (Blob) entity.getProperty(PROPERTY_DATA);
- serializedAC = blob.getBytes();
- // bring it to memcache
- memcache.put(AC_BASE + session.getId(), serializedAC,
- Expiration.byDeltaSeconds(session
- .getMaxInactiveInterval()),
- MemcacheService.SetPolicy.ADD_ONLY_IF_NOT_PRESENT);
- }
- }
- if (serializedAC != null) {
- ByteArrayInputStream bais = new ByteArrayInputStream(serializedAC);
- ObjectInputStream ois;
- try {
- ois = new ObjectInputStream(bais);
- ApplicationContext applicationContext = (ApplicationContext) ois
- .readObject();
- session.setAttribute(WebApplicationContext.class.getName(),
- applicationContext);
- } catch (IOException e) {
- getLogger().log(
- Level.WARNING,
- "Could not de-serialize ApplicationContext for "
- + session.getId()
- + " A new one will be created. ", e);
- } catch (ClassNotFoundException e) {
- getLogger().log(
- Level.WARNING,
- "Could not de-serialize ApplicationContext for "
- + session.getId()
- + " A new one will be created. ", e);
- }
- }
- // will create new context if the above did not
- return getApplicationContext(session);
-
- }
-
- private boolean isCleanupRequest(HttpServletRequest request) {
- String path = getRequestPathInfo(request);
- if (path != null && path.equals(CLEANUP_PATH)) {
- return true;
- }
- return false;
- }
-
- /**
- * Removes the ApplicationContext from the session in order to minimize the
- * data serialized to datastore and memcache.
- *
- * @param request
- */
- private void cleanSession(HttpServletRequest request) {
- HttpSession session = request.getSession(false);
- if (session != null) {
- session.removeAttribute(WebApplicationContext.class.getName());
- }
- }
-
- /**
- * This will look at the timestamp and delete expired persisted Vaadin and
- * appengine sessions from the datastore.
- *
- * TODO Possible improvements include: 1. Use transactions (requires entity
- * groups - overkill?) 2. Delete one-at-a-time, catch possible exception,
- * continue w/ next.
- */
- private void cleanDatastore() {
- long expire = new Date().getTime();
- try {
- DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
- // Vaadin stuff first
- {
- Query q = new Query(AC_BASE);
- q.setKeysOnly();
-
- q.addFilter(PROPERTY_EXPIRES,
- FilterOperator.LESS_THAN_OR_EQUAL, expire);
- PreparedQuery pq = ds.prepare(q);
- List<Entity> entities = pq.asList(Builder
- .withLimit(CLEANUP_LIMIT));
- if (entities != null) {
- getLogger().info(
- "Vaadin cleanup deleting " + entities.size()
- + " expired Vaadin sessions.");
- List<Key> keys = new ArrayList<Key>();
- for (Entity e : entities) {
- keys.add(e.getKey());
- }
- ds.delete(keys);
- }
- }
- // Also cleanup GAE sessions
- {
- Query q = new Query(APPENGINE_SESSION_KIND);
- q.setKeysOnly();
- q.addFilter(PROPERTY_APPENGINE_EXPIRES,
- FilterOperator.LESS_THAN_OR_EQUAL, expire);
- PreparedQuery pq = ds.prepare(q);
- List<Entity> entities = pq.asList(Builder
- .withLimit(CLEANUP_LIMIT));
- if (entities != null) {
- getLogger().info(
- "Vaadin cleanup deleting " + entities.size()
- + " expired appengine sessions.");
- List<Key> keys = new ArrayList<Key>();
- for (Entity e : entities) {
- keys.add(e.getKey());
- }
- ds.delete(keys);
- }
- }
- } catch (Exception e) {
- getLogger().log(Level.WARNING, "Exception while cleaning.", e);
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(GAEApplicationServlet.class.getName());
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/HttpServletRequestListener.java b/src/com/vaadin/terminal/gwt/server/HttpServletRequestListener.java
deleted file mode 100644
index d811cadf86..0000000000
--- a/src/com/vaadin/terminal/gwt/server/HttpServletRequestListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-import javax.servlet.Filter;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.vaadin.Application;
-import com.vaadin.service.ApplicationContext.TransactionListener;
-import com.vaadin.terminal.Terminal;
-
-/**
- * {@link Application} that implements this interface gets notified of request
- * start and end by terminal.
- * <p>
- * Interface can be used for several helper tasks including:
- * <ul>
- * <li>Opening and closing database connections
- * <li>Implementing {@link ThreadLocal}
- * <li>Setting/Getting {@link Cookie}
- * </ul>
- * <p>
- * Alternatives for implementing similar features are are Servlet {@link Filter}
- * s and {@link TransactionListener}s in Vaadin.
- *
- * @since 6.2
- * @see PortletRequestListener
- */
-public interface HttpServletRequestListener extends Serializable {
-
- /**
- * This method is called before {@link Terminal} applies the request to
- * Application.
- *
- * @param request
- * @param response
- */
- public void onRequestStart(HttpServletRequest request,
- HttpServletResponse response);
-
- /**
- * This method is called at the end of each request.
- *
- * @param request
- * @param response
- */
- public void onRequestEnd(HttpServletRequest request,
- HttpServletResponse response);
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/JsonCodec.java b/src/com/vaadin/terminal/gwt/server/JsonCodec.java
deleted file mode 100644
index 8199bc6ada..0000000000
--- a/src/com/vaadin/terminal/gwt/server/JsonCodec.java
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.external.json.JSONObject;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.communication.UidlValue;
-import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ConnectorTracker;
-
-/**
- * Decoder for converting RPC parameters and other values from JSON in transfer
- * between the client and the server and vice versa.
- *
- * @since 7.0
- */
-public class JsonCodec implements Serializable {
-
- private static Map<Class<?>, String> typeToTransportType = new HashMap<Class<?>, String>();
-
- /**
- * Note! This does not contain primitives.
- * <p>
- */
- private static Map<String, Class<?>> transportTypeToType = new HashMap<String, Class<?>>();
-
- static {
- registerType(String.class, JsonEncoder.VTYPE_STRING);
- registerType(Connector.class, JsonEncoder.VTYPE_CONNECTOR);
- registerType(Boolean.class, JsonEncoder.VTYPE_BOOLEAN);
- registerType(boolean.class, JsonEncoder.VTYPE_BOOLEAN);
- registerType(Integer.class, JsonEncoder.VTYPE_INTEGER);
- registerType(int.class, JsonEncoder.VTYPE_INTEGER);
- registerType(Float.class, JsonEncoder.VTYPE_FLOAT);
- registerType(float.class, JsonEncoder.VTYPE_FLOAT);
- registerType(Double.class, JsonEncoder.VTYPE_DOUBLE);
- registerType(double.class, JsonEncoder.VTYPE_DOUBLE);
- registerType(Long.class, JsonEncoder.VTYPE_LONG);
- registerType(long.class, JsonEncoder.VTYPE_LONG);
- registerType(String[].class, JsonEncoder.VTYPE_STRINGARRAY);
- registerType(Object[].class, JsonEncoder.VTYPE_ARRAY);
- registerType(Map.class, JsonEncoder.VTYPE_MAP);
- registerType(HashMap.class, JsonEncoder.VTYPE_MAP);
- registerType(List.class, JsonEncoder.VTYPE_LIST);
- registerType(Set.class, JsonEncoder.VTYPE_SET);
- }
-
- private static void registerType(Class<?> type, String transportType) {
- typeToTransportType.put(type, transportType);
- if (!type.isPrimitive()) {
- transportTypeToType.put(transportType, type);
- }
- }
-
- public static boolean isInternalTransportType(String transportType) {
- return transportTypeToType.containsKey(transportType);
- }
-
- public static boolean isInternalType(Type type) {
- if (type instanceof Class && ((Class<?>) type).isPrimitive()) {
- if (type == byte.class || type == char.class) {
- // Almost all primitive types are handled internally
- return false;
- }
- // All primitive types are handled internally
- return true;
- } else if (type == UidlValue.class) {
- // UidlValue is a special internal type wrapping type info and a
- // value
- return true;
- }
- return typeToTransportType.containsKey(getClassForType(type));
- }
-
- private static Class<?> getClassForType(Type type) {
- if (type instanceof ParameterizedType) {
- return (Class<?>) (((ParameterizedType) type).getRawType());
- } else if (type instanceof Class<?>) {
- return (Class<?>) type;
- } else {
- return null;
- }
- }
-
- private static Class<?> getType(String transportType) {
- return transportTypeToType.get(transportType);
- }
-
- public static Object decodeInternalOrCustomType(Type targetType,
- Object value, ConnectorTracker connectorTracker)
- throws JSONException {
- if (isInternalType(targetType)) {
- return decodeInternalType(targetType, false, value,
- connectorTracker);
- } else {
- return decodeCustomType(targetType, value, connectorTracker);
- }
- }
-
- public static Object decodeCustomType(Type targetType, Object value,
- ConnectorTracker connectorTracker) throws JSONException {
- if (isInternalType(targetType)) {
- throw new JSONException("decodeCustomType cannot be used for "
- + targetType + ", which is an internal type");
- }
-
- // Try to decode object using fields
- if (value == JSONObject.NULL) {
- return null;
- } else if (targetType == byte.class || targetType == Byte.class) {
- return Byte.valueOf(String.valueOf(value));
- } else if (targetType == char.class || targetType == Character.class) {
- return Character.valueOf(String.valueOf(value).charAt(0));
- } else if (targetType instanceof Class<?>
- && ((Class<?>) targetType).isArray()) {
- // Legacy Object[] and String[] handled elsewhere, this takes care
- // of generic arrays
- Class<?> componentType = ((Class<?>) targetType).getComponentType();
- return decodeArray(componentType, (JSONArray) value,
- connectorTracker);
- } else if (targetType instanceof GenericArrayType) {
- Type componentType = ((GenericArrayType) targetType)
- .getGenericComponentType();
- return decodeArray(componentType, (JSONArray) value,
- connectorTracker);
- } else if (targetType == JSONObject.class
- || targetType == JSONArray.class) {
- return value;
- } else {
- return decodeObject(targetType, (JSONObject) value,
- connectorTracker);
- }
- }
-
- private static Object decodeArray(Type componentType, JSONArray value,
- ConnectorTracker connectorTracker) throws JSONException {
- Class<?> componentClass = getClassForType(componentType);
- Object array = Array.newInstance(componentClass, value.length());
- for (int i = 0; i < value.length(); i++) {
- Object decodedValue = decodeInternalOrCustomType(componentType,
- value.get(i), connectorTracker);
- Array.set(array, i, decodedValue);
- }
- return array;
- }
-
- /**
- * Decodes a value that is of an internal type.
- * <p>
- * Ensures the encoded value is of the same type as target type.
- * </p>
- * <p>
- * Allows restricting collections so that they must be declared using
- * generics. If this is used then all objects in the collection are encoded
- * using the declared type. Otherwise only internal types are allowed in
- * collections.
- * </p>
- *
- * @param targetType
- * The type that should be returned by this method
- * @param valueAndType
- * The encoded value and type array
- * @param application
- * A reference to the application
- * @param enforceGenericsInCollections
- * true if generics should be enforce, false to only allow
- * internal types in collections
- * @return
- * @throws JSONException
- */
- public static Object decodeInternalType(Type targetType,
- boolean restrictToInternalTypes, Object encodedJsonValue,
- ConnectorTracker connectorTracker) throws JSONException {
- if (!isInternalType(targetType)) {
- throw new JSONException("Type " + targetType
- + " is not a supported internal type.");
- }
- String transportType = getInternalTransportType(targetType);
-
- if (encodedJsonValue == JSONObject.NULL) {
- return null;
- }
-
- // UidlValue
- if (targetType == UidlValue.class) {
- return decodeUidlValue((JSONArray) encodedJsonValue,
- connectorTracker);
- }
-
- // Collections
- if (JsonEncoder.VTYPE_LIST.equals(transportType)) {
- return decodeList(targetType, restrictToInternalTypes,
- (JSONArray) encodedJsonValue, connectorTracker);
- } else if (JsonEncoder.VTYPE_SET.equals(transportType)) {
- return decodeSet(targetType, restrictToInternalTypes,
- (JSONArray) encodedJsonValue, connectorTracker);
- } else if (JsonEncoder.VTYPE_MAP.equals(transportType)) {
- return decodeMap(targetType, restrictToInternalTypes,
- encodedJsonValue, connectorTracker);
- }
-
- // Arrays
- if (JsonEncoder.VTYPE_ARRAY.equals(transportType)) {
-
- return decodeObjectArray(targetType, (JSONArray) encodedJsonValue,
- connectorTracker);
-
- } else if (JsonEncoder.VTYPE_STRINGARRAY.equals(transportType)) {
- return decodeStringArray((JSONArray) encodedJsonValue);
- }
-
- // Special Vaadin types
-
- String stringValue = String.valueOf(encodedJsonValue);
-
- if (JsonEncoder.VTYPE_CONNECTOR.equals(transportType)) {
- return connectorTracker.getConnector(stringValue);
- }
-
- // Legacy types
-
- if (JsonEncoder.VTYPE_STRING.equals(transportType)) {
- return stringValue;
- } else if (JsonEncoder.VTYPE_INTEGER.equals(transportType)) {
- return Integer.valueOf(stringValue);
- } else if (JsonEncoder.VTYPE_LONG.equals(transportType)) {
- return Long.valueOf(stringValue);
- } else if (JsonEncoder.VTYPE_FLOAT.equals(transportType)) {
- return Float.valueOf(stringValue);
- } else if (JsonEncoder.VTYPE_DOUBLE.equals(transportType)) {
- return Double.valueOf(stringValue);
- } else if (JsonEncoder.VTYPE_BOOLEAN.equals(transportType)) {
- return Boolean.valueOf(stringValue);
- }
-
- throw new JSONException("Unknown type " + transportType);
- }
-
- private static UidlValue decodeUidlValue(JSONArray encodedJsonValue,
- ConnectorTracker connectorTracker) throws JSONException {
- String type = encodedJsonValue.getString(0);
-
- Object decodedValue = decodeInternalType(getType(type), true,
- encodedJsonValue.get(1), connectorTracker);
- return new UidlValue(decodedValue);
- }
-
- private static boolean transportTypesCompatible(
- String encodedTransportType, String transportType) {
- if (encodedTransportType == null) {
- return false;
- }
- if (encodedTransportType.equals(transportType)) {
- return true;
- }
- if (encodedTransportType.equals(JsonEncoder.VTYPE_NULL)) {
- return true;
- }
-
- return false;
- }
-
- private static Map<Object, Object> decodeMap(Type targetType,
- boolean restrictToInternalTypes, Object jsonMap,
- ConnectorTracker connectorTracker) throws JSONException {
- if (jsonMap instanceof JSONArray) {
- // Client-side has no declared type information to determine
- // encoding method for empty maps, so these are handled separately.
- // See #8906.
- JSONArray jsonArray = (JSONArray) jsonMap;
- if (jsonArray.length() == 0) {
- return new HashMap<Object, Object>();
- }
- }
-
- if (!restrictToInternalTypes && targetType instanceof ParameterizedType) {
- Type keyType = ((ParameterizedType) targetType)
- .getActualTypeArguments()[0];
- Type valueType = ((ParameterizedType) targetType)
- .getActualTypeArguments()[1];
- if (keyType == String.class) {
- return decodeStringMap(valueType, (JSONObject) jsonMap,
- connectorTracker);
- } else if (keyType == Connector.class) {
- return decodeConnectorMap(valueType, (JSONObject) jsonMap,
- connectorTracker);
- } else {
- return decodeObjectMap(keyType, valueType, (JSONArray) jsonMap,
- connectorTracker);
- }
- } else {
- return decodeStringMap(UidlValue.class, (JSONObject) jsonMap,
- connectorTracker);
- }
- }
-
- private static Map<Object, Object> decodeObjectMap(Type keyType,
- Type valueType, JSONArray jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
- Map<Object, Object> map = new HashMap<Object, Object>();
-
- JSONArray keys = jsonMap.getJSONArray(0);
- JSONArray values = jsonMap.getJSONArray(1);
-
- assert (keys.length() == values.length());
-
- for (int i = 0; i < keys.length(); i++) {
- Object key = decodeInternalOrCustomType(keyType, keys.get(i),
- connectorTracker);
- Object value = decodeInternalOrCustomType(valueType, values.get(i),
- connectorTracker);
-
- map.put(key, value);
- }
-
- return map;
- }
-
- private static Map<Object, Object> decodeConnectorMap(Type valueType,
- JSONObject jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
- Map<Object, Object> map = new HashMap<Object, Object>();
-
- for (Iterator<?> iter = jsonMap.keys(); iter.hasNext();) {
- String key = (String) iter.next();
- Object value = decodeInternalOrCustomType(valueType,
- jsonMap.get(key), connectorTracker);
- if (valueType == UidlValue.class) {
- value = ((UidlValue) value).getValue();
- }
- map.put(connectorTracker.getConnector(key), value);
- }
-
- return map;
- }
-
- private static Map<Object, Object> decodeStringMap(Type valueType,
- JSONObject jsonMap, ConnectorTracker connectorTracker)
- throws JSONException {
- Map<Object, Object> map = new HashMap<Object, Object>();
-
- for (Iterator<?> iter = jsonMap.keys(); iter.hasNext();) {
- String key = (String) iter.next();
- Object value = decodeInternalOrCustomType(valueType,
- jsonMap.get(key), connectorTracker);
- if (valueType == UidlValue.class) {
- value = ((UidlValue) value).getValue();
- }
- map.put(key, value);
- }
-
- return map;
- }
-
- /**
- * @param targetType
- * @param restrictToInternalTypes
- * @param typeIndex
- * The index of a generic type to use to define the child type
- * that should be decoded
- * @param encodedValueAndType
- * @param application
- * @return
- * @throws JSONException
- */
- private static Object decodeParametrizedType(Type targetType,
- boolean restrictToInternalTypes, int typeIndex, Object value,
- ConnectorTracker connectorTracker) throws JSONException {
- if (!restrictToInternalTypes && targetType instanceof ParameterizedType) {
- Type childType = ((ParameterizedType) targetType)
- .getActualTypeArguments()[typeIndex];
- // Only decode the given type
- return decodeInternalOrCustomType(childType, value,
- connectorTracker);
- } else {
- // Only UidlValue when not enforcing a given type to avoid security
- // issues
- UidlValue decodeInternalType = (UidlValue) decodeInternalType(
- UidlValue.class, true, value, connectorTracker);
- return decodeInternalType.getValue();
- }
- }
-
- private static Object decodeEnum(Class<? extends Enum> cls, JSONObject value) {
- String enumIdentifier = String.valueOf(value);
- return Enum.valueOf(cls, enumIdentifier);
- }
-
- private static String[] decodeStringArray(JSONArray jsonArray)
- throws JSONException {
- int length = jsonArray.length();
- List<String> tokens = new ArrayList<String>(length);
- for (int i = 0; i < length; ++i) {
- tokens.add(jsonArray.getString(i));
- }
- return tokens.toArray(new String[tokens.size()]);
- }
-
- private static Object[] decodeObjectArray(Type targetType,
- JSONArray jsonArray, ConnectorTracker connectorTracker)
- throws JSONException {
- List list = decodeList(List.class, true, jsonArray, connectorTracker);
- return list.toArray(new Object[list.size()]);
- }
-
- private static List<Object> decodeList(Type targetType,
- boolean restrictToInternalTypes, JSONArray jsonArray,
- ConnectorTracker connectorTracker) throws JSONException {
- List<Object> list = new ArrayList<Object>();
- for (int i = 0; i < jsonArray.length(); ++i) {
- // each entry always has two elements: type and value
- Object encodedValue = jsonArray.get(i);
- Object decodedChild = decodeParametrizedType(targetType,
- restrictToInternalTypes, 0, encodedValue, connectorTracker);
- list.add(decodedChild);
- }
- return list;
- }
-
- private static Set<Object> decodeSet(Type targetType,
- boolean restrictToInternalTypes, JSONArray jsonArray,
- ConnectorTracker connectorTracker) throws JSONException {
- HashSet<Object> set = new HashSet<Object>();
- set.addAll(decodeList(targetType, restrictToInternalTypes, jsonArray,
- connectorTracker));
- return set;
- }
-
- /**
- * Returns the name that should be used as field name in the JSON. We strip
- * "set" from the setter, keeping the result - this is easy to do on both
- * server and client, avoiding some issues with cASE. E.g setZIndex()
- * becomes "zIndex". Also ensures that both getter and setter are present,
- * returning null otherwise.
- *
- * @param pd
- * @return the name to be used or null if both getter and setter are not
- * found.
- */
- static String getTransportFieldName(PropertyDescriptor pd) {
- if (pd.getReadMethod() == null || pd.getWriteMethod() == null) {
- return null;
- }
- String fieldName = pd.getWriteMethod().getName().substring(3);
- fieldName = Character.toLowerCase(fieldName.charAt(0))
- + fieldName.substring(1);
- return fieldName;
- }
-
- private static Object decodeObject(Type targetType,
- JSONObject serializedObject, ConnectorTracker connectorTracker)
- throws JSONException {
-
- Class<?> targetClass = getClassForType(targetType);
- if (Enum.class.isAssignableFrom(targetClass)) {
- return decodeEnum(targetClass.asSubclass(Enum.class),
- serializedObject);
- }
-
- try {
- Object decodedObject = targetClass.newInstance();
- for (PropertyDescriptor pd : Introspector.getBeanInfo(targetClass)
- .getPropertyDescriptors()) {
-
- String fieldName = getTransportFieldName(pd);
- if (fieldName == null) {
- continue;
- }
- Object encodedFieldValue = serializedObject.get(fieldName);
- Type fieldType = pd.getReadMethod().getGenericReturnType();
- Object decodedFieldValue = decodeInternalOrCustomType(
- fieldType, encodedFieldValue, connectorTracker);
-
- pd.getWriteMethod().invoke(decodedObject, decodedFieldValue);
- }
-
- return decodedObject;
- } catch (IllegalArgumentException e) {
- throw new JSONException(e);
- } catch (IllegalAccessException e) {
- throw new JSONException(e);
- } catch (InvocationTargetException e) {
- throw new JSONException(e);
- } catch (InstantiationException e) {
- throw new JSONException(e);
- } catch (IntrospectionException e) {
- throw new JSONException(e);
- }
- }
-
- public static Object encode(Object value, Object referenceValue,
- Type valueType, ConnectorTracker connectorTracker)
- throws JSONException {
-
- if (valueType == null) {
- throw new IllegalArgumentException("type must be defined");
- }
-
- if (valueType instanceof WildcardType) {
- throw new IllegalStateException(
- "Can not serialize type with wildcard: " + valueType);
- }
-
- if (null == value) {
- return encodeNull();
- }
-
- if (value instanceof String[]) {
- String[] array = (String[]) value;
- JSONArray jsonArray = new JSONArray();
- for (int i = 0; i < array.length; ++i) {
- jsonArray.put(array[i]);
- }
- return jsonArray;
- } else if (value instanceof String) {
- return value;
- } else if (value instanceof Boolean) {
- return value;
- } else if (value instanceof Number) {
- return value;
- } else if (value instanceof Character) {
- // Character is not a Number
- return value;
- } else if (value instanceof Collection) {
- Collection<?> collection = (Collection<?>) value;
- JSONArray jsonArray = encodeCollection(valueType, collection,
- connectorTracker);
- return jsonArray;
- } else if (valueType instanceof Class<?>
- && ((Class<?>) valueType).isArray()) {
- JSONArray jsonArray = encodeArrayContents(
- ((Class<?>) valueType).getComponentType(), value,
- connectorTracker);
- return jsonArray;
- } else if (valueType instanceof GenericArrayType) {
- Type componentType = ((GenericArrayType) valueType)
- .getGenericComponentType();
- JSONArray jsonArray = encodeArrayContents(componentType, value,
- connectorTracker);
- return jsonArray;
- } else if (value instanceof Map) {
- Object jsonMap = encodeMap(valueType, (Map<?, ?>) value,
- connectorTracker);
- return jsonMap;
- } else if (value instanceof Connector) {
- Connector connector = (Connector) value;
- if (value instanceof Component
- && !(AbstractCommunicationManager
- .isVisible((Component) value))) {
- return encodeNull();
- }
- return connector.getConnectorId();
- } else if (value instanceof Enum) {
- return encodeEnum((Enum<?>) value, connectorTracker);
- } else if (value instanceof JSONArray || value instanceof JSONObject) {
- return value;
- } else {
- // Any object that we do not know how to encode we encode by looping
- // through fields
- return encodeObject(value, referenceValue, connectorTracker);
- }
- }
-
- private static Object encodeNull() {
- return JSONObject.NULL;
- }
-
- private static Object encodeObject(Object value, Object referenceValue,
- ConnectorTracker connectorTracker) throws JSONException {
- JSONObject jsonMap = new JSONObject();
-
- try {
- for (PropertyDescriptor pd : Introspector.getBeanInfo(
- value.getClass()).getPropertyDescriptors()) {
- String fieldName = getTransportFieldName(pd);
- if (fieldName == null) {
- continue;
- }
- Method getterMethod = pd.getReadMethod();
- // We can't use PropertyDescriptor.getPropertyType() as it does
- // not support generics
- Type fieldType = getterMethod.getGenericReturnType();
- Object fieldValue = getterMethod.invoke(value, (Object[]) null);
- boolean equals = false;
- Object referenceFieldValue = null;
- if (referenceValue != null) {
- referenceFieldValue = getterMethod.invoke(referenceValue,
- (Object[]) null);
- equals = equals(fieldValue, referenceFieldValue);
- }
- if (!equals) {
- if (jsonMap.has(fieldName)) {
- throw new RuntimeException(
- "Can't encode "
- + value.getClass().getName()
- + " as it has multiple fields with the name "
- + fieldName.toLowerCase()
- + ". This can happen if only casing distinguishes one property name from another.");
- }
- jsonMap.put(
- fieldName,
- encode(fieldValue, referenceFieldValue, fieldType,
- connectorTracker));
- // } else {
- // System.out.println("Skipping field " + fieldName
- // + " of type " + fieldType.getName()
- // + " for object " + value.getClass().getName()
- // + " as " + fieldValue + "==" + referenceFieldValue);
- }
- }
- } catch (Exception e) {
- // TODO: Should exceptions be handled in a different way?
- throw new JSONException(e);
- }
- return jsonMap;
- }
-
- /**
- * Compares the value with the reference. If they match, returns true.
- *
- * @param fieldValue
- * @param referenceValue
- * @return
- */
- private static boolean equals(Object fieldValue, Object referenceValue) {
- if (fieldValue == null) {
- return referenceValue == null;
- }
-
- if (fieldValue.equals(referenceValue)) {
- return true;
- }
-
- return false;
- }
-
- private static String encodeEnum(Enum<?> e,
- ConnectorTracker connectorTracker) throws JSONException {
- return e.name();
- }
-
- private static JSONArray encodeArrayContents(Type componentType,
- Object array, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray jsonArray = new JSONArray();
- for (int i = 0; i < Array.getLength(array); i++) {
- jsonArray.put(encode(Array.get(array, i), null, componentType,
- connectorTracker));
- }
- return jsonArray;
- }
-
- private static JSONArray encodeCollection(Type targetType,
- Collection collection, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray jsonArray = new JSONArray();
- for (Object o : collection) {
- jsonArray.put(encodeChild(targetType, 0, o, connectorTracker));
- }
- return jsonArray;
- }
-
- private static Object encodeChild(Type targetType, int typeIndex, Object o,
- ConnectorTracker connectorTracker) throws JSONException {
- if (targetType instanceof ParameterizedType) {
- Type childType = ((ParameterizedType) targetType)
- .getActualTypeArguments()[typeIndex];
- // Encode using the given type
- return encode(o, null, childType, connectorTracker);
- } else {
- throw new JSONException("Collection is missing generics");
- }
- }
-
- private static Object encodeMap(Type mapType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
- Type keyType, valueType;
-
- if (mapType instanceof ParameterizedType) {
- keyType = ((ParameterizedType) mapType).getActualTypeArguments()[0];
- valueType = ((ParameterizedType) mapType).getActualTypeArguments()[1];
- } else {
- throw new JSONException("Map is missing generics");
- }
-
- if (map.isEmpty()) {
- // Client -> server encodes empty map as an empty array because of
- // #8906. Do the same for server -> client to maintain symmetry.
- return new JSONArray();
- }
-
- if (keyType == String.class) {
- return encodeStringMap(valueType, map, connectorTracker);
- } else if (keyType == Connector.class) {
- return encodeConnectorMap(valueType, map, connectorTracker);
- } else {
- return encodeObjectMap(keyType, valueType, map, connectorTracker);
- }
- }
-
- private static JSONArray encodeObjectMap(Type keyType, Type valueType,
- Map<?, ?> map, ConnectorTracker connectorTracker)
- throws JSONException {
- JSONArray keys = new JSONArray();
- JSONArray values = new JSONArray();
-
- for (Entry<?, ?> entry : map.entrySet()) {
- Object encodedKey = encode(entry.getKey(), null, keyType,
- connectorTracker);
- Object encodedValue = encode(entry.getValue(), null, valueType,
- connectorTracker);
-
- keys.put(encodedKey);
- values.put(encodedValue);
- }
-
- return new JSONArray(Arrays.asList(keys, values));
- }
-
- private static JSONObject encodeConnectorMap(Type valueType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
- JSONObject jsonMap = new JSONObject();
-
- for (Entry<?, ?> entry : map.entrySet()) {
- Connector key = (Connector) entry.getKey();
- Object encodedValue = encode(entry.getValue(), null, valueType,
- connectorTracker);
- jsonMap.put(key.getConnectorId(), encodedValue);
- }
-
- return jsonMap;
- }
-
- private static JSONObject encodeStringMap(Type valueType, Map<?, ?> map,
- ConnectorTracker connectorTracker) throws JSONException {
- JSONObject jsonMap = new JSONObject();
-
- for (Entry<?, ?> entry : map.entrySet()) {
- String key = (String) entry.getKey();
- Object encodedValue = encode(entry.getValue(), null, valueType,
- connectorTracker);
- jsonMap.put(key, encodedValue);
- }
-
- return jsonMap;
- }
-
- /**
- * Gets the transport type for the given class. Returns null if no transport
- * type can be found.
- *
- * @param valueType
- * The type that should be transported
- * @return
- * @throws JSONException
- */
- private static String getInternalTransportType(Type valueType) {
- return typeToTransportType.get(getClassForType(valueType));
- }
-
- private static String getCustomTransportType(Class<?> targetType) {
- return targetType.getName();
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
deleted file mode 100644
index 5a830ddb63..0000000000
--- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.logging.Logger;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.StreamVariable;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.ui.Alignment;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.CustomLayout;
-
-/**
- * User Interface Description Language Target.
- *
- * TODO document better: role of this class, UIDL format, attributes, variables,
- * etc.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@SuppressWarnings("serial")
-public class JsonPaintTarget implements PaintTarget {
-
- /* Document type declarations */
-
- private final static String UIDL_ARG_NAME = "name";
-
- private final Stack<String> mOpenTags;
-
- private final Stack<JsonTag> openJsonTags;
-
- // these match each other element-wise
- private final Stack<ClientConnector> openPaintables;
- private final Stack<String> openPaintableTags;
-
- private final PrintWriter uidlBuffer;
-
- private boolean closed = false;
-
- private final AbstractCommunicationManager manager;
-
- private int changes = 0;
-
- private final Set<Object> usedResources = new HashSet<Object>();
-
- private boolean customLayoutArgumentsOpen = false;
-
- private JsonTag tag;
-
- private boolean cacheEnabled = false;
-
- private final Set<Class<? extends ClientConnector>> usedClientConnectors = new HashSet<Class<? extends ClientConnector>>();
-
- /**
- * Creates a new JsonPaintTarget.
- *
- * @param manager
- * @param outWriter
- * A character-output stream.
- * @param cachingRequired
- * true if this is not a full repaint, i.e. caches are to be
- * used.
- * @throws PaintException
- * if the paint operation failed.
- */
- public JsonPaintTarget(AbstractCommunicationManager manager,
- PrintWriter outWriter, boolean cachingRequired)
- throws PaintException {
-
- this.manager = manager;
-
- // Sets the target for UIDL writing
- uidlBuffer = outWriter;
-
- // Initialize tag-writing
- mOpenTags = new Stack<String>();
- openJsonTags = new Stack<JsonTag>();
-
- openPaintables = new Stack<ClientConnector>();
- openPaintableTags = new Stack<String>();
-
- cacheEnabled = cachingRequired;
- }
-
- @Override
- public void startTag(String tagName) throws PaintException {
- startTag(tagName, false);
- }
-
- /**
- * Prints the element start tag.
- *
- * <pre>
- * Todo:
- * Checking of input values
- *
- * </pre>
- *
- * @param tagName
- * the name of the start tag.
- * @throws PaintException
- * if the paint operation failed.
- *
- */
- public void startTag(String tagName, boolean isChildNode)
- throws PaintException {
- // In case of null data output nothing:
- if (tagName == null) {
- throw new NullPointerException();
- }
-
- // Ensures that the target is open
- if (closed) {
- throw new PaintException(
- "Attempted to write to a closed PaintTarget.");
- }
-
- if (tag != null) {
- openJsonTags.push(tag);
- }
- // Checks tagName and attributes here
- mOpenTags.push(tagName);
-
- tag = new JsonTag(tagName);
-
- customLayoutArgumentsOpen = false;
-
- }
-
- /**
- * Prints the element end tag.
- *
- * If the parent tag is closed before every child tag is closed an
- * PaintException is raised.
- *
- * @param tag
- * the name of the end tag.
- * @throws Paintexception
- * if the paint operation failed.
- */
-
- @Override
- public void endTag(String tagName) throws PaintException {
- // In case of null data output nothing:
- if (tagName == null) {
- throw new NullPointerException();
- }
-
- // Ensure that the target is open
- if (closed) {
- throw new PaintException(
- "Attempted to write to a closed PaintTarget.");
- }
-
- if (openJsonTags.size() > 0) {
- final JsonTag parent = openJsonTags.pop();
-
- String lastTag = "";
-
- lastTag = mOpenTags.pop();
- if (!tagName.equalsIgnoreCase(lastTag)) {
- throw new PaintException("Invalid UIDL: wrong ending tag: '"
- + tagName + "' expected: '" + lastTag + "'.");
- }
-
- parent.addData(tag.getJSON());
-
- tag = parent;
- } else {
- changes++;
- uidlBuffer.print(((changes > 1) ? "," : "") + tag.getJSON());
- tag = null;
- }
- }
-
- /**
- * Substitutes the XML sensitive characters with predefined XML entities.
- *
- * @param xml
- * the String to be substituted.
- * @return A new string instance where all occurrences of XML sensitive
- * characters are substituted with entities.
- */
- static public String escapeXML(String xml) {
- if (xml == null || xml.length() <= 0) {
- return "";
- }
- return escapeXML(new StringBuilder(xml)).toString();
- }
-
- /**
- * Substitutes the XML sensitive characters with predefined XML entities.
- *
- * @param xml
- * the String to be substituted.
- * @return A new StringBuilder instance where all occurrences of XML
- * sensitive characters are substituted with entities.
- *
- */
- static StringBuilder escapeXML(StringBuilder xml) {
- if (xml == null || xml.length() <= 0) {
- return new StringBuilder("");
- }
-
- final StringBuilder result = new StringBuilder(xml.length() * 2);
-
- for (int i = 0; i < xml.length(); i++) {
- final char c = xml.charAt(i);
- final String s = toXmlChar(c);
- if (s != null) {
- result.append(s);
- } else {
- result.append(c);
- }
- }
- return result;
- }
-
- /**
- * Escapes the given string so it can safely be used as a JSON string.
- *
- * @param s
- * The string to escape
- * @return Escaped version of the string
- */
- static public String escapeJSON(String s) {
- // FIXME: Move this method to another class as other classes use it
- // also.
- if (s == null) {
- return "";
- }
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < s.length(); i++) {
- final char ch = s.charAt(i);
- switch (ch) {
- case '"':
- sb.append("\\\"");
- break;
- case '\\':
- sb.append("\\\\");
- break;
- case '\b':
- sb.append("\\b");
- break;
- case '\f':
- sb.append("\\f");
- break;
- case '\n':
- sb.append("\\n");
- break;
- case '\r':
- sb.append("\\r");
- break;
- case '\t':
- sb.append("\\t");
- break;
- case '/':
- sb.append("\\/");
- break;
- default:
- if (ch >= '\u0000' && ch <= '\u001F') {
- final String ss = Integer.toHexString(ch);
- sb.append("\\u");
- for (int k = 0; k < 4 - ss.length(); k++) {
- sb.append('0');
- }
- sb.append(ss.toUpperCase());
- } else {
- sb.append(ch);
- }
- }
- }
- return sb.toString();
- }
-
- /**
- * Substitutes a XML sensitive character with predefined XML entity.
- *
- * @param c
- * the Character to be replaced with an entity.
- * @return String of the entity or null if character is not to be replaced
- * with an entity.
- */
- private static String toXmlChar(char c) {
- switch (c) {
- case '&':
- return "&amp;"; // & => &amp;
- case '>':
- return "&gt;"; // > => &gt;
- case '<':
- return "&lt;"; // < => &lt;
- case '"':
- return "&quot;"; // " => &quot;
- case '\'':
- return "&apos;"; // ' => &apos;
- default:
- return null;
- }
- }
-
- /**
- * Prints XML-escaped text.
- *
- * @param str
- * @throws PaintException
- * if the paint operation failed.
- *
- */
-
- @Override
- public void addText(String str) throws PaintException {
- tag.addData("\"" + escapeJSON(str) + "\"");
- }
-
- @Override
- public void addAttribute(String name, boolean value) throws PaintException {
- tag.addAttribute("\"" + name + "\":" + (value ? "true" : "false"));
- }
-
- @Override
- public void addAttribute(String name, Resource value) throws PaintException {
- if (value == null) {
- throw new NullPointerException();
- }
- ResourceReference reference = ResourceReference.create(value);
- addAttribute(name, reference.getURL());
- }
-
- @Override
- public void addAttribute(String name, int value) throws PaintException {
- tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
- }
-
- @Override
- public void addAttribute(String name, long value) throws PaintException {
- tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
- }
-
- @Override
- public void addAttribute(String name, float value) throws PaintException {
- tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
- }
-
- @Override
- public void addAttribute(String name, double value) throws PaintException {
- tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
- }
-
- @Override
- public void addAttribute(String name, String value) throws PaintException {
- // In case of null data output nothing:
- if ((value == null) || (name == null)) {
- throw new NullPointerException(
- "Parameters must be non-null strings");
- }
-
- tag.addAttribute("\"" + name + "\":\"" + escapeJSON(value) + "\"");
-
- if (customLayoutArgumentsOpen && "template".equals(name)) {
- getUsedResources().add("layouts/" + value + ".html");
- }
-
- if (name.equals("locale")) {
- manager.requireLocale(value);
- }
-
- }
-
- @Override
- public void addAttribute(String name, Component value)
- throws PaintException {
- final String id = value.getConnectorId();
- addAttribute(name, id);
- }
-
- @Override
- public void addAttribute(String name, Map<?, ?> value)
- throws PaintException {
-
- StringBuilder sb = new StringBuilder();
- sb.append("\"");
- sb.append(name);
- sb.append("\":");
- sb.append("{");
- for (Iterator<?> it = value.keySet().iterator(); it.hasNext();) {
- Object key = it.next();
- Object mapValue = value.get(key);
- sb.append("\"");
- if (key instanceof ClientConnector) {
- sb.append(((ClientConnector) key).getConnectorId());
- } else {
- sb.append(escapeJSON(key.toString()));
- }
- sb.append("\":");
- if (mapValue instanceof Float || mapValue instanceof Integer
- || mapValue instanceof Double
- || mapValue instanceof Boolean
- || mapValue instanceof Alignment) {
- sb.append(mapValue);
- } else {
- sb.append("\"");
- sb.append(escapeJSON(mapValue.toString()));
- sb.append("\"");
- }
- if (it.hasNext()) {
- sb.append(",");
- }
- }
- sb.append("}");
-
- tag.addAttribute(sb.toString());
- }
-
- @Override
- public void addAttribute(String name, Object[] values) {
- // In case of null data output nothing:
- if ((values == null) || (name == null)) {
- throw new NullPointerException(
- "Parameters must be non-null strings");
- }
- final StringBuilder buf = new StringBuilder();
- buf.append("\"" + name + "\":[");
- for (int i = 0; i < values.length; i++) {
- if (i > 0) {
- buf.append(",");
- }
- buf.append("\"");
- buf.append(escapeJSON(values[i].toString()));
- buf.append("\"");
- }
- buf.append("]");
- tag.addAttribute(buf.toString());
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, String value)
- throws PaintException {
- tag.addVariable(new StringVariable(owner, name, escapeJSON(value)));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, Component value)
- throws PaintException {
- tag.addVariable(new StringVariable(owner, name, value.getConnectorId()));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, int value)
- throws PaintException {
- tag.addVariable(new IntVariable(owner, name, value));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, long value)
- throws PaintException {
- tag.addVariable(new LongVariable(owner, name, value));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, float value)
- throws PaintException {
- tag.addVariable(new FloatVariable(owner, name, value));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, double value)
- throws PaintException {
- tag.addVariable(new DoubleVariable(owner, name, value));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, boolean value)
- throws PaintException {
- tag.addVariable(new BooleanVariable(owner, name, value));
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name, String[] value)
- throws PaintException {
- tag.addVariable(new ArrayVariable(owner, name, value));
- }
-
- /**
- * Adds a upload stream type variable.
- *
- * TODO not converted for JSON
- *
- * @param owner
- * the Listener for variable changes.
- * @param name
- * the Variable name.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
-
- @Override
- public void addUploadStreamVariable(VariableOwner owner, String name)
- throws PaintException {
- startTag("uploadstream");
- addAttribute(UIDL_ARG_NAME, name);
- endTag("uploadstream");
- }
-
- /**
- * Prints the single text section.
- *
- * Prints full text section. The section data is escaped
- *
- * @param sectionTagName
- * the name of the tag.
- * @param sectionData
- * the section data to be printed.
- * @throws PaintException
- * if the paint operation failed.
- */
-
- @Override
- public void addSection(String sectionTagName, String sectionData)
- throws PaintException {
- tag.addData("{\"" + sectionTagName + "\":\"" + escapeJSON(sectionData)
- + "\"}");
- }
-
- /**
- * Adds XML directly to UIDL.
- *
- * @param xml
- * the Xml to be added.
- * @throws PaintException
- * if the paint operation failed.
- */
-
- @Override
- public void addUIDL(String xml) throws PaintException {
-
- // Ensure that the target is open
- if (closed) {
- throw new PaintException(
- "Attempted to write to a closed PaintTarget.");
- }
-
- // Make sure that the open start tag is closed before
- // anything is written.
-
- // Escape and write what was given
- if (xml != null) {
- tag.addData("\"" + escapeJSON(xml) + "\"");
- }
-
- }
-
- /**
- * Adds XML section with namespace.
- *
- * @param sectionTagName
- * the name of the tag.
- * @param sectionData
- * the section data.
- * @param namespace
- * the namespace to be added.
- * @throws PaintException
- * if the paint operation failed.
- *
- * @see com.vaadin.terminal.PaintTarget#addXMLSection(String, String,
- * String)
- */
-
- @Override
- public void addXMLSection(String sectionTagName, String sectionData,
- String namespace) throws PaintException {
-
- // Ensure that the target is open
- if (closed) {
- throw new PaintException(
- "Attempted to write to a closed PaintTarget.");
- }
-
- startTag(sectionTagName);
- if (namespace != null) {
- addAttribute("xmlns", namespace);
- }
-
- if (sectionData != null) {
- tag.addData("\"" + escapeJSON(sectionData) + "\"");
- }
- endTag(sectionTagName);
- }
-
- /**
- * Gets the UIDL already printed to stream. Paint target must be closed
- * before the <code>getUIDL</code> can be called.
- *
- * @return the UIDL.
- */
- public String getUIDL() {
- if (closed) {
- return uidlBuffer.toString();
- }
- throw new IllegalStateException(
- "Tried to read UIDL from open PaintTarget");
- }
-
- /**
- * Closes the paint target. Paint target must be closed before the
- * <code>getUIDL</code> can be called. Subsequent attempts to write to paint
- * target. If the target was already closed, call to this function is
- * ignored. will generate an exception.
- *
- * @throws PaintException
- * if the paint operation failed.
- */
- public void close() throws PaintException {
- if (tag != null) {
- uidlBuffer.write(tag.getJSON());
- }
- flush();
- closed = true;
- }
-
- /**
- * Method flush.
- */
- private void flush() {
- uidlBuffer.flush();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.PaintTarget#startPaintable(com.vaadin.terminal
- * .Paintable, java.lang.String)
- */
-
- @Override
- public PaintStatus startPaintable(Component connector, String tagName)
- throws PaintException {
- boolean topLevelPaintable = openPaintables.isEmpty();
-
- getLogger().fine(
- "startPaintable for " + connector.getClass().getName() + "@"
- + Integer.toHexString(connector.hashCode()));
- startTag(tagName, true);
-
- openPaintables.push(connector);
- openPaintableTags.push(tagName);
-
- addAttribute("id", connector.getConnectorId());
-
- // Only paint top level paintables. All sub paintables are marked as
- // queued and painted separately later.
- if (!topLevelPaintable) {
- return PaintStatus.CACHED;
- }
-
- if (connector instanceof CustomLayout) {
- customLayoutArgumentsOpen = true;
- }
- return PaintStatus.PAINTING;
- }
-
- @Override
- public void endPaintable(Component paintable) throws PaintException {
- getLogger().fine(
- "endPaintable for " + paintable.getClass().getName() + "@"
- + Integer.toHexString(paintable.hashCode()));
-
- ClientConnector openPaintable = openPaintables.peek();
- if (paintable != openPaintable) {
- throw new PaintException("Invalid UIDL: closing wrong paintable: '"
- + paintable.getConnectorId() + "' expected: '"
- + openPaintable.getConnectorId() + "'.");
- }
- // remove paintable from the stack
- openPaintables.pop();
- String openTag = openPaintableTags.pop();
- endTag(openTag);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.PaintTarget#addCharacterData(java.lang.String )
- */
-
- @Override
- public void addCharacterData(String text) throws PaintException {
- if (text != null) {
- tag.addData(text);
- }
- }
-
- /**
- * This is basically a container for UI components variables, that will be
- * added at the end of JSON object.
- *
- * @author mattitahvonen
- *
- */
- class JsonTag implements Serializable {
- boolean firstField = false;
-
- Vector<Object> variables = new Vector<Object>();
-
- Vector<Object> children = new Vector<Object>();
-
- Vector<Object> attr = new Vector<Object>();
-
- StringBuilder data = new StringBuilder();
-
- public boolean childrenArrayOpen = false;
-
- private boolean childNode = false;
-
- private boolean tagClosed = false;
-
- public JsonTag(String tagName) {
- data.append("[\"" + tagName + "\"");
- }
-
- private void closeTag() {
- if (!tagClosed) {
- data.append(attributesAsJsonObject());
- data.append(getData());
- // Writes the end (closing) tag
- data.append("]");
- tagClosed = true;
- }
- }
-
- public String getJSON() {
- if (!tagClosed) {
- closeTag();
- }
- return data.toString();
- }
-
- public void openChildrenArray() {
- if (!childrenArrayOpen) {
- // append("c : [");
- childrenArrayOpen = true;
- // firstField = true;
- }
- }
-
- public void closeChildrenArray() {
- // append("]");
- // firstField = false;
- }
-
- public void setChildNode(boolean b) {
- childNode = b;
- }
-
- public boolean isChildNode() {
- return childNode;
- }
-
- public String startField() {
- if (firstField) {
- firstField = false;
- return "";
- } else {
- return ",";
- }
- }
-
- /**
- *
- * @param s
- * json string, object or array
- */
- public void addData(String s) {
- children.add(s);
- }
-
- public String getData() {
- final StringBuilder buf = new StringBuilder();
- final Iterator<Object> it = children.iterator();
- while (it.hasNext()) {
- buf.append(startField());
- buf.append(it.next());
- }
- return buf.toString();
- }
-
- public void addAttribute(String jsonNode) {
- attr.add(jsonNode);
- }
-
- private String attributesAsJsonObject() {
- final StringBuilder buf = new StringBuilder();
- buf.append(startField());
- buf.append("{");
- for (final Iterator<Object> iter = attr.iterator(); iter.hasNext();) {
- final String element = (String) iter.next();
- buf.append(element);
- if (iter.hasNext()) {
- buf.append(",");
- }
- }
- buf.append(tag.variablesAsJsonObject());
- buf.append("}");
- return buf.toString();
- }
-
- public void addVariable(Variable v) {
- variables.add(v);
- }
-
- private String variablesAsJsonObject() {
- if (variables.size() == 0) {
- return "";
- }
- final StringBuilder buf = new StringBuilder();
- buf.append(startField());
- buf.append("\"v\":{");
- final Iterator<Object> iter = variables.iterator();
- while (iter.hasNext()) {
- final Variable element = (Variable) iter.next();
- buf.append(element.getJsonPresentation());
- if (iter.hasNext()) {
- buf.append(",");
- }
- }
- buf.append("}");
- return buf.toString();
- }
- }
-
- abstract class Variable implements Serializable {
-
- String name;
-
- public abstract String getJsonPresentation();
- }
-
- class BooleanVariable extends Variable implements Serializable {
- boolean value;
-
- public BooleanVariable(VariableOwner owner, String name, boolean v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":" + (value == true ? "true" : "false");
- }
-
- }
-
- class StringVariable extends Variable implements Serializable {
- String value;
-
- public StringVariable(VariableOwner owner, String name, String v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":\"" + value + "\"";
- }
-
- }
-
- class IntVariable extends Variable implements Serializable {
- int value;
-
- public IntVariable(VariableOwner owner, String name, int v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":" + value;
- }
- }
-
- class LongVariable extends Variable implements Serializable {
- long value;
-
- public LongVariable(VariableOwner owner, String name, long v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":" + value;
- }
- }
-
- class FloatVariable extends Variable implements Serializable {
- float value;
-
- public FloatVariable(VariableOwner owner, String name, float v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":" + value;
- }
- }
-
- class DoubleVariable extends Variable implements Serializable {
- double value;
-
- public DoubleVariable(VariableOwner owner, String name, double v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- return "\"" + name + "\":" + value;
- }
- }
-
- class ArrayVariable extends Variable implements Serializable {
- String[] value;
-
- public ArrayVariable(VariableOwner owner, String name, String[] v) {
- value = v;
- this.name = name;
- }
-
- @Override
- public String getJsonPresentation() {
- StringBuilder sb = new StringBuilder();
- sb.append("\"");
- sb.append(name);
- sb.append("\":[");
- for (int i = 0; i < value.length;) {
- sb.append("\"");
- sb.append(escapeJSON(value[i]));
- sb.append("\"");
- i++;
- if (i < value.length) {
- sb.append(",");
- }
- }
- sb.append("]");
- return sb.toString();
- }
- }
-
- public Set<Object> getUsedResources() {
- return usedResources;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public String getTag(ClientConnector clientConnector) {
- Class<? extends ClientConnector> clientConnectorClass = clientConnector
- .getClass();
- while (clientConnectorClass.isAnonymousClass()) {
- clientConnectorClass = (Class<? extends ClientConnector>) clientConnectorClass
- .getSuperclass();
- }
- Class<?> clazz = clientConnectorClass;
- while (!usedClientConnectors.contains(clazz)
- && clazz.getSuperclass() != null
- && ClientConnector.class.isAssignableFrom(clazz)) {
- usedClientConnectors.add((Class<? extends ClientConnector>) clazz);
- clazz = clazz.getSuperclass();
- }
- return manager.getTagForType(clientConnectorClass);
- }
-
- Collection<Class<? extends ClientConnector>> getUsedClientConnectors() {
- return usedClientConnectors;
- }
-
- @Override
- public void addVariable(VariableOwner owner, String name,
- StreamVariable value) throws PaintException {
- String url = manager.getStreamVariableTargetUrl(
- (ClientConnector) owner, name, value);
- if (url != null) {
- addVariable(owner, name, url);
- } // else { //NOP this was just a cleanup by component }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.PaintTarget#isFullRepaint()
- */
-
- @Override
- public boolean isFullRepaint() {
- return !cacheEnabled;
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(JsonPaintTarget.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/LegacyChangeVariablesInvocation.java b/src/com/vaadin/terminal/gwt/server/LegacyChangeVariablesInvocation.java
deleted file mode 100644
index 9dba05d2c1..0000000000
--- a/src/com/vaadin/terminal/gwt/server/LegacyChangeVariablesInvocation.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.vaadin.shared.communication.MethodInvocation;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-
-public class LegacyChangeVariablesInvocation extends MethodInvocation {
- private Map<String, Object> variableChanges = new HashMap<String, Object>();
-
- public LegacyChangeVariablesInvocation(String connectorId,
- String variableName, Object value) {
- super(connectorId, ApplicationConnection.UPDATE_VARIABLE_INTERFACE,
- ApplicationConnection.UPDATE_VARIABLE_METHOD);
- setVariableChange(variableName, value);
- }
-
- public static boolean isLegacyVariableChange(String interfaceName,
- String methodName) {
- return ApplicationConnection.UPDATE_VARIABLE_METHOD
- .equals(interfaceName)
- && ApplicationConnection.UPDATE_VARIABLE_METHOD
- .equals(methodName);
- }
-
- public void setVariableChange(String name, Object value) {
- variableChanges.put(name, value);
- }
-
- public Map<String, Object> getVariableChanges() {
- return variableChanges;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/NoInputStreamException.java b/src/com/vaadin/terminal/gwt/server/NoInputStreamException.java
deleted file mode 100644
index 70c3add858..0000000000
--- a/src/com/vaadin/terminal/gwt/server/NoInputStreamException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-@SuppressWarnings("serial")
-public class NoInputStreamException extends Exception {
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/NoOutputStreamException.java b/src/com/vaadin/terminal/gwt/server/NoOutputStreamException.java
deleted file mode 100644
index e4db8453b0..0000000000
--- a/src/com/vaadin/terminal/gwt/server/NoOutputStreamException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-@SuppressWarnings("serial")
-public class NoOutputStreamException extends Exception {
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
deleted file mode 100644
index 70505ab5f9..0000000000
--- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.File;
-import java.io.Serializable;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.portlet.ActionRequest;
-import javax.portlet.ActionResponse;
-import javax.portlet.EventRequest;
-import javax.portlet.EventResponse;
-import javax.portlet.MimeResponse;
-import javax.portlet.PortletConfig;
-import javax.portlet.PortletMode;
-import javax.portlet.PortletModeException;
-import javax.portlet.PortletResponse;
-import javax.portlet.PortletSession;
-import javax.portlet.PortletURL;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceRequest;
-import javax.portlet.ResourceResponse;
-import javax.portlet.StateAwareResponse;
-import javax.servlet.http.HttpSessionBindingListener;
-import javax.xml.namespace.QName;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.ExternalResource;
-import com.vaadin.ui.Root;
-
-/**
- * TODO Write documentation, fix JavaDoc tags.
- *
- * This is automatically registered as a {@link HttpSessionBindingListener} when
- * {@link PortletSession#setAttribute()} is called with the context as value.
- *
- * @author peholmst
- */
-@SuppressWarnings("serial")
-public class PortletApplicationContext2 extends AbstractWebApplicationContext {
-
- protected Map<Application, Set<PortletListener>> portletListeners = new HashMap<Application, Set<PortletListener>>();
-
- protected transient PortletSession session;
- protected transient PortletConfig portletConfig;
-
- protected HashMap<String, Application> portletWindowIdToApplicationMap = new HashMap<String, Application>();
-
- private transient PortletResponse response;
-
- private final Map<String, QName> eventActionDestinationMap = new HashMap<String, QName>();
- private final Map<String, Serializable> eventActionValueMap = new HashMap<String, Serializable>();
-
- private final Map<String, String> sharedParameterActionNameMap = new HashMap<String, String>();
- private final Map<String, String> sharedParameterActionValueMap = new HashMap<String, String>();
-
- @Override
- public File getBaseDirectory() {
- String resultPath = session.getPortletContext().getRealPath("/");
- if (resultPath != null) {
- return new File(resultPath);
- } else {
- try {
- final URL url = session.getPortletContext().getResource("/");
- return new File(url.getFile());
- } catch (final Exception e) {
- // FIXME: Handle exception
- getLogger()
- .log(Level.INFO,
- "Cannot access base directory, possible security issue "
- + "with Application Server or Servlet Container",
- e);
- }
- }
- return null;
- }
-
- protected PortletCommunicationManager getApplicationManager(
- Application application) {
- PortletCommunicationManager mgr = (PortletCommunicationManager) applicationToAjaxAppMgrMap
- .get(application);
-
- if (mgr == null) {
- // Creates a new manager
- mgr = createPortletCommunicationManager(application);
- applicationToAjaxAppMgrMap.put(application, mgr);
- }
- return mgr;
- }
-
- protected PortletCommunicationManager createPortletCommunicationManager(
- Application application) {
- return new PortletCommunicationManager(application);
- }
-
- public static PortletApplicationContext2 getApplicationContext(
- PortletSession session) {
- Object cxattr = session.getAttribute(PortletApplicationContext2.class
- .getName());
- PortletApplicationContext2 cx = null;
- // can be false also e.g. if old context comes from another
- // classloader when using
- // <private-session-attributes>false</private-session-attributes>
- // and redeploying the portlet - see #7461
- if (cxattr instanceof PortletApplicationContext2) {
- cx = (PortletApplicationContext2) cxattr;
- }
- if (cx == null) {
- cx = new PortletApplicationContext2();
- session.setAttribute(PortletApplicationContext2.class.getName(), cx);
- }
- if (cx.session == null) {
- cx.session = session;
- }
- return cx;
- }
-
- @Override
- protected void removeApplication(Application application) {
- super.removeApplication(application);
- // values() is backed by map, removes the key-value pair from the map
- portletWindowIdToApplicationMap.values().remove(application);
- }
-
- protected void addApplication(Application application,
- String portletWindowId) {
- applications.add(application);
- portletWindowIdToApplicationMap.put(portletWindowId, application);
- }
-
- public Application getApplicationForWindowId(String portletWindowId) {
- return portletWindowIdToApplicationMap.get(portletWindowId);
- }
-
- public PortletSession getPortletSession() {
- return session;
- }
-
- public PortletConfig getPortletConfig() {
- return portletConfig;
- }
-
- public void setPortletConfig(PortletConfig config) {
- portletConfig = config;
- }
-
- public void addPortletListener(Application app, PortletListener listener) {
- Set<PortletListener> l = portletListeners.get(app);
- if (l == null) {
- l = new LinkedHashSet<PortletListener>();
- portletListeners.put(app, l);
- }
- l.add(listener);
- }
-
- public void removePortletListener(Application app, PortletListener listener) {
- Set<PortletListener> l = portletListeners.get(app);
- if (l != null) {
- l.remove(listener);
- }
- }
-
- public void firePortletRenderRequest(Application app, Root root,
- RenderRequest request, RenderResponse response) {
- Set<PortletListener> listeners = portletListeners.get(app);
- if (listeners != null) {
- for (PortletListener l : listeners) {
- l.handleRenderRequest(request, new RestrictedRenderResponse(
- response), root);
- }
- }
- }
-
- public void firePortletActionRequest(Application app, Root root,
- ActionRequest request, ActionResponse response) {
- String key = request.getParameter(ActionRequest.ACTION_NAME);
- if (eventActionDestinationMap.containsKey(key)) {
- // this action request is only to send queued portlet events
- response.setEvent(eventActionDestinationMap.get(key),
- eventActionValueMap.get(key));
- // cleanup
- eventActionDestinationMap.remove(key);
- eventActionValueMap.remove(key);
- } else if (sharedParameterActionNameMap.containsKey(key)) {
- // this action request is only to set shared render parameters
- response.setRenderParameter(sharedParameterActionNameMap.get(key),
- sharedParameterActionValueMap.get(key));
- // cleanup
- sharedParameterActionNameMap.remove(key);
- sharedParameterActionValueMap.remove(key);
- } else {
- // normal action request, notify listeners
- Set<PortletListener> listeners = portletListeners.get(app);
- if (listeners != null) {
- for (PortletListener l : listeners) {
- l.handleActionRequest(request, response, root);
- }
- }
- }
- }
-
- public void firePortletEventRequest(Application app, Root root,
- EventRequest request, EventResponse response) {
- Set<PortletListener> listeners = portletListeners.get(app);
- if (listeners != null) {
- for (PortletListener l : listeners) {
- l.handleEventRequest(request, response, root);
- }
- }
- }
-
- public void firePortletResourceRequest(Application app, Root root,
- ResourceRequest request, ResourceResponse response) {
- Set<PortletListener> listeners = portletListeners.get(app);
- if (listeners != null) {
- for (PortletListener l : listeners) {
- l.handleResourceRequest(request, response, root);
- }
- }
- }
-
- public interface PortletListener extends Serializable {
-
- public void handleRenderRequest(RenderRequest request,
- RenderResponse response, Root root);
-
- public void handleActionRequest(ActionRequest request,
- ActionResponse response, Root root);
-
- public void handleEventRequest(EventRequest request,
- EventResponse response, Root root);
-
- public void handleResourceRequest(ResourceRequest request,
- ResourceResponse response, Root root);
- }
-
- /**
- * This is for use by {@link AbstractApplicationPortlet} only.
- *
- * TODO cleaner implementation, now "semi-static"!
- *
- * @param mimeResponse
- */
- void setResponse(PortletResponse response) {
- this.response = response;
- }
-
- /**
- * Creates a new action URL.
- *
- * @param action
- * @return action URL or null if called outside a MimeRequest (outside a
- * UIDL request or similar)
- */
- public PortletURL generateActionURL(String action) {
- PortletURL url = null;
- if (response instanceof MimeResponse) {
- url = ((MimeResponse) response).createActionURL();
- url.setParameter("javax.portlet.action", action);
- } else {
- return null;
- }
- return url;
- }
-
- /**
- * Sends a portlet event to the indicated destination.
- *
- * Internally, an action may be created and opened, as an event cannot be
- * sent directly from all types of requests.
- *
- * The event destinations and values need to be kept in the context until
- * sent. Any memory leaks if the action fails are limited to the session.
- *
- * Event names for events sent and received by a portlet need to be declared
- * in portlet.xml .
- *
- * @param root
- * a window in which a temporary action URL can be opened if
- * necessary
- * @param name
- * event name
- * @param value
- * event value object that is Serializable and, if appropriate,
- * has a valid JAXB annotation
- */
- public void sendPortletEvent(Root root, QName name, Serializable value)
- throws IllegalStateException {
- if (response instanceof MimeResponse) {
- String actionKey = "" + System.currentTimeMillis();
- while (eventActionDestinationMap.containsKey(actionKey)) {
- actionKey = actionKey + ".";
- }
- PortletURL actionUrl = generateActionURL(actionKey);
- if (actionUrl != null) {
- eventActionDestinationMap.put(actionKey, name);
- eventActionValueMap.put(actionKey, value);
- root.getPage().open(new ExternalResource(actionUrl.toString()));
- } else {
- // this should never happen as we already know the response is a
- // MimeResponse
- throw new IllegalStateException(
- "Portlet events can only be sent from a portlet request");
- }
- } else if (response instanceof StateAwareResponse) {
- ((StateAwareResponse) response).setEvent(name, value);
- } else {
- throw new IllegalStateException(
- "Portlet events can only be sent from a portlet request");
- }
- }
-
- /**
- * Sets a shared portlet parameter.
- *
- * Internally, an action may be created and opened, as shared parameters
- * cannot be set directly from all types of requests.
- *
- * The parameters and values need to be kept in the context until sent. Any
- * memory leaks if the action fails are limited to the session.
- *
- * Shared parameters set or read by a portlet need to be declared in
- * portlet.xml .
- *
- * @param root
- * a window in which a temporary action URL can be opened if
- * necessary
- * @param name
- * parameter identifier
- * @param value
- * parameter value
- */
- public void setSharedRenderParameter(Root root, String name, String value)
- throws IllegalStateException {
- if (response instanceof MimeResponse) {
- String actionKey = "" + System.currentTimeMillis();
- while (sharedParameterActionNameMap.containsKey(actionKey)) {
- actionKey = actionKey + ".";
- }
- PortletURL actionUrl = generateActionURL(actionKey);
- if (actionUrl != null) {
- sharedParameterActionNameMap.put(actionKey, name);
- sharedParameterActionValueMap.put(actionKey, value);
- root.getPage().open(new ExternalResource(actionUrl.toString()));
- } else {
- // this should never happen as we already know the response is a
- // MimeResponse
- throw new IllegalStateException(
- "Shared parameters can only be set from a portlet request");
- }
- } else if (response instanceof StateAwareResponse) {
- ((StateAwareResponse) response).setRenderParameter(name, value);
- } else {
- throw new IllegalStateException(
- "Shared parameters can only be set from a portlet request");
- }
- }
-
- /**
- * Sets the portlet mode. This may trigger a new render request.
- *
- * Portlet modes used by a portlet need to be declared in portlet.xml .
- *
- * @param root
- * a window in which the render URL can be opened if necessary
- * @param portletMode
- * the portlet mode to switch to
- * @throws PortletModeException
- * if the portlet mode is not allowed for some reason
- * (configuration, permissions etc.)
- */
- public void setPortletMode(Root root, PortletMode portletMode)
- throws IllegalStateException, PortletModeException {
- if (response instanceof MimeResponse) {
- PortletURL url = ((MimeResponse) response).createRenderURL();
- url.setPortletMode(portletMode);
- throw new RuntimeException("Root.open has not yet been implemented");
- // root.open(new ExternalResource(url.toString()));
- } else if (response instanceof StateAwareResponse) {
- ((StateAwareResponse) response).setPortletMode(portletMode);
- } else {
- throw new IllegalStateException(
- "Portlet mode can only be changed from a portlet request");
- }
- }
-
- private Logger getLogger() {
- return Logger.getLogger(PortletApplicationContext2.class.getName());
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java
deleted file mode 100644
index 39c27d05fe..0000000000
--- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.portlet.MimeResponse;
-import javax.portlet.PortletContext;
-import javax.portlet.PortletRequest;
-import javax.portlet.PortletResponse;
-import javax.portlet.RenderRequest;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceURL;
-
-import com.vaadin.Application;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.external.json.JSONObject;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConfiguration;
-import com.vaadin.ui.Root;
-
-/**
- * TODO document me!
- *
- * @author peholmst
- *
- */
-@SuppressWarnings("serial")
-public class PortletCommunicationManager extends AbstractCommunicationManager {
-
- public PortletCommunicationManager(Application application) {
- super(application);
- }
-
- @Override
- protected BootstrapHandler createBootstrapHandler() {
- return new BootstrapHandler() {
- @Override
- public boolean handleRequest(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException {
- PortletRequest portletRequest = WrappedPortletRequest.cast(
- request).getPortletRequest();
- if (portletRequest instanceof RenderRequest) {
- return super.handleRequest(application, request, response);
- } else {
- return false;
- }
- }
-
- @Override
- protected String getApplicationId(BootstrapContext context) {
- PortletRequest portletRequest = WrappedPortletRequest.cast(
- context.getRequest()).getPortletRequest();
- /*
- * We need to generate a unique ID because some portals already
- * create a DIV with the portlet's Window ID as the DOM ID.
- */
- return "v-" + portletRequest.getWindowID();
- }
-
- @Override
- protected String getAppUri(BootstrapContext context) {
- return getRenderResponse(context).createActionURL().toString();
- }
-
- private RenderResponse getRenderResponse(BootstrapContext context) {
- PortletResponse response = ((WrappedPortletResponse) context
- .getResponse()).getPortletResponse();
-
- RenderResponse renderResponse = (RenderResponse) response;
- return renderResponse;
- }
-
- @Override
- protected JSONObject getDefaultParameters(BootstrapContext context)
- throws JSONException {
- /*
- * We need this in order to get uploads to work. TODO this is
- * not needed for uploads anymore, check if this is needed for
- * some other things
- */
- JSONObject defaults = super.getDefaultParameters(context);
-
- ResourceURL portletResourceUrl = getRenderResponse(context)
- .createResourceURL();
- portletResourceUrl
- .setResourceID(AbstractApplicationPortlet.RESOURCE_URL_ID);
- defaults.put(ApplicationConfiguration.PORTLET_RESOUCE_URL_BASE,
- portletResourceUrl.toString());
-
- defaults.put("pathInfo", "");
-
- return defaults;
- }
-
- @Override
- protected void appendMainScriptTagContents(
- BootstrapContext context, StringBuilder builder)
- throws JSONException, IOException {
- // fixed base theme to use - all portal pages with Vaadin
- // applications will load this exactly once
- String portalTheme = WrappedPortletRequest
- .cast(context.getRequest())
- .getPortalProperty(
- AbstractApplicationPortlet.PORTAL_PARAMETER_VAADIN_THEME);
- if (portalTheme != null
- && !portalTheme.equals(context.getThemeName())) {
- String portalThemeUri = getThemeUri(context, portalTheme);
- // XSS safe - originates from portal properties
- builder.append("vaadin.loadTheme('" + portalThemeUri
- + "');");
- }
-
- super.appendMainScriptTagContents(context, builder);
- }
-
- @Override
- protected String getMainDivStyle(BootstrapContext context) {
- DeploymentConfiguration deploymentConfiguration = context
- .getRequest().getDeploymentConfiguration();
- return deploymentConfiguration.getApplicationOrSystemProperty(
- AbstractApplicationPortlet.PORTLET_PARAMETER_STYLE,
- null);
- }
-
- @Override
- protected String getInitialUIDL(WrappedRequest request, Root root)
- throws PaintException, JSONException {
- return PortletCommunicationManager.this.getInitialUIDL(request,
- root);
- }
-
- @Override
- protected JSONObject getApplicationParameters(
- BootstrapContext context) throws JSONException,
- PaintException {
- JSONObject parameters = super.getApplicationParameters(context);
- WrappedPortletResponse wrappedPortletResponse = (WrappedPortletResponse) context
- .getResponse();
- MimeResponse portletResponse = (MimeResponse) wrappedPortletResponse
- .getPortletResponse();
- ResourceURL resourceURL = portletResponse.createResourceURL();
- resourceURL.setResourceID("browserDetails");
- parameters.put("browserDetailsUrl", resourceURL.toString());
- return parameters;
- }
-
- };
-
- }
-
- @Override
- protected InputStream getThemeResourceAsStream(Root root, String themeName,
- String resource) {
- PortletApplicationContext2 context = (PortletApplicationContext2) root
- .getApplication().getContext();
- PortletContext portletContext = context.getPortletSession()
- .getPortletContext();
- return portletContext.getResourceAsStream("/"
- + AbstractApplicationPortlet.THEME_DIRECTORY_PATH + themeName
- + "/" + resource);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java b/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java
deleted file mode 100644
index 8a30f5c1d4..0000000000
--- a/src/com/vaadin/terminal/gwt/server/PortletRequestListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-import javax.portlet.PortletRequest;
-import javax.portlet.PortletResponse;
-import javax.servlet.Filter;
-
-import com.vaadin.Application;
-import com.vaadin.service.ApplicationContext.TransactionListener;
-import com.vaadin.terminal.Terminal;
-
-/**
- * An {@link Application} that implements this interface gets notified of
- * request start and end by the terminal. It is quite similar to the
- * {@link HttpServletRequestListener}, but the parameters are Portlet specific.
- * If an Application is deployed as both a Servlet and a Portlet, one most
- * likely needs to implement both.
- * <p>
- * Only JSR 286 style Portlets are supported.
- * <p>
- * The interface can be used for several helper tasks including:
- * <ul>
- * <li>Opening and closing database connections
- * <li>Implementing {@link ThreadLocal}
- * <li>Inter-portlet communication
- * </ul>
- * <p>
- * Alternatives for implementing similar features are are Servlet {@link Filter}
- * s and {@link TransactionListener}s in Vaadin.
- *
- * @since 6.2
- * @see HttpServletRequestListener
- */
-public interface PortletRequestListener extends Serializable {
-
- /**
- * This method is called before {@link Terminal} applies the request to
- * Application.
- *
- * @param requestData
- * the {@link PortletRequest} about to change Application state
- */
- public void onRequestStart(PortletRequest request, PortletResponse response);
-
- /**
- * This method is called at the end of each request.
- *
- * @param requestData
- * the {@link PortletRequest}
- */
- public void onRequestEnd(PortletRequest request, PortletResponse response);
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/RequestTimer.java b/src/com/vaadin/terminal/gwt/server/RequestTimer.java
deleted file mode 100644
index 6c0edec466..0000000000
--- a/src/com/vaadin/terminal/gwt/server/RequestTimer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-/**
- * Times the handling of requests and stores the information as an attribute in
- * the request. The timing info is later passed on to the client in the UIDL and
- * the client provides JavaScript API for accessing this data from e.g.
- * TestBench.
- *
- * @author Jonatan Kronqvist / Vaadin Ltd
- */
-public class RequestTimer implements Serializable {
- private long requestStartTime = 0;
-
- /**
- * Starts the timing of a request. This should be called before any
- * processing of the request.
- */
- public void start() {
- requestStartTime = System.nanoTime();
- }
-
- /**
- * Stops the timing of a request. This should be called when all processing
- * of a request has finished.
- *
- * @param context
- */
- public void stop(AbstractWebApplicationContext context) {
- // Measure and store the total handling time. This data can be
- // used in TestBench 3 tests.
- long time = (System.nanoTime() - requestStartTime) / 1000000;
-
- // The timings must be stored in the context, since a new
- // RequestTimer is created for every request.
- context.setLastRequestTime(time);
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ResourceReference.java b/src/com/vaadin/terminal/gwt/server/ResourceReference.java
deleted file mode 100644
index 2104ad4b87..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ResourceReference.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.Application;
-import com.vaadin.shared.communication.URLReference;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.ExternalResource;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.ThemeResource;
-
-public class ResourceReference extends URLReference {
-
- private Resource resource;
-
- public ResourceReference(Resource resource) {
- this.resource = resource;
- }
-
- public Resource getResource() {
- return resource;
- }
-
- @Override
- public String getURL() {
- if (resource instanceof ExternalResource) {
- return ((ExternalResource) resource).getURL();
- } else if (resource instanceof ApplicationResource) {
- final ApplicationResource r = (ApplicationResource) resource;
- final Application a = r.getApplication();
- if (a == null) {
- throw new RuntimeException(
- "An ApplicationResource ("
- + r.getClass().getName()
- + " must be attached to an application when it is sent to the client.");
- }
- final String uri = a.getRelativeLocation(r);
- return uri;
- } else if (resource instanceof ThemeResource) {
- final String uri = "theme://"
- + ((ThemeResource) resource).getResourceId();
- return uri;
- } else {
- throw new RuntimeException(getClass().getSimpleName()
- + " does not support resources of type: "
- + resource.getClass().getName());
- }
-
- }
-
- public static ResourceReference create(Resource resource) {
- if (resource == null) {
- return null;
- } else {
- return new ResourceReference(resource);
- }
- }
-
- public static Resource getResource(URLReference reference) {
- if (reference == null) {
- return null;
- }
- assert reference instanceof ResourceReference;
- return ((ResourceReference) reference).getResource();
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/RestrictedRenderResponse.java b/src/com/vaadin/terminal/gwt/server/RestrictedRenderResponse.java
deleted file mode 100644
index 9fdffbf9a5..0000000000
--- a/src/com/vaadin/terminal/gwt/server/RestrictedRenderResponse.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Locale;
-
-import javax.portlet.CacheControl;
-import javax.portlet.PortletMode;
-import javax.portlet.PortletURL;
-import javax.portlet.RenderResponse;
-import javax.portlet.ResourceURL;
-import javax.servlet.http.Cookie;
-
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Element;
-
-/**
- * Read-only wrapper for a {@link RenderResponse}.
- *
- * Only for use by {@link PortletApplicationContext} and
- * {@link PortletApplicationContext2}.
- */
-class RestrictedRenderResponse implements RenderResponse, Serializable {
-
- private RenderResponse response;
-
- RestrictedRenderResponse(RenderResponse response) {
- this.response = response;
- }
-
- @Override
- public void addProperty(String key, String value) {
- response.addProperty(key, value);
- }
-
- @Override
- public PortletURL createActionURL() {
- return response.createActionURL();
- }
-
- @Override
- public PortletURL createRenderURL() {
- return response.createRenderURL();
- }
-
- @Override
- public String encodeURL(String path) {
- return response.encodeURL(path);
- }
-
- @Override
- public void flushBuffer() throws IOException {
- // NOP
- // TODO throw?
- }
-
- @Override
- public int getBufferSize() {
- return response.getBufferSize();
- }
-
- @Override
- public String getCharacterEncoding() {
- return response.getCharacterEncoding();
- }
-
- @Override
- public String getContentType() {
- return response.getContentType();
- }
-
- @Override
- public Locale getLocale() {
- return response.getLocale();
- }
-
- @Override
- public String getNamespace() {
- return response.getNamespace();
- }
-
- @Override
- public OutputStream getPortletOutputStream() throws IOException {
- // write forbidden
- return null;
- }
-
- @Override
- public PrintWriter getWriter() throws IOException {
- // write forbidden
- return null;
- }
-
- @Override
- public boolean isCommitted() {
- return response.isCommitted();
- }
-
- @Override
- public void reset() {
- // NOP
- // TODO throw?
- }
-
- @Override
- public void resetBuffer() {
- // NOP
- // TODO throw?
- }
-
- @Override
- public void setBufferSize(int size) {
- // NOP
- // TODO throw?
- }
-
- @Override
- public void setContentType(String type) {
- // NOP
- // TODO throw?
- }
-
- @Override
- public void setProperty(String key, String value) {
- response.setProperty(key, value);
- }
-
- @Override
- public void setTitle(String title) {
- response.setTitle(title);
- }
-
- @Override
- public void setNextPossiblePortletModes(Collection<PortletMode> portletModes) {
- // NOP
- // TODO throw?
- }
-
- @Override
- public ResourceURL createResourceURL() {
- return response.createResourceURL();
- }
-
- @Override
- public CacheControl getCacheControl() {
- return response.getCacheControl();
- }
-
- @Override
- public void addProperty(Cookie cookie) {
- // NOP
- // TODO throw?
- }
-
- @Override
- public void addProperty(String key, Element element) {
- // NOP
- // TODO throw?
- }
-
- @Override
- public Element createElement(String tagName) throws DOMException {
- // NOP
- return null;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/RpcManager.java b/src/com/vaadin/terminal/gwt/server/RpcManager.java
deleted file mode 100644
index 026c847e2b..0000000000
--- a/src/com/vaadin/terminal/gwt/server/RpcManager.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-/**
- * Server side RPC manager that can invoke methods based on RPC calls received
- * from the client.
- *
- * @since 7.0
- */
-public interface RpcManager extends Serializable {
- public void applyInvocation(ServerRpcMethodInvocation invocation)
- throws RpcInvocationException;
-
- /**
- * Wrapper exception for exceptions which occur during invocation of an RPC
- * call
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0
- *
- */
- public static class RpcInvocationException extends Exception {
-
- public RpcInvocationException() {
- super();
- }
-
- public RpcInvocationException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public RpcInvocationException(String message) {
- super(message);
- }
-
- public RpcInvocationException(Throwable cause) {
- super(cause);
- }
-
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/RpcTarget.java b/src/com/vaadin/terminal/gwt/server/RpcTarget.java
deleted file mode 100644
index b280f5c6b5..0000000000
--- a/src/com/vaadin/terminal/gwt/server/RpcTarget.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.VariableOwner;
-
-/**
- * Marker interface for server side classes that can receive RPC calls.
- *
- * This plays a role similar to that of {@link VariableOwner}.
- *
- * @since 7.0
- */
-public interface RpcTarget extends Serializable {
- /**
- * Returns the RPC manager instance to use when receiving calls for an RPC
- * interface.
- *
- * @param rpcInterface
- * interface for which the call was made
- * @return RpcManager or null if none found for the interface
- */
- public RpcManager getRpcManager(Class<?> rpcInterface);
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ServerRpcManager.java b/src/com/vaadin/terminal/gwt/server/ServerRpcManager.java
deleted file mode 100644
index 1c7af82a36..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ServerRpcManager.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.shared.Connector;
-
-/**
- * Server side RPC manager that handles RPC calls coming from the client.
- *
- * Each {@link RpcTarget} (typically a {@link ClientConnector}) should have its
- * own instance of {@link ServerRpcManager} if it wants to receive RPC calls
- * from the client.
- *
- * @since 7.0
- */
-public class ServerRpcManager<T> implements RpcManager {
-
- private final T implementation;
- private final Class<T> rpcInterface;
-
- private static final Map<Class<?>, Class<?>> boxedTypes = new HashMap<Class<?>, Class<?>>();
- static {
- try {
- Class<?>[] boxClasses = new Class<?>[] { Boolean.class, Byte.class,
- Short.class, Character.class, Integer.class, Long.class,
- Float.class, Double.class };
- for (Class<?> boxClass : boxClasses) {
- Field typeField = boxClass.getField("TYPE");
- Class<?> primitiveType = (Class<?>) typeField.get(boxClass);
- boxedTypes.put(primitiveType, boxClass);
- }
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Create a RPC manager for an RPC target.
- *
- * @param target
- * RPC call target (normally a {@link Connector})
- * @param implementation
- * RPC interface implementation for the target
- * @param rpcInterface
- * RPC interface type
- */
- public ServerRpcManager(T implementation, Class<T> rpcInterface) {
- this.implementation = implementation;
- this.rpcInterface = rpcInterface;
- }
-
- /**
- * Invoke a method in a server side RPC target class. This method is to be
- * used by the RPC framework and unit testing tools only.
- *
- * @param target
- * non-null target of the RPC call
- * @param invocation
- * method invocation to perform
- * @throws RpcInvocationException
- */
- public static void applyInvocation(RpcTarget target,
- ServerRpcMethodInvocation invocation) throws RpcInvocationException {
- RpcManager manager = target.getRpcManager(invocation
- .getInterfaceClass());
- if (manager != null) {
- manager.applyInvocation(invocation);
- } else {
- getLogger()
- .log(Level.WARNING,
- "RPC call received for RpcTarget "
- + target.getClass().getName()
- + " ("
- + invocation.getConnectorId()
- + ") but the target has not registered any RPC interfaces");
- }
- }
-
- /**
- * Returns the RPC interface implementation for the RPC target.
- *
- * @return RPC interface implementation
- */
- protected T getImplementation() {
- return implementation;
- }
-
- /**
- * Returns the RPC interface type managed by this RPC manager instance.
- *
- * @return RPC interface type
- */
- protected Class<T> getRpcInterface() {
- return rpcInterface;
- }
-
- /**
- * Invoke a method in a server side RPC target class. This method is to be
- * used by the RPC framework and unit testing tools only.
- *
- * @param invocation
- * method invocation to perform
- */
- @Override
- public void applyInvocation(ServerRpcMethodInvocation invocation)
- throws RpcInvocationException {
- Method method = invocation.getMethod();
- Class<?>[] parameterTypes = method.getParameterTypes();
- Object[] args = new Object[parameterTypes.length];
- Object[] arguments = invocation.getParameters();
- for (int i = 0; i < args.length; i++) {
- // no conversion needed for basic cases
- // Class<?> type = parameterTypes[i];
- // if (type.isPrimitive()) {
- // type = boxedTypes.get(type);
- // }
- args[i] = arguments[i];
- }
- try {
- method.invoke(implementation, args);
- } catch (Exception e) {
- throw new RpcInvocationException("Unable to invoke method "
- + invocation.getMethodName() + " in "
- + invocation.getInterfaceName(), e);
- }
- }
-
- private static Logger getLogger() {
- return Logger.getLogger(ServerRpcManager.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ServerRpcMethodInvocation.java b/src/com/vaadin/terminal/gwt/server/ServerRpcMethodInvocation.java
deleted file mode 100644
index ff81a27596..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ServerRpcMethodInvocation.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import com.vaadin.shared.communication.MethodInvocation;
-import com.vaadin.shared.communication.ServerRpc;
-
-public class ServerRpcMethodInvocation extends MethodInvocation {
-
- private static final Map<String, Method> invocationMethodCache = new ConcurrentHashMap<String, Method>(
- 128, 0.75f, 1);
-
- private final Method method;
-
- private Class<? extends ServerRpc> interfaceClass;
-
- public ServerRpcMethodInvocation(String connectorId, String interfaceName,
- String methodName, int parameterCount) {
- super(connectorId, interfaceName, methodName);
-
- interfaceClass = findClass();
- method = findInvocationMethod(interfaceClass, methodName,
- parameterCount);
- }
-
- private Class<? extends ServerRpc> findClass() {
- try {
- Class<?> rpcInterface = Class.forName(getInterfaceName());
- if (!ServerRpc.class.isAssignableFrom(rpcInterface)) {
- throw new IllegalArgumentException("The interface "
- + getInterfaceName() + "is not a server RPC interface.");
- }
- return (Class<? extends ServerRpc>) rpcInterface;
- } catch (ClassNotFoundException e) {
- throw new IllegalArgumentException("The server RPC interface "
- + getInterfaceName() + " could not be found", e);
- } finally {
-
- }
- }
-
- public Class<? extends ServerRpc> getInterfaceClass() {
- return interfaceClass;
- }
-
- public Method getMethod() {
- return method;
- }
-
- /**
- * Tries to find the method from the cache or alternatively by invoking
- * {@link #doFindInvocationMethod(Class, String, int)} and updating the
- * cache.
- *
- * @param targetType
- * @param methodName
- * @param parameterCount
- * @return
- */
- private Method findInvocationMethod(Class<?> targetType, String methodName,
- int parameterCount) {
- // TODO currently only using method name and number of parameters as the
- // signature
- String signature = targetType.getName() + "." + methodName + "("
- + parameterCount;
- Method invocationMethod = invocationMethodCache.get(signature);
-
- if (invocationMethod == null) {
- invocationMethod = doFindInvocationMethod(targetType, methodName,
- parameterCount);
-
- if (invocationMethod != null) {
- invocationMethodCache.put(signature, invocationMethod);
- }
- }
-
- if (invocationMethod == null) {
- throw new IllegalStateException("Can't find method " + methodName
- + " with " + parameterCount + " parameters in "
- + targetType.getName());
- }
-
- return invocationMethod;
- }
-
- /**
- * Tries to find the method from the class by looping through available
- * methods.
- *
- * @param targetType
- * @param methodName
- * @param parameterCount
- * @return
- */
- private Method doFindInvocationMethod(Class<?> targetType,
- String methodName, int parameterCount) {
- Method[] methods = targetType.getMethods();
- for (Method method : methods) {
- Class<?>[] parameterTypes = method.getParameterTypes();
- if (method.getName().equals(methodName)
- && parameterTypes.length == parameterCount) {
- return method;
- }
- }
- return null;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java b/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java
deleted file mode 100644
index 2a1dc31897..0000000000
--- a/src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.vaadin.terminal.gwt.server;
-
-import java.io.Serializable;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.ui.Root;
-
-/*
- @VaadinApache2LicenseForJavaFiles@
- */
-
-class ServletPortletHelper implements Serializable {
- public static final String UPLOAD_URL_PREFIX = "APP/UPLOAD/";
-
- public static class ApplicationClassException extends Exception {
-
- public ApplicationClassException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ApplicationClassException(String message) {
- super(message);
- }
- }
-
- static Class<? extends Application> getApplicationClass(
- DeploymentConfiguration deploymentConfiguration)
- throws ApplicationClassException {
- String applicationParameter = deploymentConfiguration
- .getInitParameters().getProperty("application");
- String rootParameter = deploymentConfiguration.getInitParameters()
- .getProperty(Application.ROOT_PARAMETER);
- ClassLoader classLoader = deploymentConfiguration.getClassLoader();
-
- if (applicationParameter == null) {
-
- // Validate the parameter value
- verifyRootClass(rootParameter, classLoader);
-
- // Application can be used if a valid rootLayout is defined
- return Application.class;
- }
-
- try {
- return (Class<? extends Application>) classLoader
- .loadClass(applicationParameter);
- } catch (final ClassNotFoundException e) {
- throw new ApplicationClassException(
- "Failed to load application class: " + applicationParameter,
- e);
- }
- }
-
- private static void verifyRootClass(String className,
- ClassLoader classLoader) throws ApplicationClassException {
- if (className == null) {
- throw new ApplicationClassException(Application.ROOT_PARAMETER
- + " init parameter not defined");
- }
-
- // Check that the root layout class can be found
- try {
- Class<?> rootClass = classLoader.loadClass(className);
- if (!Root.class.isAssignableFrom(rootClass)) {
- throw new ApplicationClassException(className
- + " does not implement Root");
- }
- // Try finding a default constructor, else throw exception
- rootClass.getConstructor();
- } catch (ClassNotFoundException e) {
- throw new ApplicationClassException(className
- + " could not be loaded", e);
- } catch (SecurityException e) {
- throw new ApplicationClassException("Could not access " + className
- + " class", e);
- } catch (NoSuchMethodException e) {
- throw new ApplicationClassException(className
- + " doesn't have a public no-args constructor");
- }
- }
-
- private static boolean hasPathPrefix(WrappedRequest request, String prefix) {
- String pathInfo = request.getRequestPathInfo();
-
- if (pathInfo == null) {
- return false;
- }
-
- if (!prefix.startsWith("/")) {
- prefix = '/' + prefix;
- }
-
- if (pathInfo.startsWith(prefix)) {
- return true;
- }
-
- return false;
- }
-
- public static boolean isFileUploadRequest(WrappedRequest request) {
- return hasPathPrefix(request, UPLOAD_URL_PREFIX);
- }
-
- public static boolean isConnectorResourceRequest(WrappedRequest request) {
- return hasPathPrefix(request,
- ApplicationConnection.CONNECTOR_RESOURCE_PREFIX + "/");
- }
-
- public static boolean isUIDLRequest(WrappedRequest request) {
- return hasPathPrefix(request, ApplicationConnection.UIDL_REQUEST_PATH);
- }
-
- public static boolean isApplicationResourceRequest(WrappedRequest request) {
- return hasPathPrefix(request, ApplicationConnection.APP_REQUEST_PATH);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/SessionExpiredException.java b/src/com/vaadin/terminal/gwt/server/SessionExpiredException.java
deleted file mode 100644
index 37b76de443..0000000000
--- a/src/com/vaadin/terminal/gwt/server/SessionExpiredException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-@SuppressWarnings("serial")
-public class SessionExpiredException extends Exception {
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/StreamingEndEventImpl.java b/src/com/vaadin/terminal/gwt/server/StreamingEndEventImpl.java
deleted file mode 100644
index 0d4963bd7d..0000000000
--- a/src/com/vaadin/terminal/gwt/server/StreamingEndEventImpl.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.terminal.StreamVariable.StreamingEndEvent;
-
-@SuppressWarnings("serial")
-final class StreamingEndEventImpl extends AbstractStreamingEvent implements
- StreamingEndEvent {
-
- public StreamingEndEventImpl(String filename, String type, long totalBytes) {
- super(filename, type, totalBytes, totalBytes);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/StreamingErrorEventImpl.java b/src/com/vaadin/terminal/gwt/server/StreamingErrorEventImpl.java
deleted file mode 100644
index 6ab3df2789..0000000000
--- a/src/com/vaadin/terminal/gwt/server/StreamingErrorEventImpl.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.terminal.StreamVariable.StreamingErrorEvent;
-
-@SuppressWarnings("serial")
-final class StreamingErrorEventImpl extends AbstractStreamingEvent implements
- StreamingErrorEvent {
-
- private final Exception exception;
-
- public StreamingErrorEventImpl(final String filename, final String type,
- long contentLength, long bytesReceived, final Exception exception) {
- super(filename, type, contentLength, bytesReceived);
- this.exception = exception;
- }
-
- @Override
- public final Exception getException() {
- return exception;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/StreamingProgressEventImpl.java b/src/com/vaadin/terminal/gwt/server/StreamingProgressEventImpl.java
deleted file mode 100644
index cfa7a1b98d..0000000000
--- a/src/com/vaadin/terminal/gwt/server/StreamingProgressEventImpl.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.terminal.StreamVariable.StreamingProgressEvent;
-
-@SuppressWarnings("serial")
-final class StreamingProgressEventImpl extends AbstractStreamingEvent implements
- StreamingProgressEvent {
-
- public StreamingProgressEventImpl(final String filename, final String type,
- long contentLength, long bytesReceived) {
- super(filename, type, contentLength, bytesReceived);
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/StreamingStartEventImpl.java b/src/com/vaadin/terminal/gwt/server/StreamingStartEventImpl.java
deleted file mode 100644
index 274d05e111..0000000000
--- a/src/com/vaadin/terminal/gwt/server/StreamingStartEventImpl.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import com.vaadin.terminal.StreamVariable.StreamingStartEvent;
-
-@SuppressWarnings("serial")
-final class StreamingStartEventImpl extends AbstractStreamingEvent implements
- StreamingStartEvent {
-
- private boolean disposed;
-
- public StreamingStartEventImpl(final String filename, final String type,
- long contentLength) {
- super(filename, type, contentLength, 0);
- }
-
- @Override
- public void disposeStreamVariable() {
- disposed = true;
- }
-
- boolean isDisposed() {
- return disposed;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/SystemMessageException.java b/src/com/vaadin/terminal/gwt/server/SystemMessageException.java
deleted file mode 100644
index d15ff8a7ef..0000000000
--- a/src/com/vaadin/terminal/gwt/server/SystemMessageException.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-@SuppressWarnings("serial")
-public class SystemMessageException extends RuntimeException {
-
- /**
- * Cause of the method exception
- */
- private Throwable cause;
-
- /**
- * Constructs a new <code>SystemMessageException</code> with the specified
- * detail message.
- *
- * @param msg
- * the detail message.
- */
- public SystemMessageException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a new <code>SystemMessageException</code> with the specified
- * detail message and cause.
- *
- * @param msg
- * the detail message.
- * @param cause
- * the cause of the exception.
- */
- public SystemMessageException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
- /**
- * Constructs a new <code>SystemMessageException</code> from another
- * exception.
- *
- * @param cause
- * the cause of the exception.
- */
- public SystemMessageException(Throwable cause) {
- this.cause = cause;
- }
-
- /**
- * @see java.lang.Throwable#getCause()
- */
- @Override
- public Throwable getCause() {
- return cause;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/UnsupportedBrowserHandler.java b/src/com/vaadin/terminal/gwt/server/UnsupportedBrowserHandler.java
deleted file mode 100644
index 5248af595e..0000000000
--- a/src/com/vaadin/terminal/gwt/server/UnsupportedBrowserHandler.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-
-/**
- * A {@link RequestHandler} that presents an informative page if the browser in
- * use is unsupported. Recognizes Chrome Frame and allow it to be used.
- *
- * <p>
- * This handler is usually added to the application by
- * {@link AbstractCommunicationManager}.
- * </p>
- */
-@SuppressWarnings("serial")
-public class UnsupportedBrowserHandler implements RequestHandler {
-
- /** Cookie used to ignore browser checks */
- public static final String FORCE_LOAD_COOKIE = "vaadinforceload=1";
-
- @Override
- public boolean handleRequest(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException {
-
- if (request.getBrowserDetails() != null) {
- // Check if the browser is supported
- // If Chrome Frame is available we'll assume it's ok
- WebBrowser b = request.getBrowserDetails().getWebBrowser();
- if (b.isTooOldToFunctionProperly() && !b.isChromeFrameCapable()) {
- // bypass if cookie set
- String c = request.getHeader("Cookie");
- if (c == null || !c.contains(FORCE_LOAD_COOKIE)) {
- writeBrowserTooOldPage(request, response);
- return true; // request handled
- }
- }
- }
-
- return false; // pass to next handler
- }
-
- /**
- * Writes a page encouraging the user to upgrade to a more current browser.
- *
- * @param request
- * @param response
- * @throws IOException
- */
- protected void writeBrowserTooOldPage(WrappedRequest request,
- WrappedResponse response) throws IOException {
- Writer page = response.getWriter();
- WebBrowser b = request.getBrowserDetails().getWebBrowser();
-
- page.write("<html><body><h1>I'm sorry, but your browser is not supported</h1>"
- + "<p>The version ("
- + b.getBrowserMajorVersion()
- + "."
- + b.getBrowserMinorVersion()
- + ") of the browser you are using "
- + " is outdated and not supported.</p>"
- + "<p>You should <b>consider upgrading</b> to a more up-to-date browser.</p> "
- + "<p>The most popular browsers are <b>"
- + " <a href=\"https://www.google.com/chrome\">Chrome</a>,"
- + " <a href=\"http://www.mozilla.com/firefox\">Firefox</a>,"
- + (b.isWindows() ? " <a href=\"http://windows.microsoft.com/en-US/internet-explorer/downloads/ie\">Internet Explorer</a>,"
- : "")
- + " <a href=\"http://www.opera.com/browser\">Opera</a>"
- + " and <a href=\"http://www.apple.com/safari\">Safari</a>.</b><br/>"
- + "Upgrading to the latest version of one of these <b>will make the web safer, faster and better looking.</b></p>"
- + (b.isIE() ? "<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js\"></script>"
- + "<p>If you can not upgrade your browser, please consider trying <a onclick=\"CFInstall.check({mode:'overlay'});return false;\" href=\"http://www.google.com/chromeframe\">Chrome Frame</a>.</p>"
- : "") //
- + "<p><sub><a onclick=\"document.cookie='"
- + FORCE_LOAD_COOKIE
- + "';window.location.reload();return false;\" href=\"#\">Continue without updating</a> (not recommended)</sub></p>"
- + "</body>\n" + "</html>");
-
- page.close();
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/UploadException.java b/src/com/vaadin/terminal/gwt/server/UploadException.java
deleted file mode 100644
index 58253da0fb..0000000000
--- a/src/com/vaadin/terminal/gwt/server/UploadException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.terminal.gwt.server;
-
-@SuppressWarnings("serial")
-public class UploadException extends Exception {
- public UploadException(Exception e) {
- super("Upload failed", e);
- }
-
- public UploadException(String msg) {
- super(msg);
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java b/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java
deleted file mode 100644
index 36c08b2ed9..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.File;
-import java.util.Enumeration;
-import java.util.HashMap;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionBindingListener;
-
-import com.vaadin.Application;
-
-/**
- * Web application context for Vaadin applications.
- *
- * This is automatically added as a {@link HttpSessionBindingListener} when
- * added to a {@link HttpSession}.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.1
- */
-@SuppressWarnings("serial")
-public class WebApplicationContext extends AbstractWebApplicationContext {
-
- protected transient HttpSession session;
- private transient boolean reinitializingSession = false;
-
- /**
- * Stores a reference to the currentRequest. Null it not inside a request.
- */
- private transient Object currentRequest = null;
-
- /**
- * Creates a new Web Application Context.
- *
- */
- protected WebApplicationContext() {
-
- }
-
- @Override
- protected void startTransaction(Application application, Object request) {
- currentRequest = request;
- super.startTransaction(application, request);
- }
-
- @Override
- protected void endTransaction(Application application, Object request) {
- super.endTransaction(application, request);
- currentRequest = null;
- }
-
- @Override
- public void valueUnbound(HttpSessionBindingEvent event) {
- if (!reinitializingSession) {
- // Avoid closing the application if we are only reinitializing the
- // session. Closing the application would cause the state to be lost
- // and a new application to be created, which is not what we want.
- super.valueUnbound(event);
- }
- }
-
- /**
- * Discards the current session and creates a new session with the same
- * contents. The purpose of this is to introduce a new session key in order
- * to avoid session fixation attacks.
- */
- @SuppressWarnings("unchecked")
- public void reinitializeSession() {
-
- HttpSession oldSession = getHttpSession();
-
- // Stores all attributes (security key, reference to this context
- // instance) so they can be added to the new session
- HashMap<String, Object> attrs = new HashMap<String, Object>();
- for (Enumeration<String> e = oldSession.getAttributeNames(); e
- .hasMoreElements();) {
- String name = e.nextElement();
- attrs.put(name, oldSession.getAttribute(name));
- }
-
- // Invalidate the current session, set flag to avoid call to
- // valueUnbound
- reinitializingSession = true;
- oldSession.invalidate();
- reinitializingSession = false;
-
- // Create a new session
- HttpSession newSession = ((HttpServletRequest) currentRequest)
- .getSession();
-
- // Restores all attributes (security key, reference to this context
- // instance)
- for (String name : attrs.keySet()) {
- newSession.setAttribute(name, attrs.get(name));
- }
-
- // Update the "current session" variable
- session = newSession;
- }
-
- /**
- * Gets the application context base directory.
- *
- * @see com.vaadin.service.ApplicationContext#getBaseDirectory()
- */
- @Override
- public File getBaseDirectory() {
- final String realPath = ApplicationServlet.getResourcePath(
- session.getServletContext(), "/");
- if (realPath == null) {
- return null;
- }
- return new File(realPath);
- }
-
- /**
- * Gets the http-session application is running in.
- *
- * @return HttpSession this application context resides in.
- */
- public HttpSession getHttpSession() {
- return session;
- }
-
- /**
- * Gets the application context for an HttpSession.
- *
- * @param session
- * the HTTP session.
- * @return the application context for HttpSession.
- */
- static public WebApplicationContext getApplicationContext(
- HttpSession session) {
- WebApplicationContext cx = (WebApplicationContext) session
- .getAttribute(WebApplicationContext.class.getName());
- if (cx == null) {
- cx = new WebApplicationContext();
- session.setAttribute(WebApplicationContext.class.getName(), cx);
- }
- if (cx.session == null) {
- cx.session = session;
- }
- return cx;
- }
-
- protected void addApplication(Application application) {
- applications.add(application);
- }
-
- /**
- * Gets communication manager for an application.
- *
- * If this application has not been running before, a new manager is
- * created.
- *
- * @param application
- * @return CommunicationManager
- */
- public CommunicationManager getApplicationManager(Application application,
- AbstractApplicationServlet servlet) {
- CommunicationManager mgr = (CommunicationManager) applicationToAjaxAppMgrMap
- .get(application);
-
- if (mgr == null) {
- // Creates new manager
- mgr = servlet.createCommunicationManager(application);
- applicationToAjaxAppMgrMap.put(application, mgr);
- }
- return mgr;
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/WebBrowser.java b/src/com/vaadin/terminal/gwt/server/WebBrowser.java
deleted file mode 100644
index 4b92b12b66..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WebBrowser.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.util.Date;
-import java.util.Locale;
-
-import com.vaadin.shared.VBrowserDetails;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.WrappedRequest;
-
-/**
- * Class that provides information about the web browser the user is using.
- * Provides information such as browser name and version, screen resolution and
- * IP address.
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- */
-public class WebBrowser implements Terminal {
-
- private int screenHeight = 0;
- private int screenWidth = 0;
- private String browserApplication = null;
- private Locale locale;
- private String address;
- private boolean secureConnection;
- private int timezoneOffset = 0;
- private int rawTimezoneOffset = 0;
- private int dstSavings;
- private boolean dstInEffect;
- private boolean touchDevice;
-
- private VBrowserDetails browserDetails;
- private long clientServerTimeDelta;
-
- /**
- * There is no default-theme for this terminal type.
- *
- * @return Always returns null.
- */
-
- @Override
- public String getDefaultTheme() {
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Terminal#getScreenHeight()
- */
-
- @Override
- public int getScreenHeight() {
- return screenHeight;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Terminal#getScreenWidth()
- */
-
- @Override
- public int getScreenWidth() {
- return screenWidth;
- }
-
- /**
- * Get the browser user-agent string.
- *
- * @return The raw browser userAgent string
- */
- public String getBrowserApplication() {
- return browserApplication;
- }
-
- /**
- * Gets the IP-address of the web browser. If the application is running
- * inside a portlet, this method will return null.
- *
- * @return IP-address in 1.12.123.123 -format
- */
- public String getAddress() {
- return address;
- }
-
- /** Get the default locate of the browser. */
- public Locale getLocale() {
- return locale;
- }
-
- /** Is the connection made using HTTPS? */
- public boolean isSecureConnection() {
- return secureConnection;
- }
-
- /**
- * Tests whether the user is using Firefox.
- *
- * @return true if the user is using Firefox, false if the user is not using
- * Firefox or if no information on the browser is present
- */
- public boolean isFirefox() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isFirefox();
- }
-
- /**
- * Tests whether the user is using Internet Explorer.
- *
- * @return true if the user is using Internet Explorer, false if the user is
- * not using Internet Explorer or if no information on the browser
- * is present
- */
- public boolean isIE() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isIE();
- }
-
- /**
- * Tests whether the user is using Safari.
- *
- * @return true if the user is using Safari, false if the user is not using
- * Safari or if no information on the browser is present
- */
- public boolean isSafari() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isSafari();
- }
-
- /**
- * Tests whether the user is using Opera.
- *
- * @return true if the user is using Opera, false if the user is not using
- * Opera or if no information on the browser is present
- */
- public boolean isOpera() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isOpera();
- }
-
- /**
- * Tests whether the user is using Chrome.
- *
- * @return true if the user is using Chrome, false if the user is not using
- * Chrome or if no information on the browser is present
- */
- public boolean isChrome() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChrome();
- }
-
- /**
- * Tests whether the user is using Chrome Frame.
- *
- * @return true if the user is using Chrome Frame, false if the user is not
- * using Chrome or if no information on the browser is present
- */
- public boolean isChromeFrame() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChromeFrame();
- }
-
- /**
- * Tests whether the user's browser is Chrome Frame capable.
- *
- * @return true if the user can use Chrome Frame, false if the user can not
- * or if no information on the browser is present
- */
- public boolean isChromeFrameCapable() {
- if (browserDetails == null) {
- return false;
- }
-
- return browserDetails.isChromeFrameCapable();
- }
-
- /**
- * Gets the major version of the browser the user is using.
- *
- * <p>
- * Note that Internet Explorer in IE7 compatibility mode might return 8 in
- * some cases even though it should return 7.
- * </p>
- *
- * @return The major version of the browser or -1 if not known.
- */
- public int getBrowserMajorVersion() {
- if (browserDetails == null) {
- return -1;
- }
-
- return browserDetails.getBrowserMajorVersion();
- }
-
- /**
- * Gets the minor version of the browser the user is using.
- *
- * @see #getBrowserMajorVersion()
- *
- * @return The minor version of the browser or -1 if not known.
- */
- public int getBrowserMinorVersion() {
- if (browserDetails == null) {
- return -1;
- }
-
- return browserDetails.getBrowserMinorVersion();
- }
-
- /**
- * Tests whether the user is using Linux.
- *
- * @return true if the user is using Linux, false if the user is not using
- * Linux or if no information on the browser is present
- */
- public boolean isLinux() {
- return browserDetails.isLinux();
- }
-
- /**
- * Tests whether the user is using Mac OS X.
- *
- * @return true if the user is using Mac OS X, false if the user is not
- * using Mac OS X or if no information on the browser is present
- */
- public boolean isMacOSX() {
- return browserDetails.isMacOSX();
- }
-
- /**
- * Tests whether the user is using Windows.
- *
- * @return true if the user is using Windows, false if the user is not using
- * Windows or if no information on the browser is present
- */
- public boolean isWindows() {
- return browserDetails.isWindows();
- }
-
- /**
- * Returns the browser-reported TimeZone offset in milliseconds from GMT.
- * This includes possible daylight saving adjustments, to figure out which
- * TimeZone the user actually might be in, see
- * {@link #getRawTimezoneOffset()}.
- *
- * @see WebBrowser#getRawTimezoneOffset()
- * @return timezone offset in milliseconds, 0 if not available
- */
- public Integer getTimezoneOffset() {
- return timezoneOffset;
- }
-
- /**
- * Returns the browser-reported TimeZone offset in milliseconds from GMT
- * ignoring possible daylight saving adjustments that may be in effect in
- * the browser.
- * <p>
- * You can use this to figure out which TimeZones the user could actually be
- * in by calling {@link TimeZone#getAvailableIDs(int)}.
- * </p>
- * <p>
- * If {@link #getRawTimezoneOffset()} and {@link #getTimezoneOffset()}
- * returns the same value, the browser is either in a zone that does not
- * currently have daylight saving time, or in a zone that never has daylight
- * saving time.
- * </p>
- *
- * @return timezone offset in milliseconds excluding DST, 0 if not available
- */
- public Integer getRawTimezoneOffset() {
- return rawTimezoneOffset;
- }
-
- /**
- * Gets the difference in minutes between the browser's GMT TimeZone and
- * DST.
- *
- * @return the amount of minutes that the TimeZone shifts when DST is in
- * effect
- */
- public int getDSTSavings() {
- return dstSavings;
- }
-
- /**
- * Determines whether daylight savings time (DST) is currently in effect in
- * the region of the browser or not.
- *
- * @return true if the browser resides at a location that currently is in
- * DST
- */
- public boolean isDSTInEffect() {
- return dstInEffect;
- }
-
- /**
- * Returns the current date and time of the browser. This will not be
- * entirely accurate due to varying network latencies, but should provide a
- * close-enough value for most cases. Also note that the returned Date
- * object uses servers default time zone, not the clients.
- *
- * @return the current date and time of the browser.
- * @see #isDSTInEffect()
- * @see #getDSTSavings()
- * @see #getTimezoneOffset()
- */
- public Date getCurrentDate() {
- return new Date(new Date().getTime() + clientServerTimeDelta);
- }
-
- /**
- * @return true if the browser is detected to support touch events
- */
- public boolean isTouchDevice() {
- return touchDevice;
- }
-
- /**
- * For internal use by AbstractApplicationServlet/AbstractApplicationPortlet
- * only. Updates all properties in the class according to the given
- * information.
- *
- * @param sw
- * Screen width
- * @param sh
- * Screen height
- * @param tzo
- * TimeZone offset in minutes from GMT
- * @param rtzo
- * raw TimeZone offset in minutes from GMT (w/o DST adjustment)
- * @param dstSavings
- * the difference between the raw TimeZone and DST in minutes
- * @param dstInEffect
- * is DST currently active in the region or not?
- * @param curDate
- * the current date in milliseconds since the epoch
- * @param touchDevice
- */
- void updateClientSideDetails(String sw, String sh, String tzo, String rtzo,
- String dstSavings, String dstInEffect, String curDate,
- boolean touchDevice) {
- if (sw != null) {
- try {
- screenHeight = Integer.parseInt(sh);
- screenWidth = Integer.parseInt(sw);
- } catch (final NumberFormatException e) {
- screenHeight = screenWidth = 0;
- }
- }
- if (tzo != null) {
- try {
- // browser->java conversion: min->ms, reverse sign
- timezoneOffset = -Integer.parseInt(tzo) * 60 * 1000;
- } catch (final NumberFormatException e) {
- timezoneOffset = 0; // default gmt+0
- }
- }
- if (rtzo != null) {
- try {
- // browser->java conversion: min->ms, reverse sign
- rawTimezoneOffset = -Integer.parseInt(rtzo) * 60 * 1000;
- } catch (final NumberFormatException e) {
- rawTimezoneOffset = 0; // default gmt+0
- }
- }
- if (dstSavings != null) {
- try {
- // browser->java conversion: min->ms
- this.dstSavings = Integer.parseInt(dstSavings) * 60 * 1000;
- } catch (final NumberFormatException e) {
- this.dstSavings = 0; // default no savings
- }
- }
- if (dstInEffect != null) {
- this.dstInEffect = Boolean.parseBoolean(dstInEffect);
- }
- if (curDate != null) {
- try {
- long curTime = Long.parseLong(curDate);
- clientServerTimeDelta = curTime - new Date().getTime();
- } catch (final NumberFormatException e) {
- clientServerTimeDelta = 0;
- }
- }
- this.touchDevice = touchDevice;
-
- }
-
- /**
- * For internal use by AbstractApplicationServlet/AbstractApplicationPortlet
- * only. Updates all properties in the class according to the given
- * information.
- *
- * @param request
- * the wrapped request to read the information from
- */
- void updateRequestDetails(WrappedRequest request) {
- locale = request.getLocale();
- address = request.getRemoteAddr();
- secureConnection = request.isSecure();
- String agent = request.getHeader("user-agent");
-
- if (agent != null) {
- browserApplication = agent;
- browserDetails = new VBrowserDetails(agent);
- }
-
- if (request.getParameter("sw") != null) {
- updateClientSideDetails(request.getParameter("sw"),
- request.getParameter("sh"), request.getParameter("tzo"),
- request.getParameter("rtzo"), request.getParameter("dstd"),
- request.getParameter("dston"),
- request.getParameter("curdate"),
- request.getParameter("td") != null);
- }
- }
-
- /**
- * Checks if the browser is so old that it simply won't work with a Vaadin
- * application. Can be used to redirect to an alternative page, show
- * alternative content or similar.
- *
- * When this method returns true chances are very high that the browser
- * won't work and it does not make sense to direct the user to the Vaadin
- * application.
- *
- * @return true if the browser won't work, false if not the browser is
- * supported or might work
- */
- public boolean isTooOldToFunctionProperly() {
- if (browserDetails == null) {
- // Don't know, so assume it will work
- return false;
- }
-
- return browserDetails.isTooOldToFunctionProperly();
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java b/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java
deleted file mode 100644
index cf58f398af..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedRequest;
-
-/**
- * Wrapper for {@link HttpServletRequest}.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedRequest
- * @see WrappedHttpServletResponse
- */
-public class WrappedHttpServletRequest extends HttpServletRequestWrapper
- implements WrappedRequest {
-
- private final DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a http servlet request and associates with a deployment
- * configuration
- *
- * @param request
- * the http servlet request to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedHttpServletRequest(HttpServletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- super(request);
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- @Override
- public String getRequestPathInfo() {
- return getPathInfo();
- }
-
- @Override
- public int getSessionMaxInactiveInterval() {
- return getSession().getMaxInactiveInterval();
- }
-
- @Override
- public Object getSessionAttribute(String name) {
- return getSession().getAttribute(name);
- }
-
- @Override
- public void setSessionAttribute(String name, Object attribute) {
- getSession().setAttribute(name, attribute);
- }
-
- /**
- * Gets the original, unwrapped HTTP servlet request.
- *
- * @return the servlet request
- */
- public HttpServletRequest getHttpServletRequest() {
- return this;
- }
-
- @Override
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- @Override
- public BrowserDetails getBrowserDetails() {
- return new BrowserDetails() {
- @Override
- public String getUriFragment() {
- return null;
- }
-
- @Override
- public String getWindowName() {
- return null;
- }
-
- @Override
- public WebBrowser getWebBrowser() {
- WebApplicationContext context = (WebApplicationContext) Application
- .getCurrent().getContext();
- return context.getBrowser();
- }
- };
- }
-
- /**
- * Helper method to get a <code>WrappedHttpServletRequest</code> from a
- * <code>WrappedRequest</code>. Aside from casting, this method also takes
- * care of situations where there's another level of wrapping.
- *
- * @param request
- * a wrapped request
- * @return a wrapped http servlet request
- * @throws ClassCastException
- * if the wrapped request doesn't wrap a http servlet request
- */
- public static WrappedHttpServletRequest cast(WrappedRequest request) {
- if (request instanceof CombinedRequest) {
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- return (WrappedHttpServletRequest) request;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletResponse.java b/src/com/vaadin/terminal/gwt/server/WrappedHttpServletResponse.java
deleted file mode 100644
index 32b2f352a8..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WrappedHttpServletResponse.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedResponse;
-
-/**
- * Wrapper for {@link HttpServletResponse}.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedResponse
- * @see WrappedHttpServletRequest
- */
-public class WrappedHttpServletResponse extends HttpServletResponseWrapper
- implements WrappedResponse {
-
- private DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a http servlet response and an associated deployment configuration
- *
- * @param response
- * the http servlet response to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedHttpServletResponse(HttpServletResponse response,
- DeploymentConfiguration deploymentConfiguration) {
- super(response);
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- /**
- * Gets the original unwrapped <code>HttpServletResponse</code>
- *
- * @return the unwrapped response
- */
- public HttpServletResponse getHttpServletResponse() {
- return this;
- }
-
- @Override
- public void setCacheTime(long milliseconds) {
- doSetCacheTime(this, milliseconds);
- }
-
- // Implementation shared with WrappedPortletResponse
- static void doSetCacheTime(WrappedResponse response, long milliseconds) {
- if (milliseconds <= 0) {
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Pragma", "no-cache");
- response.setDateHeader("Expires", 0);
- } else {
- response.setHeader("Cache-Control", "max-age=" + milliseconds
- / 1000);
- response.setDateHeader("Expires", System.currentTimeMillis()
- + milliseconds);
- // Required to apply caching in some Tomcats
- response.setHeader("Pragma", "cache");
- }
- }
-
- @Override
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java b/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
deleted file mode 100644
index a3fa172034..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.portlet.ClientDataRequest;
-import javax.portlet.PortletRequest;
-import javax.portlet.ResourceRequest;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.CombinedRequest;
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-
-/**
- * Wrapper for {@link PortletRequest} and its subclasses.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedRequest
- * @see WrappedPortletResponse
- */
-public class WrappedPortletRequest implements WrappedRequest {
-
- private final PortletRequest request;
- private final DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a portlet request and an associated deployment configuration
- *
- * @param request
- * the portlet request to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedPortletRequest(PortletRequest request,
- DeploymentConfiguration deploymentConfiguration) {
- this.request = request;
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- @Override
- public Object getAttribute(String name) {
- return request.getAttribute(name);
- }
-
- @Override
- public int getContentLength() {
- try {
- return ((ClientDataRequest) request).getContentLength();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content lenght only available for ClientDataRequests");
- }
- }
-
- @Override
- public InputStream getInputStream() throws IOException {
- try {
- return ((ClientDataRequest) request).getPortletInputStream();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Input data only available for ClientDataRequests");
- }
- }
-
- @Override
- public String getParameter(String name) {
- return request.getParameter(name);
- }
-
- @Override
- public Map<String, String[]> getParameterMap() {
- return request.getParameterMap();
- }
-
- @Override
- public void setAttribute(String name, Object o) {
- request.setAttribute(name, o);
- }
-
- @Override
- public String getRequestPathInfo() {
- if (request instanceof ResourceRequest) {
- ResourceRequest resourceRequest = (ResourceRequest) request;
- String resourceID = resourceRequest.getResourceID();
- if (AbstractApplicationPortlet.RESOURCE_URL_ID.equals(resourceID)) {
- String resourcePath = resourceRequest
- .getParameter(ApplicationConnection.V_RESOURCE_PATH);
- return resourcePath;
- }
- return resourceID;
- } else {
- return null;
- }
- }
-
- @Override
- public int getSessionMaxInactiveInterval() {
- return request.getPortletSession().getMaxInactiveInterval();
- }
-
- @Override
- public Object getSessionAttribute(String name) {
- return request.getPortletSession().getAttribute(name);
- }
-
- @Override
- public void setSessionAttribute(String name, Object attribute) {
- request.getPortletSession().setAttribute(name, attribute);
- }
-
- /**
- * Gets the original, unwrapped portlet request.
- *
- * @return the unwrapped portlet request
- */
- public PortletRequest getPortletRequest() {
- return request;
- }
-
- @Override
- public String getContentType() {
- try {
- return ((ResourceRequest) request).getContentType();
- } catch (ClassCastException e) {
- throw new IllegalStateException(
- "Content type only available for ResourceRequests");
- }
- }
-
- @Override
- public BrowserDetails getBrowserDetails() {
- return new BrowserDetails() {
- @Override
- public String getUriFragment() {
- return null;
- }
-
- @Override
- public String getWindowName() {
- return null;
- }
-
- @Override
- public WebBrowser getWebBrowser() {
- PortletApplicationContext2 context = (PortletApplicationContext2) Application
- .getCurrent().getContext();
- return context.getBrowser();
- }
- };
- }
-
- @Override
- public Locale getLocale() {
- return request.getLocale();
- }
-
- @Override
- public String getRemoteAddr() {
- return null;
- }
-
- @Override
- public boolean isSecure() {
- return request.isSecure();
- }
-
- @Override
- public String getHeader(String string) {
- return null;
- }
-
- /**
- * Reads a portal property from the portal context of the wrapped request.
- *
- * @param name
- * a string with the name of the portal property to get
- * @return a string with the value of the property, or <code>null</code> if
- * the property is not defined
- */
- public String getPortalProperty(String name) {
- return request.getPortalContext().getProperty(name);
- }
-
- @Override
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-
- /**
- * Helper method to get a <code>WrappedPortlettRequest</code> from a
- * <code>WrappedRequest</code>. Aside from casting, this method also takes
- * care of situations where there's another level of wrapping.
- *
- * @param request
- * a wrapped request
- * @return a wrapped portlet request
- * @throws ClassCastException
- * if the wrapped request doesn't wrap a portlet request
- */
- public static WrappedPortletRequest cast(WrappedRequest request) {
- if (request instanceof CombinedRequest) {
- CombinedRequest combinedRequest = (CombinedRequest) request;
- request = combinedRequest.getSecondRequest();
- }
- return (WrappedPortletRequest) request;
- }
-}
diff --git a/src/com/vaadin/terminal/gwt/server/WrappedPortletResponse.java b/src/com/vaadin/terminal/gwt/server/WrappedPortletResponse.java
deleted file mode 100644
index f7ecf26f3c..0000000000
--- a/src/com/vaadin/terminal/gwt/server/WrappedPortletResponse.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.server;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import javax.portlet.MimeResponse;
-import javax.portlet.PortletResponse;
-import javax.portlet.ResourceResponse;
-
-import com.vaadin.terminal.DeploymentConfiguration;
-import com.vaadin.terminal.WrappedResponse;
-
-/**
- * Wrapper for {@link PortletResponse} and its subclasses.
- *
- * @author Vaadin Ltd.
- * @since 7.0
- *
- * @see WrappedResponse
- * @see WrappedPortletRequest
- */
-public class WrappedPortletResponse implements WrappedResponse {
- private static final DateFormat HTTP_DATE_FORMAT = new SimpleDateFormat(
- "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
- static {
- HTTP_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
- }
-
- private final PortletResponse response;
- private DeploymentConfiguration deploymentConfiguration;
-
- /**
- * Wraps a portlet response and an associated deployment configuration
- *
- * @param response
- * the portlet response to wrap
- * @param deploymentConfiguration
- * the associated deployment configuration
- */
- public WrappedPortletResponse(PortletResponse response,
- DeploymentConfiguration deploymentConfiguration) {
- this.response = response;
- this.deploymentConfiguration = deploymentConfiguration;
- }
-
- @Override
- public OutputStream getOutputStream() throws IOException {
- return ((MimeResponse) response).getPortletOutputStream();
- }
-
- /**
- * Gets the original, unwrapped portlet response.
- *
- * @return the unwrapped portlet response
- */
- public PortletResponse getPortletResponse() {
- return response;
- }
-
- @Override
- public void setContentType(String type) {
- ((MimeResponse) response).setContentType(type);
- }
-
- @Override
- public PrintWriter getWriter() throws IOException {
- return ((MimeResponse) response).getWriter();
- }
-
- @Override
- public void setStatus(int responseStatus) {
- response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
- Integer.toString(responseStatus));
- }
-
- @Override
- public void setHeader(String name, String value) {
- response.setProperty(name, value);
- }
-
- @Override
- public void setDateHeader(String name, long timestamp) {
- response.setProperty(name, HTTP_DATE_FORMAT.format(new Date(timestamp)));
- }
-
- @Override
- public void setCacheTime(long milliseconds) {
- WrappedHttpServletResponse.doSetCacheTime(this, milliseconds);
- }
-
- @Override
- public void sendError(int errorCode, String message) throws IOException {
- setStatus(errorCode);
- getWriter().write(message);
- }
-
- @Override
- public DeploymentConfiguration getDeploymentConfiguration() {
- return deploymentConfiguration;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/terminal/package.html b/src/com/vaadin/terminal/package.html
deleted file mode 100644
index 83514a0de5..0000000000
--- a/src/com/vaadin/terminal/package.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-
-</head>
-
-<body bgcolor="white">
-
-<!-- Package summary here -->
-
-<p>Provides classes and interfaces that wrap the terminal-side functionalities
-for the server-side application. (FIXME: This could be a little more descriptive and wordy.)</p>
-
-<h2>Package Specification</h2>
-
-<!-- Package spec here -->
-
-<!-- Put @see and @since tags down here. -->
-
-</body>
-</html>
diff --git a/src/com/vaadin/tools/ReflectTools.java b/src/com/vaadin/tools/ReflectTools.java
deleted file mode 100644
index ea2afae301..0000000000
--- a/src/com/vaadin/tools/ReflectTools.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.tools;
-
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * An util class with helpers for reflection operations. Used internally by
- * Vaadin and should not be used by application developers. Subject to change at
- * any time.
- *
- * @since 6.2
- */
-public class ReflectTools {
- /**
- * Locates the method in the given class. Returns null if the method is not
- * found. Throws an ExceptionInInitializerError if there is a problem
- * locating the method as this is mainly called from static blocks.
- *
- * @param cls
- * Class that contains the method
- * @param methodName
- * The name of the method
- * @param parameterTypes
- * The parameter types for the method.
- * @return A reference to the method
- * @throws ExceptionInInitializerError
- * Wraps any exception in an {@link ExceptionInInitializerError}
- * so this method can be called from a static initializer.
- */
- public static Method findMethod(Class<?> cls, String methodName,
- Class<?>... parameterTypes) throws ExceptionInInitializerError {
- try {
- return cls.getDeclaredMethod(methodName, parameterTypes);
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- /**
- * Returns the value of the java field.
- * <p>
- * Uses getter if present, otherwise tries to access even private fields
- * directly.
- *
- * @param object
- * The object containing the field
- * @param field
- * The field we want to get the value for
- * @return The value of the field in the object
- * @throws InvocationTargetException
- * If the value could not be retrieved
- * @throws IllegalAccessException
- * If the value could not be retrieved
- * @throws IllegalArgumentException
- * If the value could not be retrieved
- */
- public static Object getJavaFieldValue(Object object,
- java.lang.reflect.Field field) throws IllegalArgumentException,
- IllegalAccessException, InvocationTargetException {
- PropertyDescriptor pd;
- try {
- pd = new PropertyDescriptor(field.getName(), object.getClass());
- Method getter = pd.getReadMethod();
- if (getter != null) {
- return getter.invoke(object, (Object[]) null);
- }
- } catch (IntrospectionException e1) {
- // Ignore this and try to get directly using the field
- }
-
- // Try to get the value or throw an exception
- if (!field.isAccessible()) {
- // Try to gain access even if field is private
- field.setAccessible(true);
- }
- return field.get(object);
- }
-
- /**
- * Sets the value of a java field.
- * <p>
- * Uses setter if present, otherwise tries to access even private fields
- * directly.
- *
- * @param object
- * The object containing the field
- * @param field
- * The field we want to set the value for
- * @param value
- * The value to set
- * @throws IllegalAccessException
- * If the value could not be assigned to the field
- * @throws IllegalArgumentException
- * If the value could not be assigned to the field
- * @throws InvocationTargetException
- * If the value could not be assigned to the field
- */
- public static void setJavaFieldValue(Object object,
- java.lang.reflect.Field field, Object value)
- throws IllegalAccessException, IllegalArgumentException,
- InvocationTargetException {
- PropertyDescriptor pd;
- try {
- pd = new PropertyDescriptor(field.getName(), object.getClass());
- Method setter = pd.getWriteMethod();
- if (setter != null) {
- // Exceptions are thrown forward if this fails
- setter.invoke(object, value);
- }
- } catch (IntrospectionException e1) {
- // Ignore this and try to set directly using the field
- }
-
- // Try to set the value directly to the field or throw an exception
- if (!field.isAccessible()) {
- // Try to gain access even if field is private
- field.setAccessible(true);
- }
- field.set(object, value);
- }
-}
diff --git a/src/com/vaadin/tools/WidgetsetCompiler.java b/src/com/vaadin/tools/WidgetsetCompiler.java
deleted file mode 100644
index ecc1946e60..0000000000
--- a/src/com/vaadin/tools/WidgetsetCompiler.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.tools;
-
-import java.lang.reflect.Method;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.terminal.gwt.widgetsetutils.WidgetSetBuilder;
-
-/**
- * A wrapper for the GWT 1.6 compiler that runs the compiler in a new thread.
- *
- * This allows circumventing a J2SE 5.0 bug (6316197) that prevents setting the
- * stack size for the main thread. Thus, larger widgetsets can be compiled.
- *
- * This class takes the same command line arguments as the
- * com.google.gwt.dev.GWTCompiler class. The old and deprecated compiler is used
- * for compatibility with GWT 1.5.
- *
- * A typical invocation would use e.g. the following arguments
- *
- * "-out WebContent/VAADIN/widgetsets com.vaadin.terminal.gwt.DefaultWidgetSet"
- *
- * In addition, larger memory usage settings for the VM should be used, e.g.
- *
- * "-Xms256M -Xmx512M -Xss8M"
- *
- * The source directory containing widgetset and related classes must be
- * included in the classpath, as well as the gwt-dev-[platform].jar and other
- * relevant JARs.
- *
- * @deprecated with Java 6, can use com.google.gwt.dev.Compiler directly (also
- * in Eclipse plug-in etc.)
- */
-@Deprecated
-public class WidgetsetCompiler {
-
- /**
- * @param args
- * same arguments as for com.google.gwt.dev.Compiler
- */
- public static void main(final String[] args) {
- try {
- // run the compiler in a different thread to enable using the
- // user-set stack size
-
- // on Windows, the default stack size is too small for the main
- // thread and cannot be changed in JRE 1.5 (see
- // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6316197)
-
- Runnable runCompiler = new Runnable() {
- @Override
- public void run() {
- try {
- // GWTCompiler.main(args);
- // avoid warnings
-
- String wsname = args[args.length - 1];
-
- // TODO expecting this is launched via eclipse WTP
- // project
- System.out
- .println("Updating GWT module description file...");
- WidgetSetBuilder.updateWidgetSet(wsname);
- System.out.println("Done.");
-
- System.out.println("Starting GWT compiler");
- System.setProperty("gwt.nowarn.legacy.tools", "true");
- Class<?> compilerClass = Class
- .forName("com.google.gwt.dev.GWTCompiler");
- Method method = compilerClass.getDeclaredMethod("main",
- String[].class);
- method.invoke(null, new Object[] { args });
- } catch (Throwable thr) {
- getLogger().log(Level.SEVERE,
- "Widgetset compilation failed", thr);
- }
- }
- };
- Thread runThread = new Thread(runCompiler);
- runThread.start();
- runThread.join();
- System.out.println("Widgetset compilation finished");
- } catch (Throwable thr) {
- getLogger().log(Level.SEVERE, "Widgetset compilation failed", thr);
- }
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(WidgetsetCompiler.class.getName());
- }
-}
diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java
deleted file mode 100644
index 1c84ca2865..0000000000
--- a/src/com/vaadin/ui/AbsoluteLayout.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import com.vaadin.event.LayoutEvents.LayoutClickEvent;
-import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutServerRpc;
-import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutState;
-import com.vaadin.terminal.Sizeable;
-import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
-
-/**
- * AbsoluteLayout is a layout implementation that mimics html absolute
- * positioning.
- *
- */
-@SuppressWarnings("serial")
-public class AbsoluteLayout extends AbstractLayout implements
- LayoutClickNotifier {
-
- private AbsoluteLayoutServerRpc rpc = new AbsoluteLayoutServerRpc() {
-
- @Override
- public void layoutClick(MouseEventDetails mouseDetails,
- Connector clickedConnector) {
- fireEvent(LayoutClickEvent.createEvent(AbsoluteLayout.this,
- mouseDetails, clickedConnector));
- }
- };
- // Maps each component to a position
- private LinkedHashMap<Component, ComponentPosition> componentToCoordinates = new LinkedHashMap<Component, ComponentPosition>();
-
- /**
- * Creates an AbsoluteLayout with full size.
- */
- public AbsoluteLayout() {
- registerRpc(rpc);
- setSizeFull();
- }
-
- @Override
- public AbsoluteLayoutState getState() {
- return (AbsoluteLayoutState) super.getState();
- }
-
- /**
- * Gets an iterator for going through all components enclosed in the
- * absolute layout.
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return componentToCoordinates.keySet().iterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
- @Override
- public int getComponentCount() {
- return componentToCoordinates.size();
- }
-
- /**
- * Replaces one component with another one. The new component inherits the
- * old components position.
- */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- ComponentPosition position = getPosition(oldComponent);
- removeComponent(oldComponent);
- addComponent(newComponent, position);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component
- * )
- */
- @Override
- public void addComponent(Component c) {
- addComponent(c, new ComponentPosition());
- }
-
- /**
- * Adds a component to the layout. The component can be positioned by
- * providing a string formatted in CSS-format.
- * <p>
- * For example the string "top:10px;left:10px" will position the component
- * 10 pixels from the left and 10 pixels from the top. The identifiers:
- * "top","left","right" and "bottom" can be used to specify the position.
- * </p>
- *
- * @param c
- * The component to add to the layout
- * @param cssPosition
- * The css position string
- */
- public void addComponent(Component c, String cssPosition) {
- ComponentPosition position = new ComponentPosition();
- position.setCSSString(cssPosition);
- addComponent(c, position);
- }
-
- /**
- * Adds the component using the given position. Ensures the position is only
- * set if the component is added correctly.
- *
- * @param c
- * The component to add
- * @param position
- * The position info for the component. Must not be null.
- * @throws IllegalArgumentException
- * If adding the component failed
- */
- private void addComponent(Component c, ComponentPosition position)
- throws IllegalArgumentException {
- /*
- * Create position instance and add it to componentToCoordinates map. We
- * need to do this before we call addComponent so the attachListeners
- * can access this position. #6368
- */
- internalSetPosition(c, position);
- try {
- super.addComponent(c);
- } catch (IllegalArgumentException e) {
- internalRemoveComponent(c);
- throw e;
- }
- requestRepaint();
- }
-
- /**
- * Removes the component from all internal data structures. Does not
- * actually remove the component from the layout (this is assumed to have
- * been done by the caller).
- *
- * @param c
- * The component to remove
- */
- private void internalRemoveComponent(Component c) {
- componentToCoordinates.remove(c);
- }
-
- @Override
- public void updateState() {
- super.updateState();
-
- // This could be in internalRemoveComponent and internalSetComponent if
- // Map<Connector,String> was supported. We cannot get the child
- // connectorId unless the component is attached to the application so
- // the String->String map cannot be populated in internal* either.
- Map<String, String> connectorToPosition = new HashMap<String, String>();
- for (Iterator<Component> ci = getComponentIterator(); ci.hasNext();) {
- Component c = ci.next();
- connectorToPosition.put(c.getConnectorId(), getPosition(c)
- .getCSSString());
- }
- getState().setConnectorToCssPosition(connectorToPosition);
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui
- * .Component)
- */
- @Override
- public void removeComponent(Component c) {
- internalRemoveComponent(c);
- super.removeComponent(c);
- requestRepaint();
- }
-
- /**
- * Gets the position of a component in the layout. Returns null if component
- * is not attached to the layout.
- * <p>
- * Note that you cannot update the position by updating this object. Call
- * {@link #setPosition(Component, ComponentPosition)} with the updated
- * {@link ComponentPosition} object.
- * </p>
- *
- * @param component
- * The component which position is needed
- * @return An instance of ComponentPosition containing the position of the
- * component, or null if the component is not enclosed in the
- * layout.
- */
- public ComponentPosition getPosition(Component component) {
- return componentToCoordinates.get(component);
- }
-
- /**
- * Sets the position of a component in the layout.
- *
- * @param component
- * @param position
- */
- public void setPosition(Component component, ComponentPosition position) {
- if (!componentToCoordinates.containsKey(component)) {
- throw new IllegalArgumentException(
- "Component must be a child of this layout");
- }
- internalSetPosition(component, position);
- }
-
- /**
- * Updates the position for a component. Caller must ensure component is a
- * child of this layout.
- *
- * @param component
- * The component. Must be a child for this layout. Not enforced.
- * @param position
- * New position. Must not be null.
- */
- private void internalSetPosition(Component component,
- ComponentPosition position) {
- componentToCoordinates.put(component, position);
- requestRepaint();
- }
-
- /**
- * The CompontPosition class represents a components position within the
- * absolute layout. It contains the attributes for left, right, top and
- * bottom and the units used to specify them.
- */
- public class ComponentPosition implements Serializable {
-
- private int zIndex = -1;
- private Float topValue = null;
- private Float rightValue = null;
- private Float bottomValue = null;
- private Float leftValue = null;
-
- private Unit topUnits = Unit.PIXELS;
- private Unit rightUnits = Unit.PIXELS;
- private Unit bottomUnits = Unit.PIXELS;
- private Unit leftUnits = Unit.PIXELS;
-
- /**
- * Sets the position attributes using CSS syntax. Attributes not
- * included in the string are reset to their unset states.
- *
- * <code><pre>
- * setCSSString("top:10px;left:20%;z-index:16;");
- * </pre></code>
- *
- * @param css
- */
- public void setCSSString(String css) {
- topValue = rightValue = bottomValue = leftValue = null;
- topUnits = rightUnits = bottomUnits = leftUnits = Unit.PIXELS;
- zIndex = -1;
- if (css == null) {
- return;
- }
-
- String[] cssProperties = css.split(";");
- for (int i = 0; i < cssProperties.length; i++) {
- String[] keyValuePair = cssProperties[i].split(":");
- String key = keyValuePair[0].trim();
- if (key.equals("")) {
- continue;
- }
- if (key.equals("z-index")) {
- zIndex = Integer.parseInt(keyValuePair[1].trim());
- } else {
- String value;
- if (keyValuePair.length > 1) {
- value = keyValuePair[1].trim();
- } else {
- value = "";
- }
- String symbol = value.replaceAll("[0-9\\.\\-]+", "");
- if (!symbol.equals("")) {
- value = value.substring(0, value.indexOf(symbol))
- .trim();
- }
- float v = Float.parseFloat(value);
- Unit unit = Unit.getUnitFromSymbol(symbol);
- if (key.equals("top")) {
- topValue = v;
- topUnits = unit;
- } else if (key.equals("right")) {
- rightValue = v;
- rightUnits = unit;
- } else if (key.equals("bottom")) {
- bottomValue = v;
- bottomUnits = unit;
- } else if (key.equals("left")) {
- leftValue = v;
- leftUnits = unit;
- }
- }
- }
- requestRepaint();
- }
-
- /**
- * Converts the internal values into a valid CSS string.
- *
- * @return A valid CSS string
- */
- public String getCSSString() {
- String s = "";
- if (topValue != null) {
- s += "top:" + topValue + topUnits.getSymbol() + ";";
- }
- if (rightValue != null) {
- s += "right:" + rightValue + rightUnits.getSymbol() + ";";
- }
- if (bottomValue != null) {
- s += "bottom:" + bottomValue + bottomUnits.getSymbol() + ";";
- }
- if (leftValue != null) {
- s += "left:" + leftValue + leftUnits.getSymbol() + ";";
- }
- if (zIndex >= 0) {
- s += "z-index:" + zIndex + ";";
- }
- return s;
- }
-
- /**
- * Sets the 'top' attribute; distance from the top of the component to
- * the top edge of the layout.
- *
- * @param topValue
- * The value of the 'top' attribute
- * @param topUnits
- * The unit of the 'top' attribute. See UNIT_SYMBOLS for a
- * description of the available units.
- */
- public void setTop(Float topValue, Unit topUnits) {
- this.topValue = topValue;
- this.topUnits = topUnits;
- requestRepaint();
- }
-
- /**
- * Sets the 'right' attribute; distance from the right of the component
- * to the right edge of the layout.
- *
- * @param rightValue
- * The value of the 'right' attribute
- * @param rightUnits
- * The unit of the 'right' attribute. See UNIT_SYMBOLS for a
- * description of the available units.
- */
- public void setRight(Float rightValue, Unit rightUnits) {
- this.rightValue = rightValue;
- this.rightUnits = rightUnits;
- requestRepaint();
- }
-
- /**
- * Sets the 'bottom' attribute; distance from the bottom of the
- * component to the bottom edge of the layout.
- *
- * @param bottomValue
- * The value of the 'bottom' attribute
- * @param units
- * The unit of the 'bottom' attribute. See UNIT_SYMBOLS for a
- * description of the available units.
- */
- public void setBottom(Float bottomValue, Unit bottomUnits) {
- this.bottomValue = bottomValue;
- this.bottomUnits = bottomUnits;
- requestRepaint();
- }
-
- /**
- * Sets the 'left' attribute; distance from the left of the component to
- * the left edge of the layout.
- *
- * @param leftValue
- * The value of the 'left' attribute
- * @param units
- * The unit of the 'left' attribute. See UNIT_SYMBOLS for a
- * description of the available units.
- */
- public void setLeft(Float leftValue, Unit leftUnits) {
- this.leftValue = leftValue;
- this.leftUnits = leftUnits;
- requestRepaint();
- }
-
- /**
- * Sets the 'z-index' attribute; the visual stacking order
- *
- * @param zIndex
- * The z-index for the component.
- */
- public void setZIndex(int zIndex) {
- this.zIndex = zIndex;
- requestRepaint();
- }
-
- /**
- * Sets the value of the 'top' attribute; distance from the top of the
- * component to the top edge of the layout.
- *
- * @param topValue
- * The value of the 'left' attribute
- */
- public void setTopValue(Float topValue) {
- this.topValue = topValue;
- requestRepaint();
- }
-
- /**
- * Gets the 'top' attributes value in current units.
- *
- * @see #getTopUnits()
- * @return The value of the 'top' attribute, null if not set
- */
- public Float getTopValue() {
- return topValue;
- }
-
- /**
- * Gets the 'right' attributes value in current units.
- *
- * @return The value of the 'right' attribute, null if not set
- * @see #getRightUnits()
- */
- public Float getRightValue() {
- return rightValue;
- }
-
- /**
- * Sets the 'right' attribute value (distance from the right of the
- * component to the right edge of the layout). Currently active units
- * are maintained.
- *
- * @param rightValue
- * The value of the 'right' attribute
- * @see #setRightUnits(int)
- */
- public void setRightValue(Float rightValue) {
- this.rightValue = rightValue;
- requestRepaint();
- }
-
- /**
- * Gets the 'bottom' attributes value using current units.
- *
- * @return The value of the 'bottom' attribute, null if not set
- * @see #getBottomUnits()
- */
- public Float getBottomValue() {
- return bottomValue;
- }
-
- /**
- * Sets the 'bottom' attribute value (distance from the bottom of the
- * component to the bottom edge of the layout). Currently active units
- * are maintained.
- *
- * @param bottomValue
- * The value of the 'bottom' attribute
- * @see #setBottomUnits(int)
- */
- public void setBottomValue(Float bottomValue) {
- this.bottomValue = bottomValue;
- requestRepaint();
- }
-
- /**
- * Gets the 'left' attributes value using current units.
- *
- * @return The value of the 'left' attribute, null if not set
- * @see #getLeftUnits()
- */
- public Float getLeftValue() {
- return leftValue;
- }
-
- /**
- * Sets the 'left' attribute value (distance from the left of the
- * component to the left edge of the layout). Currently active units are
- * maintained.
- *
- * @param leftValue
- * The value of the 'left' CSS-attribute
- * @see #setLeftUnits(int)
- */
- public void setLeftValue(Float leftValue) {
- this.leftValue = leftValue;
- requestRepaint();
- }
-
- /**
- * Gets the unit for the 'top' attribute
- *
- * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public Unit getTopUnits() {
- return topUnits;
- }
-
- /**
- * Sets the unit for the 'top' attribute
- *
- * @param topUnits
- * See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public void setTopUnits(Unit topUnits) {
- this.topUnits = topUnits;
- requestRepaint();
- }
-
- /**
- * Gets the unit for the 'right' attribute
- *
- * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public Unit getRightUnits() {
- return rightUnits;
- }
-
- /**
- * Sets the unit for the 'right' attribute
- *
- * @param rightUnits
- * See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public void setRightUnits(Unit rightUnits) {
- this.rightUnits = rightUnits;
- requestRepaint();
- }
-
- /**
- * Gets the unit for the 'bottom' attribute
- *
- * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public Unit getBottomUnits() {
- return bottomUnits;
- }
-
- /**
- * Sets the unit for the 'bottom' attribute
- *
- * @param bottomUnits
- * See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public void setBottomUnits(Unit bottomUnits) {
- this.bottomUnits = bottomUnits;
- requestRepaint();
- }
-
- /**
- * Gets the unit for the 'left' attribute
- *
- * @return See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public Unit getLeftUnits() {
- return leftUnits;
- }
-
- /**
- * Sets the unit for the 'left' attribute
- *
- * @param leftUnits
- * See {@link Sizeable} UNIT_SYMBOLS for a description of the
- * available units.
- */
- public void setLeftUnits(Unit leftUnits) {
- this.leftUnits = leftUnits;
- requestRepaint();
- }
-
- /**
- * Gets the 'z-index' attribute.
- *
- * @return the zIndex The z-index attribute
- */
- public int getZIndex() {
- return zIndex;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return getCSSString();
- }
-
- }
-
- @Override
- public void addListener(LayoutClickListener listener) {
- addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener,
- LayoutClickListener.clickMethod);
- }
-
- @Override
- public void removeListener(LayoutClickListener listener) {
- removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener);
- }
-
-}
diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java
deleted file mode 100644
index e7cb38256c..0000000000
--- a/src/com/vaadin/ui/AbstractComponent.java
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.vaadin.Application;
-import com.vaadin.event.ActionManager;
-import com.vaadin.event.EventRouter;
-import com.vaadin.event.MethodEventSource;
-import com.vaadin.event.ShortcutListener;
-import com.vaadin.shared.ComponentState;
-import com.vaadin.terminal.AbstractClientConnector;
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-import com.vaadin.terminal.gwt.server.ComponentSizeValidator;
-import com.vaadin.terminal.gwt.server.ResourceReference;
-import com.vaadin.tools.ReflectTools;
-
-/**
- * An abstract class that defines default implementation for the
- * {@link Component} interface. Basic UI components that are not derived from an
- * external component can inherit this class to easily qualify as Vaadin
- * components. Most components in Vaadin do just that.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public abstract class AbstractComponent extends AbstractClientConnector
- implements Component, MethodEventSource {
-
- /* Private members */
-
- /**
- * Application specific data object. The component does not use or modify
- * this.
- */
- private Object applicationData;
-
- /**
- * The EventRouter used for the event model.
- */
- private EventRouter eventRouter = null;
-
- /**
- * The internal error message of the component.
- */
- private ErrorMessage componentError = null;
-
- /**
- * Locale of this component.
- */
- private Locale locale;
-
- /**
- * The component should receive focus (if {@link Focusable}) when attached.
- */
- private boolean delayedFocus;
-
- /* Sizeable fields */
-
- private float width = SIZE_UNDEFINED;
- private float height = SIZE_UNDEFINED;
- private Unit widthUnit = Unit.PIXELS;
- private Unit heightUnit = Unit.PIXELS;
- private static final Pattern sizePattern = Pattern
- .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|ex|in|cm|mm|pt|pc)?$");
-
- private ComponentErrorHandler errorHandler = null;
-
- /**
- * Keeps track of the Actions added to this component; the actual
- * handling/notifying is delegated, usually to the containing window.
- */
- private ActionManager actionManager;
-
- /* Constructor */
-
- /**
- * Constructs a new Component.
- */
- public AbstractComponent() {
- // ComponentSizeValidator.setCreationLocation(this);
- }
-
- /* Get/Set component properties */
-
- @Override
- public void setDebugId(String id) {
- getState().setDebugId(id);
- }
-
- @Override
- public String getDebugId() {
- return getState().getDebugId();
- }
-
- /**
- * Gets style for component. Multiple styles are joined with spaces.
- *
- * @return the component's styleValue of property style.
- * @deprecated Use getStyleName() instead; renamed for consistency and to
- * indicate that "style" should not be used to switch client
- * side implementation, only to style the component.
- */
- @Deprecated
- public String getStyle() {
- return getStyleName();
- }
-
- /**
- * Sets and replaces all previous style names of the component. This method
- * will trigger a {@link RepaintRequestEvent}.
- *
- * @param style
- * the new style of the component.
- * @deprecated Use setStyleName() instead; renamed for consistency and to
- * indicate that "style" should not be used to switch client
- * side implementation, only to style the component.
- */
- @Deprecated
- public void setStyle(String style) {
- setStyleName(style);
- }
-
- /*
- * Gets the component's style. Don't add a JavaDoc comment here, we use the
- * default documentation from implemented interface.
- */
- @Override
- public String getStyleName() {
- String s = "";
- if (getState().getStyles() != null) {
- for (final Iterator<String> it = getState().getStyles().iterator(); it
- .hasNext();) {
- s += it.next();
- if (it.hasNext()) {
- s += " ";
- }
- }
- }
- return s;
- }
-
- /*
- * Sets the component's style. Don't add a JavaDoc comment here, we use the
- * default documentation from implemented interface.
- */
- @Override
- public void setStyleName(String style) {
- if (style == null || "".equals(style)) {
- getState().setStyles(null);
- requestRepaint();
- return;
- }
- if (getState().getStyles() == null) {
- getState().setStyles(new ArrayList<String>());
- }
- List<String> styles = getState().getStyles();
- styles.clear();
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- styles.add(part);
- }
- }
- requestRepaint();
- }
-
- @Override
- public void addStyleName(String style) {
- if (style == null || "".equals(style)) {
- return;
- }
- if (style.contains(" ")) {
- // Split space separated style names and add them one by one.
- for (String realStyle : style.split(" ")) {
- addStyleName(realStyle);
- }
- return;
- }
-
- if (getState().getStyles() == null) {
- getState().setStyles(new ArrayList<String>());
- }
- List<String> styles = getState().getStyles();
- if (!styles.contains(style)) {
- styles.add(style);
- requestRepaint();
- }
- }
-
- @Override
- public void removeStyleName(String style) {
- if (getState().getStyles() != null) {
- String[] styleParts = style.split(" +");
- for (String part : styleParts) {
- if (part.length() > 0) {
- getState().getStyles().remove(part);
- }
- }
- requestRepaint();
- }
- }
-
- /*
- * Get's the component's caption. Don't add a JavaDoc comment here, we use
- * the default documentation from implemented interface.
- */
- @Override
- public String getCaption() {
- return getState().getCaption();
- }
-
- /**
- * Sets the component's caption <code>String</code>. Caption is the visible
- * name of the component. This method will trigger a
- * {@link RepaintRequestEvent}.
- *
- * @param caption
- * the new caption <code>String</code> for the component.
- */
- @Override
- public void setCaption(String caption) {
- getState().setCaption(caption);
- requestRepaint();
- }
-
- /*
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public Locale getLocale() {
- if (locale != null) {
- return locale;
- }
- HasComponents parent = getParent();
- if (parent != null) {
- return parent.getLocale();
- }
- final Application app = getApplication();
- if (app != null) {
- return app.getLocale();
- }
- return null;
- }
-
- /**
- * Sets the locale of this component.
- *
- * <pre>
- * // Component for which the locale is meaningful
- * InlineDateField date = new InlineDateField(&quot;Datum&quot;);
- *
- * // German language specified with ISO 639-1 language
- * // code and ISO 3166-1 alpha-2 country code.
- * date.setLocale(new Locale(&quot;de&quot;, &quot;DE&quot;));
- *
- * date.setResolution(DateField.RESOLUTION_DAY);
- * layout.addComponent(date);
- * </pre>
- *
- *
- * @param locale
- * the locale to become this component's locale.
- */
- public void setLocale(Locale locale) {
- this.locale = locale;
-
- // FIXME: Reload value if there is a converter
- requestRepaint();
- }
-
- /*
- * Gets the component's icon resource. Don't add a JavaDoc comment here, we
- * use the default documentation from implemented interface.
- */
- @Override
- public Resource getIcon() {
- return ResourceReference.getResource(getState().getIcon());
- }
-
- /**
- * Sets the component's icon. This method will trigger a
- * {@link RepaintRequestEvent}.
- *
- * @param icon
- * the icon to be shown with the component's caption.
- */
- @Override
- public void setIcon(Resource icon) {
- getState().setIcon(ResourceReference.create(icon));
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component#isEnabled()
- */
- @Override
- public boolean isEnabled() {
- return getState().isEnabled();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component#setEnabled(boolean)
- */
- @Override
- public void setEnabled(boolean enabled) {
- if (getState().isEnabled() != enabled) {
- getState().setEnabled(enabled);
- requestRepaint();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled()
- */
- @Override
- public boolean isConnectorEnabled() {
- if (!isVisible()) {
- return false;
- } else if (!isEnabled()) {
- return false;
- } else if (!super.isConnectorEnabled()) {
- return false;
- } else if (!getParent().isComponentVisible(this)) {
- return false;
- } else {
- return true;
- }
- }
-
- /*
- * Tests if the component is in the immediate mode. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- public boolean isImmediate() {
- return getState().isImmediate();
- }
-
- /**
- * Sets the component's immediate mode to the specified status. This method
- * will trigger a {@link RepaintRequestEvent}.
- *
- * @param immediate
- * the boolean value specifying if the component should be in the
- * immediate mode after the call.
- * @see Component#isImmediate()
- */
- public void setImmediate(boolean immediate) {
- getState().setImmediate(immediate);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component#isVisible()
- */
- @Override
- public boolean isVisible() {
- return getState().isVisible();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component#setVisible(boolean)
- */
- @Override
- public void setVisible(boolean visible) {
- if (getState().isVisible() == visible) {
- return;
- }
-
- getState().setVisible(visible);
- requestRepaint();
- if (getParent() != null) {
- // Must always repaint the parent (at least the hierarchy) when
- // visibility of a child component changes.
- getParent().requestRepaint();
- }
- }
-
- /**
- * <p>
- * Gets the component's description, used in tooltips and can be displayed
- * directly in certain other components such as forms. The description can
- * be used to briefly describe the state of the component to the user. The
- * description string may contain certain XML tags:
- * </p>
- *
- * <p>
- * <table border=1>
- * <tr>
- * <td width=120><b>Tag</b></td>
- * <td width=120><b>Description</b></td>
- * <td width=120><b>Example</b></td>
- * </tr>
- * <tr>
- * <td>&lt;b></td>
- * <td>bold</td>
- * <td><b>bold text</b></td>
- * </tr>
- * <tr>
- * <td>&lt;i></td>
- * <td>italic</td>
- * <td><i>italic text</i></td>
- * </tr>
- * <tr>
- * <td>&lt;u></td>
- * <td>underlined</td>
- * <td><u>underlined text</u></td>
- * </tr>
- * <tr>
- * <td>&lt;br></td>
- * <td>linebreak</td>
- * <td>N/A</td>
- * </tr>
- * <tr>
- * <td>&lt;ul><br>
- * &lt;li>item1<br>
- * &lt;li>item1<br>
- * &lt;/ul></td>
- * <td>item list</td>
- * <td>
- * <ul>
- * <li>item1
- * <li>item2
- * </ul>
- * </td>
- * </tr>
- * </table>
- * </p>
- *
- * <p>
- * These tags may be nested.
- * </p>
- *
- * @return component's description <code>String</code>
- */
- public String getDescription() {
- return getState().getDescription();
- }
-
- /**
- * Sets the component's description. See {@link #getDescription()} for more
- * information on what the description is. This method will trigger a
- * {@link RepaintRequestEvent}.
- *
- * The description is displayed as HTML/XHTML in tooltips or directly in
- * certain components so care should be taken to avoid creating the
- * possibility for HTML injection and possibly XSS vulnerabilities.
- *
- * @param description
- * the new description string for the component.
- */
- public void setDescription(String description) {
- getState().setDescription(description);
- requestRepaint();
- }
-
- /*
- * Gets the component's parent component. Don't add a JavaDoc comment here,
- * we use the default documentation from implemented interface.
- */
- @Override
- public HasComponents getParent() {
- return (HasComponents) super.getParent();
- }
-
- @Override
- public void setParent(ClientConnector parent) {
- if (parent == null || parent instanceof HasComponents) {
- super.setParent(parent);
- } else {
- throw new IllegalArgumentException(
- "The parent of a Component must implement HasComponents, which "
- + parent.getClass() + " doesn't do.");
- }
- }
-
- /**
- * Returns the closest ancestor with the given type.
- * <p>
- * To find the Window that contains the component, use {@code Window w =
- * getParent(Window.class);}
- * </p>
- *
- * @param <T>
- * The type of the ancestor
- * @param parentType
- * The ancestor class we are looking for
- * @return The first ancestor that can be assigned to the given class. Null
- * if no ancestor with the correct type could be found.
- */
- public <T extends HasComponents> T findAncestor(Class<T> parentType) {
- HasComponents p = getParent();
- while (p != null) {
- if (parentType.isAssignableFrom(p.getClass())) {
- return parentType.cast(p);
- }
- p = p.getParent();
- }
- return null;
- }
-
- /**
- * Gets the error message for this component.
- *
- * @return ErrorMessage containing the description of the error state of the
- * component or null, if the component contains no errors. Extending
- * classes should override this method if they support other error
- * message types such as validation errors or buffering errors. The
- * returned error message contains information about all the errors.
- */
- public ErrorMessage getErrorMessage() {
- return componentError;
- }
-
- /**
- * Gets the component's error message.
- *
- * @link Terminal.ErrorMessage#ErrorMessage(String, int)
- *
- * @return the component's error message.
- */
- public ErrorMessage getComponentError() {
- return componentError;
- }
-
- /**
- * Sets the component's error message. The message may contain certain XML
- * tags, for more information see
- *
- * @link Component.ErrorMessage#ErrorMessage(String, int)
- *
- * @param componentError
- * the new <code>ErrorMessage</code> of the component.
- */
- public void setComponentError(ErrorMessage componentError) {
- this.componentError = componentError;
- fireComponentErrorEvent();
- requestRepaint();
- }
-
- /*
- * Tests if the component is in read-only mode. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public boolean isReadOnly() {
- return getState().isReadOnly();
- }
-
- /*
- * Sets the component's read-only mode. Don't add a JavaDoc comment here, we
- * use the default documentation from implemented interface.
- */
- @Override
- public void setReadOnly(boolean readOnly) {
- getState().setReadOnly(readOnly);
- requestRepaint();
- }
-
- /*
- * Gets the parent window of the component. Don't add a JavaDoc comment
- * here, we use the default documentation from implemented interface.
- */
- @Override
- public Root getRoot() {
- // Just make method from implemented Component interface public
- return super.getRoot();
- }
-
- /*
- * Notify the component that it's attached to a window. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void attach() {
- super.attach();
- if (delayedFocus) {
- focus();
- }
- setActionManagerViewer();
- }
-
- /*
- * Detach the component from application. Don't add a JavaDoc comment here,
- * we use the default documentation from implemented interface.
- */
- @Override
- public void detach() {
- super.detach();
- if (actionManager != null) {
- // Remove any existing viewer. Root cast is just to make the
- // compiler happy
- actionManager.setViewer((Root) null);
- }
- }
-
- /**
- * Sets the focus for this component if the component is {@link Focusable}.
- */
- protected void focus() {
- if (this instanceof Focusable) {
- final Application app = getApplication();
- if (app != null) {
- getRoot().setFocusedComponent((Focusable) this);
- delayedFocus = false;
- } else {
- delayedFocus = true;
- }
- }
- }
-
- /**
- * Gets the application object to which the component is attached.
- *
- * <p>
- * The method will return {@code null} if the component is not currently
- * attached to an application. This is often a problem in constructors of
- * regular components and in the initializers of custom composite
- * components. A standard workaround is to move the problematic
- * initialization to {@link #attach()}, as described in the documentation of
- * the method.
- * </p>
- * <p>
- * <b>This method is not meant to be overridden. Due to CDI requirements we
- * cannot declare it as final even though it should be final.</b>
- * </p>
- *
- * @return the parent application of the component or <code>null</code>.
- * @see #attach()
- */
- @Override
- public Application getApplication() {
- // Just make method inherited from Component interface public
- return super.getApplication();
- }
-
- /**
- * Build CSS compatible string representation of height.
- *
- * @return CSS height
- */
- private String getCSSHeight() {
- if (getHeightUnits() == Unit.PIXELS) {
- return ((int) getHeight()) + getHeightUnits().getSymbol();
- } else {
- return getHeight() + getHeightUnits().getSymbol();
- }
- }
-
- /**
- * Build CSS compatible string representation of width.
- *
- * @return CSS width
- */
- private String getCSSWidth() {
- if (getWidthUnits() == Unit.PIXELS) {
- return ((int) getWidth()) + getWidthUnits().getSymbol();
- } else {
- return getWidth() + getWidthUnits().getSymbol();
- }
- }
-
- /**
- * Returns the shared state bean with information to be sent from the server
- * to the client.
- *
- * Subclasses should override this method and set any relevant fields of the
- * state returned by super.getState().
- *
- * @since 7.0
- *
- * @return updated component shared state
- */
- @Override
- public ComponentState getState() {
- return (ComponentState) super.getState();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component#updateState()
- */
- @Override
- public void updateState() {
- // TODO This logic should be on the client side and the state should
- // simply be a data object with "width" and "height".
- if (getHeight() >= 0
- && (getHeightUnits() != Unit.PERCENTAGE || ComponentSizeValidator
- .parentCanDefineHeight(this))) {
- getState().setHeight("" + getCSSHeight());
- } else {
- getState().setHeight("");
- }
-
- if (getWidth() >= 0
- && (getWidthUnits() != Unit.PERCENTAGE || ComponentSizeValidator
- .parentCanDefineWidth(this))) {
- getState().setWidth("" + getCSSWidth());
- } else {
- getState().setWidth("");
- }
-
- ErrorMessage error = getErrorMessage();
- if (null != error) {
- getState().setErrorMessage(error.getFormattedHtmlMessage());
- } else {
- getState().setErrorMessage(null);
- }
- }
-
- /* Documentation copied from interface */
- @Override
- public void requestRepaint() {
- // Invisible components (by flag in this particular component) do not
- // need repaints
- if (!getState().isVisible()) {
- return;
- }
- super.requestRepaint();
- }
-
- /* General event framework */
-
- private static final Method COMPONENT_EVENT_METHOD = ReflectTools
- .findMethod(Component.Listener.class, "componentEvent",
- Component.Event.class);
-
- /**
- * <p>
- * Registers a new listener with the specified activation method to listen
- * events generated by this component. If the activation method does not
- * have any arguments the event object will not be passed to it when it's
- * called.
- * </p>
- *
- * <p>
- * This method additionally informs the event-api to route events with the
- * given eventIdentifier to the components handleEvent function call.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventIdentifier
- * the identifier of the event to listen for
- * @param eventType
- * the type of the listened event. Events of this type or its
- * subclasses activate the listener.
- * @param target
- * the object instance who owns the activation method.
- * @param method
- * the activation method.
- *
- * @since 6.2
- */
- protected void addListener(String eventIdentifier, Class<?> eventType,
- Object target, Method method) {
- if (eventRouter == null) {
- eventRouter = new EventRouter();
- }
- boolean needRepaint = !eventRouter.hasListeners(eventType);
- eventRouter.addListener(eventType, target, method);
-
- if (needRepaint) {
- getState().addRegisteredEventListener(eventIdentifier);
- requestRepaint();
- }
- }
-
- /**
- * Checks if the given {@link Event} type is listened for this component.
- *
- * @param eventType
- * the event type to be checked
- * @return true if a listener is registered for the given event type
- */
- protected boolean hasListeners(Class<?> eventType) {
- return eventRouter != null && eventRouter.hasListeners(eventType);
- }
-
- /**
- * Removes all registered listeners matching the given parameters. Since
- * this method receives the event type and the listener object as
- * parameters, it will unregister all <code>object</code>'s methods that are
- * registered to listen to events of type <code>eventType</code> generated
- * by this component.
- *
- * <p>
- * This method additionally informs the event-api to stop routing events
- * with the given eventIdentifier to the components handleEvent function
- * call.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventIdentifier
- * the identifier of the event to stop listening for
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type <code>eventType</code> with one or more methods.
- *
- * @since 6.2
- */
- protected void removeListener(String eventIdentifier, Class<?> eventType,
- Object target) {
- if (eventRouter != null) {
- eventRouter.removeListener(eventType, target);
- if (!eventRouter.hasListeners(eventType)) {
- getState().removeRegisteredEventListener(eventIdentifier);
- requestRepaint();
- }
- }
- }
-
- /**
- * <p>
- * Registers a new listener with the specified activation method to listen
- * events generated by this component. If the activation method does not
- * have any arguments the event object will not be passed to it when it's
- * called.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the type of the listened event. Events of this type or its
- * subclasses activate the listener.
- * @param target
- * the object instance who owns the activation method.
- * @param method
- * the activation method.
- */
- @Override
- public void addListener(Class<?> eventType, Object target, Method method) {
- if (eventRouter == null) {
- eventRouter = new EventRouter();
- }
- eventRouter.addListener(eventType, target, method);
- }
-
- /**
- * <p>
- * Convenience method for registering a new listener with the specified
- * activation method to listen events generated by this component. If the
- * activation method does not have any arguments the event object will not
- * be passed to it when it's called.
- * </p>
- *
- * <p>
- * This version of <code>addListener</code> gets the name of the activation
- * method as a parameter. The actual method is reflected from
- * <code>object</code>, and unless exactly one match is found,
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * <p>
- * Note: Using this method is discouraged because it cannot be checked
- * during compilation. Use {@link #addListener(Class, Object, Method)} or
- * {@link #addListener(com.vaadin.ui.Component.Listener)} instead.
- * </p>
- *
- * @param eventType
- * the type of the listened event. Events of this type or its
- * subclasses activate the listener.
- * @param target
- * the object instance who owns the activation method.
- * @param methodName
- * the name of the activation method.
- */
- @Override
- public void addListener(Class<?> eventType, Object target, String methodName) {
- if (eventRouter == null) {
- eventRouter = new EventRouter();
- }
- eventRouter.addListener(eventType, target, methodName);
- }
-
- /**
- * Removes all registered listeners matching the given parameters. Since
- * this method receives the event type and the listener object as
- * parameters, it will unregister all <code>object</code>'s methods that are
- * registered to listen to events of type <code>eventType</code> generated
- * by this component.
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type <code>eventType</code> with one or more methods.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target) {
- if (eventRouter != null) {
- eventRouter.removeListener(eventType, target);
- }
- }
-
- /**
- * Removes one registered listener method. The given method owned by the
- * given object will no longer be called when the specified events are
- * generated by this component.
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * target object that has registered to listen to events of type
- * <code>eventType</code> with one or more methods.
- * @param method
- * the method owned by <code>target</code> that's registered to
- * listen to events of type <code>eventType</code>.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target, Method method) {
- if (eventRouter != null) {
- eventRouter.removeListener(eventType, target, method);
- }
- }
-
- /**
- * <p>
- * Removes one registered listener method. The given method owned by the
- * given object will no longer be called when the specified events are
- * generated by this component.
- * </p>
- *
- * <p>
- * This version of <code>removeListener</code> gets the name of the
- * activation method as a parameter. The actual method is reflected from
- * <code>target</code>, and unless exactly one match is found,
- * <code>java.lang.IllegalArgumentException</code> is thrown.
- * </p>
- *
- * <p>
- * For more information on the inheritable event mechanism see the
- * {@link com.vaadin.event com.vaadin.event package documentation}.
- * </p>
- *
- * @param eventType
- * the exact event type the <code>object</code> listens to.
- * @param target
- * the target object that has registered to listen to events of
- * type <code>eventType</code> with one or more methods.
- * @param methodName
- * the name of the method owned by <code>target</code> that's
- * registered to listen to events of type <code>eventType</code>.
- */
- @Override
- public void removeListener(Class<?> eventType, Object target,
- String methodName) {
- if (eventRouter != null) {
- eventRouter.removeListener(eventType, target, methodName);
- }
- }
-
- /**
- * Returns all listeners that are registered for the given event type or one
- * of its subclasses.
- *
- * @param eventType
- * The type of event to return listeners for.
- * @return A collection with all registered listeners. Empty if no listeners
- * are found.
- */
- public Collection<?> getListeners(Class<?> eventType) {
- if (eventRouter == null) {
- return Collections.EMPTY_LIST;
- }
-
- return eventRouter.getListeners(eventType);
- }
-
- /**
- * Sends the event to all listeners.
- *
- * @param event
- * the Event to be sent to all listeners.
- */
- protected void fireEvent(Component.Event event) {
- if (eventRouter != null) {
- eventRouter.fireEvent(event);
- }
-
- }
-
- /* Component event framework */
-
- /*
- * Registers a new listener to listen events generated by this component.
- * Don't add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void addListener(Component.Listener listener) {
- addListener(Component.Event.class, listener, COMPONENT_EVENT_METHOD);
- }
-
- /*
- * Removes a previously registered listener from this component. Don't add a
- * JavaDoc comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void removeListener(Component.Listener listener) {
- removeListener(Component.Event.class, listener, COMPONENT_EVENT_METHOD);
- }
-
- /**
- * Emits the component event. It is transmitted to all registered listeners
- * interested in such events.
- */
- protected void fireComponentEvent() {
- fireEvent(new Component.Event(this));
- }
-
- /**
- * Emits the component error event. It is transmitted to all registered
- * listeners interested in such events.
- */
- protected void fireComponentErrorEvent() {
- fireEvent(new Component.ErrorEvent(getComponentError(), this));
- }
-
- /**
- * Sets the data object, that can be used for any application specific data.
- * The component does not use or modify this data.
- *
- * @param data
- * the Application specific data.
- * @since 3.1
- */
- public void setData(Object data) {
- applicationData = data;
- }
-
- /**
- * Gets the application specific data. See {@link #setData(Object)}.
- *
- * @return the Application specific data set with setData function.
- * @since 3.1
- */
- public Object getData() {
- return applicationData;
- }
-
- /* Sizeable and other size related methods */
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#getHeight()
- */
- @Override
- public float getHeight() {
- return height;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#getHeightUnits()
- */
- @Override
- public Unit getHeightUnits() {
- return heightUnit;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#getWidth()
- */
- @Override
- public float getWidth() {
- return width;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#getWidthUnits()
- */
- @Override
- public Unit getWidthUnits() {
- return widthUnit;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setHeight(float, Unit)
- */
- @Override
- public void setHeight(float height, Unit unit) {
- if (unit == null) {
- throw new IllegalArgumentException("Unit can not be null");
- }
- this.height = height;
- heightUnit = unit;
- requestRepaint();
- // ComponentSizeValidator.setHeightLocation(this);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setSizeFull()
- */
- @Override
- public void setSizeFull() {
- setWidth(100, Unit.PERCENTAGE);
- setHeight(100, Unit.PERCENTAGE);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setSizeUndefined()
- */
- @Override
- public void setSizeUndefined() {
- setWidth(-1, Unit.PIXELS);
- setHeight(-1, Unit.PIXELS);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setWidth(float, Unit)
- */
- @Override
- public void setWidth(float width, Unit unit) {
- if (unit == null) {
- throw new IllegalArgumentException("Unit can not be null");
- }
- this.width = width;
- widthUnit = unit;
- requestRepaint();
- // ComponentSizeValidator.setWidthLocation(this);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setWidth(java.lang.String)
- */
- @Override
- public void setWidth(String width) {
- Size size = parseStringSize(width);
- if (size != null) {
- setWidth(size.getSize(), size.getUnit());
- } else {
- setWidth(-1, Unit.PIXELS);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Sizeable#setHeight(java.lang.String)
- */
- @Override
- public void setHeight(String height) {
- Size size = parseStringSize(height);
- if (size != null) {
- setHeight(size.getSize(), size.getUnit());
- } else {
- setHeight(-1, Unit.PIXELS);
- }
- }
-
- /*
- * Returns array with size in index 0 unit in index 1. Null or empty string
- * will produce {-1,Unit#PIXELS}
- */
- private static Size parseStringSize(String s) {
- if (s == null) {
- return null;
- }
- s = s.trim();
- if ("".equals(s)) {
- return null;
- }
- float size = 0;
- Unit unit = null;
- Matcher matcher = sizePattern.matcher(s);
- if (matcher.find()) {
- size = Float.parseFloat(matcher.group(1));
- if (size < 0) {
- size = -1;
- unit = Unit.PIXELS;
- } else {
- String symbol = matcher.group(3);
- unit = Unit.getUnitFromSymbol(symbol);
- }
- } else {
- throw new IllegalArgumentException("Invalid size argument: \"" + s
- + "\" (should match " + sizePattern.pattern() + ")");
- }
- return new Size(size, unit);
- }
-
- private static class Size implements Serializable {
- float size;
- Unit unit;
-
- public Size(float size, Unit unit) {
- this.size = size;
- this.unit = unit;
- }
-
- public float getSize() {
- return size;
- }
-
- public Unit getUnit() {
- return unit;
- }
- }
-
- public interface ComponentErrorEvent extends Terminal.ErrorEvent {
- }
-
- public interface ComponentErrorHandler extends Serializable {
- /**
- * Handle the component error
- *
- * @param event
- * @return True if the error has been handled False, otherwise
- */
- public boolean handleComponentError(ComponentErrorEvent event);
- }
-
- /**
- * Gets the error handler for the component.
- *
- * The error handler is dispatched whenever there is an error processing the
- * data coming from the client.
- *
- * @return
- */
- public ComponentErrorHandler getErrorHandler() {
- return errorHandler;
- }
-
- /**
- * Sets the error handler for the component.
- *
- * The error handler is dispatched whenever there is an error processing the
- * data coming from the client.
- *
- * If the error handler is not set, the application error handler is used to
- * handle the exception.
- *
- * @param errorHandler
- * AbstractField specific error handler
- */
- public void setErrorHandler(ComponentErrorHandler errorHandler) {
- this.errorHandler = errorHandler;
- }
-
- /**
- * Handle the component error event.
- *
- * @param error
- * Error event to handle
- * @return True if the error has been handled False, otherwise. If the error
- * haven't been handled by this component, it will be handled in the
- * application error handler.
- */
- public boolean handleError(ComponentErrorEvent error) {
- if (errorHandler != null) {
- return errorHandler.handleComponentError(error);
- }
- return false;
-
- }
-
- /*
- * Actions
- */
-
- /**
- * Gets the {@link ActionManager} used to manage the
- * {@link ShortcutListener}s added to this {@link Field}.
- *
- * @return the ActionManager in use
- */
- protected ActionManager getActionManager() {
- if (actionManager == null) {
- actionManager = new ActionManager();
- setActionManagerViewer();
- }
- return actionManager;
- }
-
- /**
- * Set a viewer for the action manager to be the parent sub window (if the
- * component is in a window) or the root (otherwise). This is still a
- * simplification of the real case as this should be handled by the parent
- * VOverlay (on the client side) if the component is inside an VOverlay
- * component.
- */
- private void setActionManagerViewer() {
- if (actionManager != null && getRoot() != null) {
- // Attached and has action manager
- Window w = findAncestor(Window.class);
- if (w != null) {
- actionManager.setViewer(w);
- } else {
- actionManager.setViewer(getRoot());
- }
- }
-
- }
-
- public void addShortcutListener(ShortcutListener shortcut) {
- getActionManager().addAction(shortcut);
- }
-
- public void removeShortcutListener(ShortcutListener shortcut) {
- if (actionManager != null) {
- actionManager.removeAction(shortcut);
- }
- }
-}
diff --git a/src/com/vaadin/ui/AbstractComponentContainer.java b/src/com/vaadin/ui/AbstractComponentContainer.java
deleted file mode 100644
index bc27242bb8..0000000000
--- a/src/com/vaadin/ui/AbstractComponentContainer.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.vaadin.terminal.gwt.server.ComponentSizeValidator;
-
-/**
- * Extension to {@link AbstractComponent} that defines the default
- * implementation for the methods in {@link ComponentContainer}. Basic UI
- * components that need to contain other components inherit this class to easily
- * qualify as a component container.
- *
- * @author Vaadin Ltd
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public abstract class AbstractComponentContainer extends AbstractComponent
- implements ComponentContainer {
-
- /**
- * Constructs a new component container.
- */
- public AbstractComponentContainer() {
- super();
- }
-
- /**
- * Removes all components from the container. This should probably be
- * re-implemented in extending classes for a more powerful implementation.
- */
- @Override
- public void removeAllComponents() {
- final LinkedList<Component> l = new LinkedList<Component>();
-
- // Adds all components
- for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
- l.add(i.next());
- }
-
- // Removes all component
- for (final Iterator<Component> i = l.iterator(); i.hasNext();) {
- removeComponent(i.next());
- }
- }
-
- /*
- * Moves all components from an another container into this container. Don't
- * add a JavaDoc comment here, we use the default documentation from
- * implemented interface.
- */
- @Override
- public void moveComponentsFrom(ComponentContainer source) {
- final LinkedList<Component> components = new LinkedList<Component>();
- for (final Iterator<Component> i = source.getComponentIterator(); i
- .hasNext();) {
- components.add(i.next());
- }
-
- for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
- final Component c = i.next();
- source.removeComponent(c);
- addComponent(c);
- }
- }
-
- /* Events */
-
- private static final Method COMPONENT_ATTACHED_METHOD;
-
- private static final Method COMPONENT_DETACHED_METHOD;
-
- static {
- try {
- COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class
- .getDeclaredMethod("componentAttachedToContainer",
- new Class[] { ComponentAttachEvent.class });
- COMPONENT_DETACHED_METHOD = ComponentDetachListener.class
- .getDeclaredMethod("componentDetachedFromContainer",
- new Class[] { ComponentDetachEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in AbstractComponentContainer");
- }
- }
-
- /* documented in interface */
- @Override
- public void addListener(ComponentAttachListener listener) {
- addListener(ComponentContainer.ComponentAttachEvent.class, listener,
- COMPONENT_ATTACHED_METHOD);
- }
-
- /* documented in interface */
- @Override
- public void addListener(ComponentDetachListener listener) {
- addListener(ComponentContainer.ComponentDetachEvent.class, listener,
- COMPONENT_DETACHED_METHOD);
- }
-
- /* documented in interface */
- @Override
- public void removeListener(ComponentAttachListener listener) {
- removeListener(ComponentContainer.ComponentAttachEvent.class, listener,
- COMPONENT_ATTACHED_METHOD);
- }
-
- /* documented in interface */
- @Override
- public void removeListener(ComponentDetachListener listener) {
- removeListener(ComponentContainer.ComponentDetachEvent.class, listener,
- COMPONENT_DETACHED_METHOD);
- }
-
- /**
- * Fires the component attached event. This should be called by the
- * addComponent methods after the component have been added to this
- * container.
- *
- * @param component
- * the component that has been added to this container.
- */
- protected void fireComponentAttachEvent(Component component) {
- fireEvent(new ComponentAttachEvent(this, component));
- }
-
- /**
- * Fires the component detached event. This should be called by the
- * removeComponent methods after the component have been removed from this
- * container.
- *
- * @param component
- * the component that has been removed from this container.
- */
- protected void fireComponentDetachEvent(Component component) {
- fireEvent(new ComponentDetachEvent(this, component));
- }
-
- /**
- * This only implements the events and component parent calls. The extending
- * classes must implement component list maintenance and call this method
- * after component list maintenance.
- *
- * @see com.vaadin.ui.ComponentContainer#addComponent(Component)
- */
- @Override
- public void addComponent(Component c) {
- if (c instanceof ComponentContainer) {
- // Make sure we're not adding the component inside it's own content
- for (Component parent = this; parent != null; parent = parent
- .getParent()) {
- if (parent == c) {
- throw new IllegalArgumentException(
- "Component cannot be added inside it's own content");
- }
- }
- }
-
- if (c.getParent() != null) {
- // If the component already has a parent, try to remove it
- ComponentContainer oldParent = (ComponentContainer) c.getParent();
- oldParent.removeComponent(c);
-
- }
-
- c.setParent(this);
- fireComponentAttachEvent(c);
- }
-
- /**
- * This only implements the events and component parent calls. The extending
- * classes must implement component list maintenance and call this method
- * before component list maintenance.
- *
- * @see com.vaadin.ui.ComponentContainer#removeComponent(Component)
- */
- @Override
- public void removeComponent(Component c) {
- if (c.getParent() == this) {
- c.setParent(null);
- fireComponentDetachEvent(c);
- }
- }
-
- @Override
- public void setVisible(boolean visible) {
- if (getState().isVisible() == visible) {
- return;
- }
-
- super.setVisible(visible);
- // If the visibility state is toggled it might affect all children
- // aswell, e.g. make container visible should make children visible if
- // they were only hidden because the container was hidden.
- requestRepaintAll();
- }
-
- @Override
- public void setWidth(float width, Unit unit) {
- /*
- * child tree repaints may be needed, due to our fall back support for
- * invalid relative sizes
- */
- Collection<Component> dirtyChildren = null;
- boolean childrenMayBecomeUndefined = false;
- if (getWidth() == SIZE_UNDEFINED && width != SIZE_UNDEFINED) {
- // children currently in invalid state may need repaint
- dirtyChildren = getInvalidSizedChildren(false);
- } else if ((width == SIZE_UNDEFINED && getWidth() != SIZE_UNDEFINED)
- || (unit == Unit.PERCENTAGE
- && getWidthUnits() != Unit.PERCENTAGE && !ComponentSizeValidator
- .parentCanDefineWidth(this))) {
- /*
- * relative width children may get to invalid state if width becomes
- * invalid. Width may also become invalid if units become percentage
- * due to the fallback support
- */
- childrenMayBecomeUndefined = true;
- dirtyChildren = getInvalidSizedChildren(false);
- }
- super.setWidth(width, unit);
- repaintChangedChildTrees(dirtyChildren, childrenMayBecomeUndefined,
- false);
- }
-
- private void repaintChangedChildTrees(
- Collection<Component> invalidChildren,
- boolean childrenMayBecomeUndefined, boolean vertical) {
- if (childrenMayBecomeUndefined) {
- Collection<Component> previouslyInvalidComponents = invalidChildren;
- invalidChildren = getInvalidSizedChildren(vertical);
- if (previouslyInvalidComponents != null && invalidChildren != null) {
- for (Iterator<Component> iterator = invalidChildren.iterator(); iterator
- .hasNext();) {
- Component component = iterator.next();
- if (previouslyInvalidComponents.contains(component)) {
- // still invalid don't repaint
- iterator.remove();
- }
- }
- }
- } else if (invalidChildren != null) {
- Collection<Component> stillInvalidChildren = getInvalidSizedChildren(vertical);
- if (stillInvalidChildren != null) {
- for (Component component : stillInvalidChildren) {
- // didn't become valid
- invalidChildren.remove(component);
- }
- }
- }
- if (invalidChildren != null) {
- repaintChildTrees(invalidChildren);
- }
- }
-
- private Collection<Component> getInvalidSizedChildren(final boolean vertical) {
- HashSet<Component> components = null;
- if (this instanceof Panel) {
- Panel p = (Panel) this;
- ComponentContainer content = p.getContent();
- boolean valid = vertical ? ComponentSizeValidator
- .checkHeights(content) : ComponentSizeValidator
- .checkWidths(content);
-
- if (!valid) {
- components = new HashSet<Component>(1);
- components.add(content);
- }
- } else {
- for (Iterator<Component> componentIterator = getComponentIterator(); componentIterator
- .hasNext();) {
- Component component = componentIterator.next();
- boolean valid = vertical ? ComponentSizeValidator
- .checkHeights(component) : ComponentSizeValidator
- .checkWidths(component);
- if (!valid) {
- if (components == null) {
- components = new HashSet<Component>();
- }
- components.add(component);
- }
- }
- }
- return components;
- }
-
- private void repaintChildTrees(Collection<Component> dirtyChildren) {
- for (Component c : dirtyChildren) {
- if (c instanceof ComponentContainer) {
- ComponentContainer cc = (ComponentContainer) c;
- cc.requestRepaintAll();
- } else {
- c.requestRepaint();
- }
- }
- }
-
- @Override
- public void setHeight(float height, Unit unit) {
- /*
- * child tree repaints may be needed, due to our fall back support for
- * invalid relative sizes
- */
- Collection<Component> dirtyChildren = null;
- boolean childrenMayBecomeUndefined = false;
- if (getHeight() == SIZE_UNDEFINED && height != SIZE_UNDEFINED) {
- // children currently in invalid state may need repaint
- dirtyChildren = getInvalidSizedChildren(true);
- } else if ((height == SIZE_UNDEFINED && getHeight() != SIZE_UNDEFINED)
- || (unit == Unit.PERCENTAGE
- && getHeightUnits() != Unit.PERCENTAGE && !ComponentSizeValidator
- .parentCanDefineHeight(this))) {
- /*
- * relative height children may get to invalid state if height
- * becomes invalid. Height may also become invalid if units become
- * percentage due to the fallback support.
- */
- childrenMayBecomeUndefined = true;
- dirtyChildren = getInvalidSizedChildren(true);
- }
- super.setHeight(height, unit);
- repaintChangedChildTrees(dirtyChildren, childrenMayBecomeUndefined,
- true);
- }
-
- @Override
- public Iterator<Component> iterator() {
- return getComponentIterator();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.ui.HasComponents#isComponentVisible(com.vaadin.ui.Component)
- */
- @Override
- public boolean isComponentVisible(Component childComponent) {
- return true;
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java
deleted file mode 100644
index 6fe7f54df5..0000000000
--- a/src/com/vaadin/ui/AbstractField.java
+++ /dev/null
@@ -1,1657 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Buffered;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validatable;
-import com.vaadin.data.Validator;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.data.util.converter.Converter.ConversionException;
-import com.vaadin.data.util.converter.ConverterUtil;
-import com.vaadin.event.Action;
-import com.vaadin.event.ShortcutAction;
-import com.vaadin.event.ShortcutListener;
-import com.vaadin.shared.AbstractFieldState;
-import com.vaadin.terminal.AbstractErrorMessage;
-import com.vaadin.terminal.CompositeErrorMessage;
-import com.vaadin.terminal.ErrorMessage;
-
-/**
- * <p>
- * Abstract field component for implementing buffered property editors. The
- * field may hold an internal value, or it may be connected to any data source
- * that implements the {@link com.vaadin.data.Property}interface.
- * <code>AbstractField</code> implements that interface itself, too, so
- * accessing the Property value represented by it is straightforward.
- * </p>
- *
- * <p>
- * AbstractField also provides the {@link com.vaadin.data.Buffered} interface
- * for buffering the data source value. By default the Field is in write
- * through-mode and {@link #setWriteThrough(boolean)}should be called to enable
- * buffering.
- * </p>
- *
- * <p>
- * The class also supports {@link com.vaadin.data.Validator validators} to make
- * sure the value contained in the field is valid.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public abstract class AbstractField<T> extends AbstractComponent implements
- Field<T>, Property.ReadOnlyStatusChangeListener,
- Property.ReadOnlyStatusChangeNotifier, Action.ShortcutNotifier {
-
- /* Private members */
-
- private static final Logger logger = Logger.getLogger(AbstractField.class
- .getName());
-
- /**
- * Value of the abstract field.
- */
- private T value;
-
- /**
- * A converter used to convert from the data model type to the field type
- * and vice versa.
- */
- private Converter<T, Object> converter = null;
- /**
- * Connected data-source.
- */
- private Property<?> dataSource = null;
-
- /**
- * The list of validators.
- */
- private LinkedList<Validator> validators = null;
-
- /**
- * Auto commit mode.
- */
- private boolean writeThroughMode = true;
-
- /**
- * Reads the value from data-source, when it is not modified.
- */
- private boolean readThroughMode = true;
-
- /**
- * Flag to indicate that the field is currently committing its value to the
- * datasource.
- */
- private boolean committingValueToDataSource = false;
-
- /**
- * Current source exception.
- */
- private Buffered.SourceException currentBufferedSourceException = null;
-
- /**
- * Are the invalid values allowed in fields ?
- */
- private boolean invalidAllowed = true;
-
- /**
- * Are the invalid values committed ?
- */
- private boolean invalidCommitted = false;
-
- /**
- * The error message for the exception that is thrown when the field is
- * required but empty.
- */
- private String requiredError = "";
-
- /**
- * The error message that is shown when the field value cannot be converted.
- */
- private String conversionError = "Could not convert value to {0}";
-
- /**
- * Is automatic validation enabled.
- */
- private boolean validationVisible = true;
-
- private boolean valueWasModifiedByDataSourceDuringCommit;
-
- /**
- * Whether this field is currently registered as listening to events from
- * its data source.
- *
- * @see #setPropertyDataSource(Property)
- * @see #addPropertyListeners()
- * @see #removePropertyListeners()
- */
- private boolean isListeningToPropertyEvents = false;
-
- /* Component basics */
-
- /*
- * Paints the field. Don't add a JavaDoc comment here, we use the default
- * documentation from the implemented interface.
- */
-
- /**
- * Returns true if the error indicator be hidden when painting the component
- * even when there are errors.
- *
- * This is a mostly internal method, but can be overridden in subclasses
- * e.g. if the error indicator should also be shown for empty fields in some
- * cases.
- *
- * @return true to hide the error indicator, false to use the normal logic
- * to show it when there are errors
- */
- protected boolean shouldHideErrors() {
- // getErrorMessage() can still return something else than null based on
- // validation etc.
- return isRequired() && isEmpty() && getComponentError() == null;
- }
-
- /**
- * Returns the type of the Field. The methods <code>getValue</code> and
- * <code>setValue</code> must be compatible with this type: one must be able
- * to safely cast the value returned from <code>getValue</code> to the given
- * type and pass any variable assignable to this type as an argument to
- * <code>setValue</code>.
- *
- * @return the type of the Field
- */
- @Override
- public abstract Class<? extends T> getType();
-
- /**
- * The abstract field is read only also if the data source is in read only
- * mode.
- */
- @Override
- public boolean isReadOnly() {
- return super.isReadOnly()
- || (dataSource != null && dataSource.isReadOnly());
- }
-
- /**
- * Changes the readonly state and throw read-only status change events.
- *
- * @see com.vaadin.ui.Component#setReadOnly(boolean)
- */
- @Override
- public void setReadOnly(boolean readOnly) {
- super.setReadOnly(readOnly);
- fireReadOnlyStatusChange();
- }
-
- /**
- * Tests if the invalid data is committed to datasource.
- *
- * @see com.vaadin.data.BufferedValidatable#isInvalidCommitted()
- */
- @Override
- public boolean isInvalidCommitted() {
- return invalidCommitted;
- }
-
- /**
- * Sets if the invalid data should be committed to datasource.
- *
- * @see com.vaadin.data.BufferedValidatable#setInvalidCommitted(boolean)
- */
- @Override
- public void setInvalidCommitted(boolean isCommitted) {
- invalidCommitted = isCommitted;
- }
-
- /*
- * Saves the current value to the data source Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public void commit() throws Buffered.SourceException, InvalidValueException {
- if (dataSource != null && !dataSource.isReadOnly()) {
- if ((isInvalidCommitted() || isValid())) {
- try {
-
- // Commits the value to datasource.
- valueWasModifiedByDataSourceDuringCommit = false;
- committingValueToDataSource = true;
- getPropertyDataSource().setValue(getConvertedValue());
- } catch (final Throwable e) {
-
- // Sets the buffering state.
- SourceException sourceException = new Buffered.SourceException(
- this, e);
- setCurrentBufferedSourceException(sourceException);
-
- // Throws the source exception.
- throw sourceException;
- } finally {
- committingValueToDataSource = false;
- }
- } else {
- /* An invalid value and we don't allow them, throw the exception */
- validate();
- }
- }
-
- // The abstract field is not modified anymore
- if (isModified()) {
- setModified(false);
- }
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
-
- if (valueWasModifiedByDataSourceDuringCommit) {
- valueWasModifiedByDataSourceDuringCommit = false;
- fireValueChange(false);
- }
-
- }
-
- /*
- * Updates the value from the data source. Don't add a JavaDoc comment here,
- * we use the default documentation from the implemented interface.
- */
- @Override
- public void discard() throws Buffered.SourceException {
- if (dataSource != null) {
-
- // Gets the correct value from datasource
- T newFieldValue;
- try {
-
- // Discards buffer by overwriting from datasource
- newFieldValue = convertFromDataSource(getDataSourceValue());
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
- } catch (final Throwable e) {
- // FIXME: What should really be done here if conversion fails?
-
- // Sets the buffering state
- currentBufferedSourceException = new Buffered.SourceException(
- this, e);
- requestRepaint();
-
- // Throws the source exception
- throw currentBufferedSourceException;
- }
-
- final boolean wasModified = isModified();
- setModified(false);
-
- // If the new value differs from the previous one
- if (!equals(newFieldValue, getInternalValue())) {
- setInternalValue(newFieldValue);
- fireValueChange(false);
- } else if (wasModified) {
- // If the value did not change, but the modification status did
- requestRepaint();
- }
- }
- }
-
- /**
- * Gets the value from the data source. This is only here because of clarity
- * in the code that handles both the data model value and the field value.
- *
- * @return The value of the property data source
- */
- private Object getDataSourceValue() {
- return dataSource.getValue();
- }
-
- /**
- * Returns the field value. This is always identical to {@link #getValue()}
- * and only here because of clarity in the code that handles both the data
- * model value and the field value.
- *
- * @return The value of the field
- */
- private T getFieldValue() {
- // Give the value from abstract buffers if the field if possible
- if (dataSource == null || !isReadThrough() || isModified()) {
- return getInternalValue();
- }
-
- // There is no buffered value so use whatever the data model provides
- return convertFromDataSource(getDataSourceValue());
- }
-
- /*
- * Has the field been modified since the last commit()? Don't add a JavaDoc
- * comment here, we use the default documentation from the implemented
- * interface.
- */
- @Override
- public boolean isModified() {
- return getState().isModified();
- }
-
- private void setModified(boolean modified) {
- getState().setModified(modified);
- requestRepaint();
- }
-
- /*
- * Tests if the field is in write-through mode. Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public boolean isWriteThrough() {
- return writeThroughMode;
- }
-
- /**
- * Sets the field's write-through mode to the specified status. When
- * switching the write-through mode on, a {@link #commit()} will be
- * performed.
- *
- * @see #setBuffered(boolean) for an easier way to control read through and
- * write through modes
- *
- * @param writeThrough
- * Boolean value to indicate if the object should be in
- * write-through mode after the call.
- * @throws SourceException
- * If the operation fails because of an exception is thrown by
- * the data source.
- * @throws InvalidValueException
- * If the implicit commit operation fails because of a
- * validation error.
- * @deprecated Use {@link #setBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Override
- @Deprecated
- public void setWriteThrough(boolean writeThrough)
- throws Buffered.SourceException, InvalidValueException {
- if (writeThroughMode == writeThrough) {
- return;
- }
- writeThroughMode = writeThrough;
- if (writeThroughMode) {
- commit();
- }
- }
-
- /*
- * Tests if the field is in read-through mode. Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public boolean isReadThrough() {
- return readThroughMode;
- }
-
- /**
- * Sets the field's read-through mode to the specified status. When
- * switching read-through mode on, the object's value is updated from the
- * data source.
- *
- * @see #setBuffered(boolean) for an easier way to control read through and
- * write through modes
- *
- * @param readThrough
- * Boolean value to indicate if the object should be in
- * read-through mode after the call.
- *
- * @throws SourceException
- * If the operation fails because of an exception is thrown by
- * the data source. The cause is included in the exception.
- * @deprecated Use {@link #setBuffered(boolean)} instead. Note that
- * setReadThrough(true), setWriteThrough(true) equals
- * setBuffered(false)
- */
- @Override
- @Deprecated
- public void setReadThrough(boolean readThrough)
- throws Buffered.SourceException {
- if (readThroughMode == readThrough) {
- return;
- }
- readThroughMode = readThrough;
- if (!isModified() && readThroughMode && getPropertyDataSource() != null) {
- setInternalValue(convertFromDataSource(getDataSourceValue()));
- fireValueChange(false);
- }
- }
-
- /**
- * Sets the buffered mode of this Field.
- * <p>
- * When the field is in buffered mode, changes will not be committed to the
- * property data source until {@link #commit()} is called.
- * </p>
- * <p>
- * Changing buffered mode will change the read through and write through
- * state for the field.
- * </p>
- * <p>
- * Mixing calls to {@link #setBuffered(boolean)} and
- * {@link #setReadThrough(boolean)} or {@link #setWriteThrough(boolean)} is
- * generally a bad idea.
- * </p>
- *
- * @param buffered
- * true if buffered mode should be turned on, false otherwise
- */
- @Override
- public void setBuffered(boolean buffered) {
- setReadThrough(!buffered);
- setWriteThrough(!buffered);
- }
-
- /**
- * Checks the buffered mode of this Field.
- * <p>
- * This method only returns true if both read and write buffering is used.
- *
- * @return true if buffered mode is on, false otherwise
- */
- @Override
- public boolean isBuffered() {
- return !isReadThrough() && !isWriteThrough();
- }
-
- /* Property interface implementation */
-
- /**
- * Returns the (field) value converted to a String using toString().
- *
- * @see java.lang.Object#toString()
- * @deprecated Instead use {@link #getValue()} to get the value of the
- * field, {@link #getConvertedValue()} to get the field value
- * converted to the data model type or
- * {@link #getPropertyDataSource()} .getValue() to get the value
- * of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using AbstractField.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This is not recommended and will not be supported in future versions.");
- final Object value = getFieldValue();
- if (value == null) {
- return null;
- }
- return value.toString();
- }
-
- /**
- * Gets the current value of the field.
- *
- * <p>
- * This is the visible, modified and possible invalid value the user have
- * entered to the field.
- * </p>
- *
- * <p>
- * Note that the object returned is compatible with getType(). For example,
- * if the type is String, this returns Strings even when the underlying
- * datasource is of some other type. In order to access the converted value,
- * use {@link #getConvertedValue()} and to access the value of the property
- * data source, use {@link Property#getValue()} for the property data
- * source.
- * </p>
- *
- * <p>
- * Since Vaadin 7.0, no implicit conversions between other data types and
- * String are performed, but a converter is used if set.
- * </p>
- *
- * @return the current value of the field.
- */
- @Override
- public T getValue() {
- return getFieldValue();
- }
-
- /**
- * Sets the value of the field.
- *
- * @param newFieldValue
- * the New value of the field.
- * @throws Property.ReadOnlyException
- */
- @Override
- public void setValue(Object newFieldValue)
- throws Property.ReadOnlyException, Converter.ConversionException {
- // This check is needed as long as setValue accepts Object instead of T
- if (newFieldValue != null) {
- if (!getType().isAssignableFrom(newFieldValue.getClass())) {
- throw new Converter.ConversionException("Value of type "
- + newFieldValue.getClass() + " cannot be assigned to "
- + getType().getName());
- }
- }
- setValue((T) newFieldValue, false);
- }
-
- /**
- * Sets the value of the field.
- *
- * @param newFieldValue
- * the New value of the field.
- * @param repaintIsNotNeeded
- * True iff caller is sure that repaint is not needed.
- * @throws Property.ReadOnlyException
- */
- protected void setValue(T newFieldValue, boolean repaintIsNotNeeded)
- throws Property.ReadOnlyException, Converter.ConversionException,
- InvalidValueException {
-
- if (!equals(newFieldValue, getInternalValue())) {
-
- // Read only fields can not be changed
- if (isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
-
- // Repaint is needed even when the client thinks that it knows the
- // new state if validity of the component may change
- if (repaintIsNotNeeded
- && (isRequired() || getValidators() != null || getConverter() != null)) {
- repaintIsNotNeeded = false;
- }
-
- if (!isInvalidAllowed()) {
- /*
- * If invalid values are not allowed the value must be validated
- * before it is set. If validation fails, the
- * InvalidValueException is thrown and the internal value is not
- * updated.
- */
- validate(newFieldValue);
- }
-
- // Changes the value
- setInternalValue(newFieldValue);
- setModified(dataSource != null);
-
- valueWasModifiedByDataSourceDuringCommit = false;
- // In write through mode , try to commit
- if (isWriteThrough() && dataSource != null
- && (isInvalidCommitted() || isValid())) {
- try {
-
- // Commits the value to datasource
- committingValueToDataSource = true;
- getPropertyDataSource().setValue(
- convertToModel(newFieldValue));
-
- // The buffer is now unmodified
- setModified(false);
-
- } catch (final Throwable e) {
-
- // Sets the buffering state
- currentBufferedSourceException = new Buffered.SourceException(
- this, e);
- requestRepaint();
-
- // Throws the source exception
- throw currentBufferedSourceException;
- } finally {
- committingValueToDataSource = false;
- }
- }
-
- // If successful, remove set the buffering state to be ok
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
-
- if (valueWasModifiedByDataSourceDuringCommit) {
- /*
- * Value was modified by datasource. Force repaint even if
- * repaint was not requested.
- */
- valueWasModifiedByDataSourceDuringCommit = repaintIsNotNeeded = false;
- }
-
- // Fires the value change
- fireValueChange(repaintIsNotNeeded);
-
- }
- }
-
- private static boolean equals(Object value1, Object value2) {
- if (value1 == null) {
- return value2 == null;
- }
- return value1.equals(value2);
- }
-
- /* External data source */
-
- /**
- * Gets the current data source of the field, if any.
- *
- * @return the current data source as a Property, or <code>null</code> if
- * none defined.
- */
- @Override
- public Property getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- * <p>
- * Sets the specified Property as the data source for the field. All
- * uncommitted changes are replaced with a value from the new data source.
- * </p>
- *
- * <p>
- * If the datasource has any validators, the same validators are added to
- * the field. Because the default behavior of the field is to allow invalid
- * values, but not to allow committing them, this only adds visual error
- * messages to fields and do not allow committing them as long as the value
- * is invalid. After the value is valid, the error message is not shown and
- * the commit can be done normally.
- * </p>
- *
- * <p>
- * If the data source implements
- * {@link com.vaadin.data.Property.ValueChangeNotifier} and/or
- * {@link com.vaadin.data.Property.ReadOnlyStatusChangeNotifier}, the field
- * registers itself as a listener and updates itself according to the events
- * it receives. To avoid memory leaks caused by references to a field no
- * longer in use, the listener registrations are removed on
- * {@link AbstractField#detach() detach} and re-added on
- * {@link AbstractField#attach() attach}.
- * </p>
- *
- * <p>
- * Note: before 6.5 we actually called discard() method in the beginning of
- * the method. This was removed to simplify implementation, avoid excess
- * calls to backing property and to avoid odd value change events that were
- * previously fired (developer expects 0-1 value change events if this
- * method is called). Some complex field implementations might now need to
- * override this method to do housekeeping similar to discard().
- * </p>
- *
- * @param newDataSource
- * the new data source Property.
- */
- @Override
- public void setPropertyDataSource(Property newDataSource) {
-
- // Saves the old value
- final Object oldValue = getInternalValue();
-
- // Stop listening to the old data source
- removePropertyListeners();
-
- // Sets the new data source
- dataSource = newDataSource;
- getState().setPropertyReadOnly(
- dataSource == null ? false : dataSource.isReadOnly());
-
- // Check if the current converter is compatible.
- if (newDataSource != null
- && !ConverterUtil.canConverterHandle(getConverter(), getType(),
- newDataSource.getType())) {
- // Changing from e.g. Number -> Double should set a new converter,
- // changing from Double -> Number can keep the old one (Property
- // accepts Number)
-
- // Set a new converter if there is a new data source and
- // there is no old converter or the old is incompatible.
- setConverter(newDataSource.getType());
- }
- // Gets the value from source
- try {
- if (dataSource != null) {
- T fieldValue = convertFromDataSource(getDataSourceValue());
- setInternalValue(fieldValue);
- }
- setModified(false);
- if (getCurrentBufferedSourceException() != null) {
- setCurrentBufferedSourceException(null);
- }
- } catch (final Throwable e) {
- setCurrentBufferedSourceException(new Buffered.SourceException(
- this, e));
- setModified(true);
- }
-
- // Listen to new data source if possible
- addPropertyListeners();
-
- // Copy the validators from the data source
- if (dataSource instanceof Validatable) {
- final Collection<Validator> validators = ((Validatable) dataSource)
- .getValidators();
- if (validators != null) {
- for (final Iterator<Validator> i = validators.iterator(); i
- .hasNext();) {
- addValidator(i.next());
- }
- }
- }
-
- // Fires value change if the value has changed
- T value = getInternalValue();
- if ((value != oldValue)
- && ((value != null && !value.equals(oldValue)) || value == null)) {
- fireValueChange(false);
- }
- }
-
- /**
- * Retrieves a converter for the field from the converter factory defined
- * for the application. Clears the converter if no application reference is
- * available or if the factory returns null.
- *
- * @param datamodelType
- * The type of the data model that we want to be able to convert
- * from
- */
- public void setConverter(Class<?> datamodelType) {
- Converter<T, ?> c = (Converter<T, ?>) ConverterUtil.getConverter(
- getType(), datamodelType, getApplication());
- setConverter(c);
- }
-
- /**
- * Convert the given value from the data source type to the UI type.
- *
- * @param newValue
- * The data source value to convert.
- * @return The converted value that is compatible with the UI type or the
- * original value if its type is compatible and no converter is set.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private T convertFromDataSource(Object newValue) {
- return ConverterUtil.convertFromModel(newValue, getType(),
- getConverter(), getLocale());
- }
-
- /**
- * Convert the given value from the UI type to the data source type.
- *
- * @param fieldValue
- * The value to convert. Typically returned by
- * {@link #getFieldValue()}
- * @return The converted value that is compatible with the data source type.
- * @throws Converter.ConversionException
- * if there is no converter and the type is not compatible with
- * the data source type.
- */
- private Object convertToModel(T fieldValue)
- throws Converter.ConversionException {
- try {
- Class<?> modelType = null;
- Property pd = getPropertyDataSource();
- if (pd != null) {
- modelType = pd.getType();
- } else if (getConverter() != null) {
- modelType = getConverter().getModelType();
- }
- return ConverterUtil.convertToModel(fieldValue,
- (Class<Object>) modelType, getConverter(), getLocale());
- } catch (ConversionException e) {
- throw new ConversionException(
- getConversionError(converter.getModelType()), e);
- }
- }
-
- /**
- * Returns the conversion error with {0} replaced by the data source type.
- *
- * @param dataSourceType
- * The type of the data source
- * @return The value conversion error string with parameters replaced.
- */
- protected String getConversionError(Class<?> dataSourceType) {
- if (dataSourceType == null) {
- return getConversionError();
- } else {
- return getConversionError().replace("{0}",
- dataSourceType.getSimpleName());
- }
- }
-
- /**
- * Returns the current value (as returned by {@link #getValue()}) converted
- * to the data source type.
- * <p>
- * This returns the same as {@link AbstractField#getValue()} if no converter
- * has been set. The value is not necessarily the same as the data source
- * value e.g. if the field is in buffered mode and has been modified.
- * </p>
- *
- * @return The converted value that is compatible with the data source type
- */
- public Object getConvertedValue() {
- return convertToModel(getFieldValue());
- }
-
- /**
- * Sets the value of the field using a value of the data source type. The
- * value given is converted to the field type and then assigned to the
- * field. This will update the property data source in the same way as when
- * {@link #setValue(Object)} is called.
- *
- * @param value
- * The value to set. Must be the same type as the data source.
- */
- public void setConvertedValue(Object value) {
- setValue(convertFromDataSource(value));
- }
-
- /* Validation */
-
- /**
- * Adds a new validator for the field's value. All validators added to a
- * field are checked each time the its value changes.
- *
- * @param validator
- * the new validator to be added.
- */
- @Override
- public void addValidator(Validator validator) {
- if (validators == null) {
- validators = new LinkedList<Validator>();
- }
- validators.add(validator);
- requestRepaint();
- }
-
- /**
- * Gets the validators of the field.
- *
- * @return the Unmodifiable collection that holds all validators for the
- * field.
- */
- @Override
- public Collection<Validator> getValidators() {
- if (validators == null || validators.isEmpty()) {
- return null;
- }
- return Collections.unmodifiableCollection(validators);
- }
-
- /**
- * Removes the validator from the field.
- *
- * @param validator
- * the validator to remove.
- */
- @Override
- public void removeValidator(Validator validator) {
- if (validators != null) {
- validators.remove(validator);
- }
- requestRepaint();
- }
-
- /**
- * Removes all validators from the field.
- */
- public void removeAllValidators() {
- if (validators != null) {
- validators.clear();
- }
- requestRepaint();
- }
-
- /**
- * Tests the current value against registered validators if the field is not
- * empty. If the field is empty it is considered valid if it is not required
- * and invalid otherwise. Validators are never checked for empty fields.
- *
- * In most cases, {@link #validate()} should be used instead of
- * {@link #isValid()} to also get the error message.
- *
- * @return <code>true</code> if all registered validators claim that the
- * current value is valid or if the field is empty and not required,
- * <code>false</code> otherwise.
- */
- @Override
- public boolean isValid() {
-
- try {
- validate();
- return true;
- } catch (InvalidValueException e) {
- return false;
- }
- }
-
- /**
- * Checks the validity of the Field.
- *
- * A field is invalid if it is set as required (using
- * {@link #setRequired(boolean)} and is empty, if one or several of the
- * validators added to the field indicate it is invalid or if the value
- * cannot be converted provided a converter has been set.
- *
- * The "required" validation is a built-in validation feature. If the field
- * is required and empty this method throws an EmptyValueException with the
- * error message set using {@link #setRequiredError(String)}.
- *
- * @see com.vaadin.data.Validatable#validate()
- */
- @Override
- public void validate() throws Validator.InvalidValueException {
-
- if (isRequired() && isEmpty()) {
- throw new Validator.EmptyValueException(requiredError);
- }
- validate(getFieldValue());
- }
-
- /**
- * Validates that the given value pass the validators for the field.
- * <p>
- * This method does not check the requiredness of the field.
- *
- * @param fieldValue
- * The value to check
- * @throws Validator.InvalidValueException
- * if one or several validators fail
- */
- protected void validate(T fieldValue)
- throws Validator.InvalidValueException {
-
- Object valueToValidate = fieldValue;
-
- // If there is a converter we start by converting the value as we want
- // to validate the converted value
- if (getConverter() != null) {
- try {
- valueToValidate = getConverter().convertToModel(fieldValue,
- getLocale());
- } catch (Exception e) {
- throw new InvalidValueException(
- getConversionError(getConverter().getModelType()));
- }
- }
-
- List<InvalidValueException> validationExceptions = new ArrayList<InvalidValueException>();
- if (validators != null) {
- // Gets all the validation errors
- for (Validator v : validators) {
- try {
- v.validate(valueToValidate);
- } catch (final Validator.InvalidValueException e) {
- validationExceptions.add(e);
- }
- }
- }
-
- // If there were no errors
- if (validationExceptions.isEmpty()) {
- return;
- }
-
- // If only one error occurred, throw it forwards
- if (validationExceptions.size() == 1) {
- throw validationExceptions.get(0);
- }
-
- InvalidValueException[] exceptionArray = validationExceptions
- .toArray(new InvalidValueException[validationExceptions.size()]);
-
- // Create a composite validator and include all exceptions
- throw new Validator.InvalidValueException(null, exceptionArray);
- }
-
- /**
- * Fields allow invalid values by default. In most cases this is wanted,
- * because the field otherwise visually forget the user input immediately.
- *
- * @return true iff the invalid values are allowed.
- * @see com.vaadin.data.Validatable#isInvalidAllowed()
- */
- @Override
- public boolean isInvalidAllowed() {
- return invalidAllowed;
- }
-
- /**
- * Fields allow invalid values by default. In most cases this is wanted,
- * because the field otherwise visually forget the user input immediately.
- * <p>
- * In common setting where the user wants to assure the correctness of the
- * datasource, but allow temporarily invalid contents in the field, the user
- * should add the validators to datasource, that should not allow invalid
- * values. The validators are automatically copied to the field when the
- * datasource is set.
- * </p>
- *
- * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean)
- */
- @Override
- public void setInvalidAllowed(boolean invalidAllowed)
- throws UnsupportedOperationException {
- this.invalidAllowed = invalidAllowed;
- }
-
- /**
- * Error messages shown by the fields are composites of the error message
- * thrown by the superclasses (that is the component error message),
- * validation errors and buffered source errors.
- *
- * @see com.vaadin.ui.AbstractComponent#getErrorMessage()
- */
- @Override
- public ErrorMessage getErrorMessage() {
-
- /*
- * Check validation errors only if automatic validation is enabled.
- * Empty, required fields will generate a validation error containing
- * the requiredError string. For these fields the exclamation mark will
- * be hidden but the error must still be sent to the client.
- */
- Validator.InvalidValueException validationError = null;
- if (isValidationVisible()) {
- try {
- validate();
- } catch (Validator.InvalidValueException e) {
- if (!e.isInvisible()) {
- validationError = e;
- }
- }
- }
-
- // Check if there are any systems errors
- final ErrorMessage superError = super.getErrorMessage();
-
- // Return if there are no errors at all
- if (superError == null && validationError == null
- && getCurrentBufferedSourceException() == null) {
- return null;
- }
-
- // Throw combination of the error types
- return new CompositeErrorMessage(
- new ErrorMessage[] {
- superError,
- AbstractErrorMessage
- .getErrorMessageForException(validationError),
- AbstractErrorMessage
- .getErrorMessageForException(getCurrentBufferedSourceException()) });
-
- }
-
- /* Value change events */
-
- private static final Method VALUE_CHANGE_METHOD;
-
- static {
- try {
- VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
- .getDeclaredMethod("valueChange",
- new Class[] { Property.ValueChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in AbstractField");
- }
- }
-
- /*
- * Adds a value change listener for the field. Don't add a JavaDoc comment
- * here, we use the default documentation from the implemented interface.
- */
- @Override
- public void addListener(Property.ValueChangeListener listener) {
- addListener(AbstractField.ValueChangeEvent.class, listener,
- VALUE_CHANGE_METHOD);
- }
-
- /*
- * Removes a value change listener from the field. Don't add a JavaDoc
- * comment here, we use the default documentation from the implemented
- * interface.
- */
- @Override
- public void removeListener(Property.ValueChangeListener listener) {
- removeListener(AbstractField.ValueChangeEvent.class, listener,
- VALUE_CHANGE_METHOD);
- }
-
- /**
- * Emits the value change event. The value contained in the field is
- * validated before the event is created.
- */
- protected void fireValueChange(boolean repaintIsNotNeeded) {
- fireEvent(new AbstractField.ValueChangeEvent(this));
- if (!repaintIsNotNeeded) {
- requestRepaint();
- }
- }
-
- /* Read-only status change events */
-
- private static final Method READ_ONLY_STATUS_CHANGE_METHOD;
-
- static {
- try {
- READ_ONLY_STATUS_CHANGE_METHOD = Property.ReadOnlyStatusChangeListener.class
- .getDeclaredMethod(
- "readOnlyStatusChange",
- new Class[] { Property.ReadOnlyStatusChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in AbstractField");
- }
- }
-
- /**
- * React to read only status changes of the property by requesting a
- * repaint.
- *
- * @see Property.ReadOnlyStatusChangeListener
- */
- @Override
- public void readOnlyStatusChange(Property.ReadOnlyStatusChangeEvent event) {
- getState().setPropertyReadOnly(event.getProperty().isReadOnly());
- requestRepaint();
- }
-
- /**
- * An <code>Event</code> object specifying the Property whose read-only
- * status has changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class ReadOnlyStatusChangeEvent extends Component.Event
- implements Property.ReadOnlyStatusChangeEvent, Serializable {
-
- /**
- * New instance of text change event.
- *
- * @param source
- * the Source of the event.
- */
- public ReadOnlyStatusChangeEvent(AbstractField source) {
- super(source);
- }
-
- /**
- * Property where the event occurred.
- *
- * @return the Source of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /*
- * Adds a read-only status change listener for the field. Don't add a
- * JavaDoc comment here, we use the default documentation from the
- * implemented interface.
- */
- @Override
- public void addListener(Property.ReadOnlyStatusChangeListener listener) {
- addListener(Property.ReadOnlyStatusChangeEvent.class, listener,
- READ_ONLY_STATUS_CHANGE_METHOD);
- }
-
- /*
- * Removes a read-only status change listener from the field. Don't add a
- * JavaDoc comment here, we use the default documentation from the
- * implemented interface.
- */
- @Override
- public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
- removeListener(Property.ReadOnlyStatusChangeEvent.class, listener,
- READ_ONLY_STATUS_CHANGE_METHOD);
- }
-
- /**
- * Emits the read-only status change event. The value contained in the field
- * is validated before the event is created.
- */
- protected void fireReadOnlyStatusChange() {
- fireEvent(new AbstractField.ReadOnlyStatusChangeEvent(this));
- }
-
- /**
- * This method listens to data source value changes and passes the changes
- * forwards.
- *
- * Changes are not forwarded to the listeners of the field during internal
- * operations of the field to avoid duplicate notifications.
- *
- * @param event
- * the value change event telling the data source contents have
- * changed.
- */
- @Override
- public void valueChange(Property.ValueChangeEvent event) {
- if (isReadThrough()) {
- if (committingValueToDataSource) {
- boolean propertyNotifiesOfTheBufferedValue = equals(event
- .getProperty().getValue(), getInternalValue());
- if (!propertyNotifiesOfTheBufferedValue) {
- /*
- * Property (or chained property like PropertyFormatter) now
- * reports different value than the one the field has just
- * committed to it. In this case we respect the property
- * value.
- *
- * Still, we don't fire value change yet, but instead
- * postpone it until "commit" is done. See setValue(Object,
- * boolean) and commit().
- */
- readValueFromProperty(event);
- valueWasModifiedByDataSourceDuringCommit = true;
- }
- } else if (!isModified()) {
- readValueFromProperty(event);
- fireValueChange(false);
- }
- }
- }
-
- private void readValueFromProperty(Property.ValueChangeEvent event) {
- setInternalValue(convertFromDataSource(event.getProperty().getValue()));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void focus() {
- super.focus();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#getTabIndex()
- */
- @Override
- public int getTabIndex() {
- return getState().getTabIndex();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
- */
- @Override
- public void setTabIndex(int tabIndex) {
- getState().setTabIndex(tabIndex);
- requestRepaint();
- }
-
- /**
- * Returns the internal field value, which might not match the data source
- * value e.g. if the field has been modified and is not in write-through
- * mode.
- *
- * This method can be overridden by subclasses together with
- * {@link #setInternalValue(Object)} to compute internal field value at
- * runtime. When doing so, typically also {@link #isModified()} needs to be
- * overridden and care should be taken in the management of the empty state
- * and buffering support.
- *
- * @return internal field value
- */
- protected T getInternalValue() {
- return value;
- }
-
- /**
- * Sets the internal field value. This is purely used by AbstractField to
- * change the internal Field value. It does not trigger valuechange events.
- * It can be overridden by the inheriting classes to update all dependent
- * variables.
- *
- * Subclasses can also override {@link #getInternalValue()} if necessary.
- *
- * @param newValue
- * the new value to be set.
- */
- protected void setInternalValue(T newValue) {
- value = newValue;
- if (validators != null && !validators.isEmpty()) {
- requestRepaint();
- }
- }
-
- /**
- * Notifies the component that it is connected to an application.
- *
- * @see com.vaadin.ui.Component#attach()
- */
- @Override
- public void attach() {
- super.attach();
-
- if (!isListeningToPropertyEvents) {
- addPropertyListeners();
- if (!isModified() && isReadThrough()) {
- // Update value from data source
- discard();
- }
- }
- }
-
- @Override
- public void detach() {
- super.detach();
- // Stop listening to data source events on detach to avoid a potential
- // memory leak. See #6155.
- removePropertyListeners();
- }
-
- /**
- * Is this field required. Required fields must filled by the user.
- *
- * If the field is required, it is visually indicated in the user interface.
- * Furthermore, setting field to be required implicitly adds "non-empty"
- * validator and thus isValid() == false or any isEmpty() fields. In those
- * cases validation errors are not painted as it is obvious that the user
- * must fill in the required fields.
- *
- * On the other hand, for the non-required fields isValid() == true if the
- * field isEmpty() regardless of any attached validators.
- *
- *
- * @return <code>true</code> if the field is required, otherwise
- * <code>false</code>.
- */
- @Override
- public boolean isRequired() {
- return getState().isRequired();
- }
-
- /**
- * Sets the field required. Required fields must filled by the user.
- *
- * If the field is required, it is visually indicated in the user interface.
- * Furthermore, setting field to be required implicitly adds "non-empty"
- * validator and thus isValid() == false or any isEmpty() fields. In those
- * cases validation errors are not painted as it is obvious that the user
- * must fill in the required fields.
- *
- * On the other hand, for the non-required fields isValid() == true if the
- * field isEmpty() regardless of any attached validators.
- *
- * @param required
- * Is the field required.
- */
- @Override
- public void setRequired(boolean required) {
- getState().setRequired(required);
- requestRepaint();
- }
-
- /**
- * Set the error that is show if this field is required, but empty. When
- * setting requiredMessage to be "" or null, no error pop-up or exclamation
- * mark is shown for a empty required field. This faults to "". Even in
- * those cases isValid() returns false for empty required fields.
- *
- * @param requiredMessage
- * Message to be shown when this field is required, but empty.
- */
- @Override
- public void setRequiredError(String requiredMessage) {
- requiredError = requiredMessage;
- requestRepaint();
- }
-
- @Override
- public String getRequiredError() {
- return requiredError;
- }
-
- /**
- * Gets the error that is shown if the field value cannot be converted to
- * the data source type.
- *
- * @return The error that is shown if conversion of the field value fails
- */
- public String getConversionError() {
- return conversionError;
- }
-
- /**
- * Sets the error that is shown if the field value cannot be converted to
- * the data source type. If {0} is present in the message, it will be
- * replaced by the simple name of the data source type.
- *
- * @param valueConversionError
- * Message to be shown when conversion of the value fails
- */
- public void setConversionError(String valueConversionError) {
- this.conversionError = valueConversionError;
- requestRepaint();
- }
-
- /**
- * Is the field empty?
- *
- * In general, "empty" state is same as null. As an exception, TextField
- * also treats empty string as "empty".
- */
- protected boolean isEmpty() {
- return (getFieldValue() == null);
- }
-
- /**
- * Is automatic, visible validation enabled?
- *
- * If automatic validation is enabled, any validators connected to this
- * component are evaluated while painting the component and potential error
- * messages are sent to client. If the automatic validation is turned off,
- * isValid() and validate() methods still work, but one must show the
- * validation in their own code.
- *
- * @return True, if automatic validation is enabled.
- */
- public boolean isValidationVisible() {
- return validationVisible;
- }
-
- /**
- * Enable or disable automatic, visible validation.
- *
- * If automatic validation is enabled, any validators connected to this
- * component are evaluated while painting the component and potential error
- * messages are sent to client. If the automatic validation is turned off,
- * isValid() and validate() methods still work, but one must show the
- * validation in their own code.
- *
- * @param validateAutomatically
- * True, if automatic validation is enabled.
- */
- public void setValidationVisible(boolean validateAutomatically) {
- if (validationVisible != validateAutomatically) {
- requestRepaint();
- validationVisible = validateAutomatically;
- }
- }
-
- /**
- * Sets the current buffered source exception.
- *
- * @param currentBufferedSourceException
- */
- public void setCurrentBufferedSourceException(
- Buffered.SourceException currentBufferedSourceException) {
- this.currentBufferedSourceException = currentBufferedSourceException;
- requestRepaint();
- }
-
- /**
- * Gets the current buffered source exception.
- *
- * @return The current source exception
- */
- protected Buffered.SourceException getCurrentBufferedSourceException() {
- return currentBufferedSourceException;
- }
-
- /**
- * A ready-made {@link ShortcutListener} that focuses the given
- * {@link Focusable} (usually a {@link Field}) when the keyboard shortcut is
- * invoked.
- *
- */
- public static class FocusShortcut extends ShortcutListener {
- protected Focusable focusable;
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}
- * using the shorthand notation defined in {@link ShortcutAction}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param shorthandCaption
- * caption with keycode and modifiers indicated
- */
- public FocusShortcut(Focusable focusable, String shorthandCaption) {
- super(shorthandCaption);
- this.focusable = focusable;
- }
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param keyCode
- * keycode that invokes the shortcut
- * @param modifiers
- * modifiers required to invoke the shortcut
- */
- public FocusShortcut(Focusable focusable, int keyCode, int... modifiers) {
- super(null, keyCode, modifiers);
- this.focusable = focusable;
- }
-
- /**
- * Creates a keyboard shortcut for focusing the given {@link Focusable}.
- *
- * @param focusable
- * to focused when the shortcut is invoked
- * @param keyCode
- * keycode that invokes the shortcut
- */
- public FocusShortcut(Focusable focusable, int keyCode) {
- this(focusable, keyCode, null);
- }
-
- @Override
- public void handleAction(Object sender, Object target) {
- focusable.focus();
- }
- }
-
- /**
- * Gets the converter used to convert the property data source value to the
- * field value.
- *
- * @return The converter or null if none is set.
- */
- public Converter<T, Object> getConverter() {
- return converter;
- }
-
- /**
- * Sets the converter used to convert the field value to property data
- * source type. The converter must have a presentation type that matches the
- * field type.
- *
- * @param converter
- * The new converter to use.
- */
- public void setConverter(Converter<T, ?> converter) {
- this.converter = (Converter<T, Object>) converter;
- requestRepaint();
- }
-
- @Override
- public AbstractFieldState getState() {
- return (AbstractFieldState) super.getState();
- }
-
- @Override
- public void updateState() {
- super.updateState();
-
- // Hide the error indicator if needed
- getState().setHideErrors(shouldHideErrors());
- }
-
- /**
- * Registers this as an event listener for events sent by the data source
- * (if any). Does nothing if
- * <code>isListeningToPropertyEvents == true</code>.
- */
- private void addPropertyListeners() {
- if (!isListeningToPropertyEvents) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource).addListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .addListener(this);
- }
- isListeningToPropertyEvents = true;
- }
- }
-
- /**
- * Stops listening to events sent by the data source (if any). Does nothing
- * if <code>isListeningToPropertyEvents == false</code>.
- */
- private void removePropertyListeners() {
- if (isListeningToPropertyEvents) {
- if (dataSource instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) dataSource)
- .removeListener(this);
- }
- if (dataSource instanceof Property.ReadOnlyStatusChangeNotifier) {
- ((Property.ReadOnlyStatusChangeNotifier) dataSource)
- .removeListener(this);
- }
- isListeningToPropertyEvents = false;
- }
- }
-}
diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java
deleted file mode 100644
index 5ec80573ab..0000000000
--- a/src/com/vaadin/ui/AbstractJavaScriptComponent.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import com.vaadin.shared.ui.JavaScriptComponentState;
-import com.vaadin.terminal.JavaScriptCallbackHelper;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.ui.JavaScriptWidget;
-
-/**
- * Base class for Components with all client-side logic implemented using
- * JavaScript.
- * <p>
- * When a new JavaScript component is initialized in the browser, the framework
- * will look for a globally defined JavaScript function that will initialize the
- * component. The name of the initialization function is formed by replacing .
- * with _ in the name of the server-side class. If no such function is defined,
- * each super class is used in turn until a match is found. The framework will
- * thus first attempt with <code>com_example_MyComponent</code> for the
- * server-side
- * <code>com.example.MyComponent extends AbstractJavaScriptComponent</code>
- * class. If MyComponent instead extends <code>com.example.SuperComponent</code>
- * , then <code>com_example_SuperComponent</code> will also be attempted if
- * <code>com_example_MyComponent</code> has not been defined.
- * <p>
- * JavaScript components have a very simple GWT widget ({@link JavaScriptWidget}
- * ) just consisting of a <code>div</code> element to which the JavaScript code
- * should initialize its own user interface.
- * <p>
- * The initialization function will be called with <code>this</code> pointing to
- * a connector wrapper object providing integration to Vaadin with the following
- * functions:
- * <ul>
- * <li><code>getConnectorId()</code> - returns a string with the id of the
- * connector.</li>
- * <li><code>getParentId([connectorId])</code> - returns a string with the id of
- * the connector's parent. If <code>connectorId</code> is provided, the id of
- * the parent of the corresponding connector with the passed id is returned
- * instead.</li>
- * <li><code>getElement([connectorId])</code> - returns the DOM Element that is
- * the root of a connector's widget. <code>null</code> is returned if the
- * connector can not be found or if the connector doesn't have a widget. If
- * <code>connectorId</code> is not provided, the connector id of the current
- * connector will be used.</li>
- * <li><code>getState()</code> - returns an object corresponding to the shared
- * state defined on the server. The scheme for conversion between Java and
- * JavaScript types is described bellow.</li>
- * <li><code>registerRpc([name, ] rpcObject)</code> - registers the
- * <code>rpcObject</code> as a RPC handler. <code>rpcObject</code> should be an
- * object with field containing functions for all eligible RPC functions. If
- * <code>name</code> is provided, the RPC handler will only used for RPC calls
- * for the RPC interface with the same fully qualified Java name. If no
- * <code>name</code> is provided, the RPC handler will be used for all incoming
- * RPC invocations where the RPC method name is defined as a function field in
- * the handler. The scheme for conversion between Java types in the RPC
- * interface definition and the JavaScript values passed as arguments to the
- * handler functions is described bellow.</li>
- * <li><code>getRpcProxy([name])</code> - returns an RPC proxy object. If
- * <code>name</code> is provided, the proxy object will contain functions for
- * all methods in the RPC interface with the same fully qualified name, provided
- * a RPC handler has been registered by the server-side code. If no
- * <code>name</code> is provided, the returned RPC proxy object will contain
- * functions for all methods in all RPC interfaces registered for the connector
- * on the server. If the same method name is present in multiple registered RPC
- * interfaces, the corresponding function in the RPC proxy object will throw an
- * exception when called. The scheme for conversion between Java types in the
- * RPC interface and the JavaScript values that should be passed to the
- * functions is described bellow.</li>
- * <li><code>translateVaadinUri(uri)</code> - Translates a Vaadin URI to a URL
- * that can be used in the browser. This is just way of accessing
- * {@link ApplicationConnection#translateVaadinUri(String)}</li>
- * </ul>
- * The connector wrapper also supports these special functions:
- * <ul>
- * <li><code>onStateChange</code> - If the JavaScript code assigns a function to
- * the field, that function is called whenever the contents of the shared state
- * is changed.</li>
- * <li>Any field name corresponding to a call to
- * {@link #addFunction(String, JavaScriptFunction)} on the server will
- * automatically be present as a function that triggers the registered function
- * on the server.</li>
- * <li>Any field name referred to using
- * {@link #callFunction(String, Object...)} on the server will be called if a
- * function has been assigned to the field.</li>
- * </ul>
- * <p>
- *
- * Values in the Shared State and in RPC calls are converted between Java and
- * JavaScript using the following conventions:
- * <ul>
- * <li>Primitive Java numbers (byte, char, int, long, float, double) and their
- * boxed types (Byte, Character, Integer, Long, Float, Double) are represented
- * by JavaScript numbers.</li>
- * <li>The primitive Java boolean and the boxed Boolean are represented by
- * JavaScript booleans.</li>
- * <li>Java Strings are represented by JavaScript strings.</li>
- * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li>
- * <li>Map<String, ?> in Java is represented by JavaScript object with fields
- * corresponding to the map keys.</li>
- * <li>Any other Java Map is represented by a JavaScript array containing two
- * arrays, the first contains the keys and the second contains the values in the
- * same order.</li>
- * <li>A Java Bean is represented by a JavaScript object with fields
- * corresponding to the bean's properties.</li>
- * <li>A Java Connector is represented by a JavaScript string containing the
- * connector's id.</li>
- * <li>A pluggable serialization mechanism is provided for types not described
- * here. Please refer to the documentation for specific types for serialization
- * information.</li>
- * </ul>
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public abstract class AbstractJavaScriptComponent extends AbstractComponent {
- private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper(
- this);
-
- @Override
- protected <T> void registerRpc(T implementation, Class<T> rpcInterfaceType) {
- super.registerRpc(implementation, rpcInterfaceType);
- callbackHelper.registerRpc(rpcInterfaceType);
- }
-
- /**
- * Register a {@link JavaScriptFunction} that can be called from the
- * JavaScript using the provided name. A JavaScript function with the
- * provided name will be added to the connector wrapper object (initially
- * available as <code>this</code>). Calling that JavaScript function will
- * cause the call method in the registered {@link JavaScriptFunction} to be
- * invoked with the same arguments.
- *
- * @param functionName
- * the name that should be used for client-side function
- * @param function
- * the {@link JavaScriptFunction} object that will be invoked
- * when the JavaScript function is called
- */
- protected void addFunction(String functionName, JavaScriptFunction function) {
- callbackHelper.registerCallback(functionName, function);
- }
-
- /**
- * Invoke a named function that the connector JavaScript has added to the
- * JavaScript connector wrapper object. The arguments should only contain
- * data types that can be represented in JavaScript including primitives,
- * their boxed types, arrays, String, List, Set, Map, Connector and
- * JavaBeans.
- *
- * @param name
- * the name of the function
- * @param arguments
- * function arguments
- */
- protected void callFunction(String name, Object... arguments) {
- callbackHelper.invokeCallback(name, arguments);
- }
-
- @Override
- public JavaScriptComponentState getState() {
- return (JavaScriptComponentState) super.getState();
- }
-}
diff --git a/src/com/vaadin/ui/AbstractLayout.java b/src/com/vaadin/ui/AbstractLayout.java
deleted file mode 100644
index 7b3a537d06..0000000000
--- a/src/com/vaadin/ui/AbstractLayout.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.shared.ui.AbstractLayoutState;
-import com.vaadin.ui.Layout.MarginHandler;
-
-/**
- * An abstract class that defines default implementation for the {@link Layout}
- * interface.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@SuppressWarnings("serial")
-public abstract class AbstractLayout extends AbstractComponentContainer
- implements Layout, MarginHandler {
-
- protected MarginInfo margins = new MarginInfo(false);
-
- @Override
- public AbstractLayoutState getState() {
- return (AbstractLayoutState) super.getState();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout#setMargin(boolean)
- */
- @Override
- public void setMargin(boolean enabled) {
- margins.setMargins(enabled);
- getState().setMarginsBitmask(margins.getBitMask());
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.MarginHandler#getMargin()
- */
- @Override
- public MarginInfo getMargin() {
- return margins;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.MarginHandler#setMargin(MarginInfo)
- */
- @Override
- public void setMargin(MarginInfo marginInfo) {
- margins.setMargins(marginInfo);
- getState().setMarginsBitmask(margins.getBitMask());
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout#setMargin(boolean, boolean, boolean, boolean)
- */
- @Override
- public void setMargin(boolean topEnabled, boolean rightEnabled,
- boolean bottomEnabled, boolean leftEnabled) {
- margins.setMargins(topEnabled, rightEnabled, bottomEnabled, leftEnabled);
- getState().setMarginsBitmask(margins.getBitMask());
- requestRepaint();
- }
-
-}
diff --git a/src/com/vaadin/ui/AbstractMedia.java b/src/com/vaadin/ui/AbstractMedia.java
deleted file mode 100644
index 71b2e38ef3..0000000000
--- a/src/com/vaadin/ui/AbstractMedia.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.vaadin.shared.communication.URLReference;
-import com.vaadin.shared.ui.AbstractMediaState;
-import com.vaadin.shared.ui.MediaControl;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.server.ResourceReference;
-
-/**
- * Abstract base class for the HTML5 media components.
- *
- * @author Vaadin Ltd
- */
-public abstract class AbstractMedia extends AbstractComponent {
-
- @Override
- public AbstractMediaState getState() {
- return (AbstractMediaState) super.getState();
- }
-
- /**
- * Sets a single media file as the source of the media component.
- *
- * @param source
- */
- public void setSource(Resource source) {
- clearSources();
-
- addSource(source);
- }
-
- private void clearSources() {
- getState().getSources().clear();
- getState().getSourceTypes().clear();
- }
-
- /**
- * Adds an alternative media file to the sources list. Which of the sources
- * is used is selected by the browser depending on which file formats it
- * supports. See <a
- * href="http://en.wikipedia.org/wiki/HTML5_video#Table">wikipedia</a> for a
- * table of formats supported by different browsers.
- *
- * @param source
- */
- public void addSource(Resource source) {
- if (source != null) {
- getState().getSources().add(new ResourceReference(source));
- getState().getSourceTypes().add(source.getMIMEType());
- requestRepaint();
- }
- }
-
- /**
- * Set multiple sources at once. Which of the sources is used is selected by
- * the browser depending on which file formats it supports. See <a
- * href="http://en.wikipedia.org/wiki/HTML5_video#Table">wikipedia</a> for a
- * table of formats supported by different browsers.
- *
- * @param sources
- */
- public void setSources(Resource... sources) {
- clearSources();
- for (Resource source : sources) {
- addSource(source);
- }
- }
-
- /**
- * @return The sources pointed to in this media.
- */
- public List<Resource> getSources() {
- ArrayList<Resource> sources = new ArrayList<Resource>();
- for (URLReference ref : getState().getSources()) {
- sources.add(((ResourceReference) ref).getResource());
- }
- return sources;
- }
-
- /**
- * Sets whether or not the browser should show native media controls.
- *
- * @param showControls
- */
- public void setShowControls(boolean showControls) {
- getState().setShowControls(showControls);
- requestRepaint();
- }
-
- /**
- * @return true if the browser is to show native media controls.
- */
- public boolean isShowControls() {
- return getState().isShowControls();
- }
-
- /**
- * Sets the alternative text to be displayed if the browser does not support
- * HTML5. This text is rendered as HTML if
- * {@link #setHtmlContentAllowed(boolean)} is set to true. With HTML
- * rendering, this method can also be used to implement fallback to a
- * flash-based player, see the <a href=
- * "https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Using_Flash"
- * >Mozilla Developer Network</a> for details.
- *
- * @param altText
- */
- public void setAltText(String altText) {
- getState().setAltText(altText);
- requestRepaint();
- }
-
- /**
- * @return The text/html that is displayed when a browser doesn't support
- * HTML5.
- */
- public String getAltText() {
- return getState().getAltText();
- }
-
- /**
- * Set whether the alternative text ({@link #setAltText(String)}) is
- * rendered as HTML or not.
- *
- * @param htmlContentAllowed
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- getState().setHtmlContentAllowed(htmlContentAllowed);
- requestRepaint();
- }
-
- /**
- * @return true if the alternative text ({@link #setAltText(String)}) is to
- * be rendered as HTML.
- */
- public boolean isHtmlContentAllowed() {
- return getState().isHtmlContentAllowed();
- }
-
- /**
- * Sets whether the media is to automatically start playback when enough
- * data has been loaded.
- *
- * @param autoplay
- */
- public void setAutoplay(boolean autoplay) {
- getState().setAutoplay(autoplay);
- requestRepaint();
- }
-
- /**
- * @return true if the media is set to automatically start playback.
- */
- public boolean isAutoplay() {
- return getState().isAutoplay();
- }
-
- /**
- * Set whether to mute the audio or not.
- *
- * @param muted
- */
- public void setMuted(boolean muted) {
- getState().setMuted(muted);
- requestRepaint();
- }
-
- /**
- * @return true if the audio is muted.
- */
- public boolean isMuted() {
- return getState().isMuted();
- }
-
- /**
- * Pauses the media.
- */
- public void pause() {
- getRpcProxy(MediaControl.class).pause();
- }
-
- /**
- * Starts playback of the media.
- */
- public void play() {
- getRpcProxy(MediaControl.class).play();
- }
-
-}
diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java
deleted file mode 100644
index 0581d0a279..0000000000
--- a/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.vaadin.event.LayoutEvents.LayoutClickEvent;
-import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutServerRpc;
-import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState;
-import com.vaadin.shared.ui.orderedlayout.AbstractOrderedLayoutState.ChildComponentData;
-import com.vaadin.terminal.Sizeable;
-import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
-
-@SuppressWarnings("serial")
-public abstract class AbstractOrderedLayout extends AbstractLayout implements
- Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier {
-
- private AbstractOrderedLayoutServerRpc rpc = new AbstractOrderedLayoutServerRpc() {
-
- @Override
- public void layoutClick(MouseEventDetails mouseDetails,
- Connector clickedConnector) {
- fireEvent(LayoutClickEvent.createEvent(AbstractOrderedLayout.this,
- mouseDetails, clickedConnector));
- }
- };
-
- public static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT;
-
- /**
- * Custom layout slots containing the components.
- */
- protected LinkedList<Component> components = new LinkedList<Component>();
-
- /* Child component alignments */
-
- /**
- * Mapping from components to alignments (horizontal + vertical).
- */
- public AbstractOrderedLayout() {
- registerRpc(rpc);
- }
-
- @Override
- public AbstractOrderedLayoutState getState() {
- return (AbstractOrderedLayoutState) super.getState();
- }
-
- /**
- * Add a component into this container. The component is added to the right
- * or under the previous component.
- *
- * @param c
- * the component to be added.
- */
- @Override
- public void addComponent(Component c) {
- // Add to components before calling super.addComponent
- // so that it is available to AttachListeners
- components.add(c);
- try {
- super.addComponent(c);
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
- componentAdded(c);
- }
-
- /**
- * Adds a component into this container. The component is added to the left
- * or on top of the other components.
- *
- * @param c
- * the component to be added.
- */
- public void addComponentAsFirst(Component c) {
- // If c is already in this, we must remove it before proceeding
- // see ticket #7668
- if (c.getParent() == this) {
- removeComponent(c);
- }
- components.addFirst(c);
- try {
- super.addComponent(c);
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
- componentAdded(c);
-
- }
-
- /**
- * Adds a component into indexed position in this container.
- *
- * @param c
- * the component to be added.
- * @param index
- * the index of the component position. The components currently
- * in and after the position are shifted forwards.
- */
- public void addComponent(Component c, int index) {
- // If c is already in this, we must remove it before proceeding
- // see ticket #7668
- if (c.getParent() == this) {
- // When c is removed, all components after it are shifted down
- if (index > getComponentIndex(c)) {
- index--;
- }
- removeComponent(c);
- }
- components.add(index, c);
- try {
- super.addComponent(c);
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
-
- componentAdded(c);
- }
-
- private void componentRemoved(Component c) {
- getState().getChildData().remove(c);
- requestRepaint();
- }
-
- private void componentAdded(Component c) {
- getState().getChildData().put(c, new ChildComponentData());
- requestRepaint();
-
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
- @Override
- public void removeComponent(Component c) {
- components.remove(c);
- super.removeComponent(c);
- componentRemoved(c);
- }
-
- /**
- * Gets the component container iterator for going trough all the components
- * in the container.
- *
- * @return the Iterator of the components inside the container.
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return components.iterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
- @Override
- public int getComponentCount() {
- return components.size();
- }
-
- /* Documented in superclass */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- // Gets the locations
- int oldLocation = -1;
- int newLocation = -1;
- int location = 0;
- for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
- final Component component = i.next();
-
- if (component == oldComponent) {
- oldLocation = location;
- }
- if (component == newComponent) {
- newLocation = location;
- }
-
- location++;
- }
-
- if (oldLocation == -1) {
- addComponent(newComponent);
- } else if (newLocation == -1) {
- removeComponent(oldComponent);
- addComponent(newComponent, oldLocation);
- } else {
- // Both old and new are in the layout
- if (oldLocation > newLocation) {
- components.remove(oldComponent);
- components.add(newLocation, oldComponent);
- components.remove(newComponent);
- components.add(oldLocation, newComponent);
- } else {
- components.remove(newComponent);
- components.add(oldLocation, newComponent);
- components.remove(oldComponent);
- components.add(newLocation, oldComponent);
- }
-
- requestRepaint();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.AlignmentHandler#setComponentAlignment(com
- * .vaadin.ui.Component, int, int)
- */
- @Override
- public void setComponentAlignment(Component childComponent,
- int horizontalAlignment, int verticalAlignment) {
- Alignment a = new Alignment(horizontalAlignment + verticalAlignment);
- setComponentAlignment(childComponent, a);
- }
-
- @Override
- public void setComponentAlignment(Component childComponent,
- Alignment alignment) {
- ChildComponentData childData = getState().getChildData().get(
- childComponent);
- if (childData != null) {
- // Alignments are bit masks
- childData.setAlignmentBitmask(alignment.getBitMask());
- requestRepaint();
- } else {
- throw new IllegalArgumentException(
- "Component must be added to layout before using setComponentAlignment()");
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.AlignmentHandler#getComponentAlignment(com
- * .vaadin.ui.Component)
- */
- @Override
- public Alignment getComponentAlignment(Component childComponent) {
- ChildComponentData childData = getState().getChildData().get(
- childComponent);
- if (childData == null) {
- throw new IllegalArgumentException(
- "The given component is not a child of this layout");
- }
-
- return new Alignment(childData.getAlignmentBitmask());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.SpacingHandler#setSpacing(boolean)
- */
- @Override
- public void setSpacing(boolean spacing) {
- getState().setSpacing(spacing);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.SpacingHandler#isSpacing()
- */
- @Override
- public boolean isSpacing() {
- return getState().isSpacing();
- }
-
- /**
- * <p>
- * This method is used to control how excess space in layout is distributed
- * among components. Excess space may exist if layout is sized and contained
- * non relatively sized components don't consume all available space.
- *
- * <p>
- * Example how to distribute 1:3 (33%) for component1 and 2:3 (67%) for
- * component2 :
- *
- * <code>
- * layout.setExpandRatio(component1, 1);<br>
- * layout.setExpandRatio(component2, 2);
- * </code>
- *
- * <p>
- * If no ratios have been set, the excess space is distributed evenly among
- * all components.
- *
- * <p>
- * Note, that width or height (depending on orientation) needs to be defined
- * for this method to have any effect.
- *
- * @see Sizeable
- *
- * @param component
- * the component in this layout which expand ratio is to be set
- * @param ratio
- */
- public void setExpandRatio(Component component, float ratio) {
- ChildComponentData childData = getState().getChildData().get(component);
- if (childData == null) {
- throw new IllegalArgumentException(
- "The given component is not a child of this layout");
- }
-
- childData.setExpandRatio(ratio);
- requestRepaint();
- };
-
- /**
- * Returns the expand ratio of given component.
- *
- * @param component
- * which expand ratios is requested
- * @return expand ratio of given component, 0.0f by default.
- */
- public float getExpandRatio(Component component) {
- ChildComponentData childData = getState().getChildData().get(component);
- if (childData == null) {
- throw new IllegalArgumentException(
- "The given component is not a child of this layout");
- }
-
- return childData.getExpandRatio();
- }
-
- @Override
- public void addListener(LayoutClickListener listener) {
- addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener,
- LayoutClickListener.clickMethod);
- }
-
- @Override
- public void removeListener(LayoutClickListener listener) {
- removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener);
- }
-
- /**
- * Returns the index of the given component.
- *
- * @param component
- * The component to look up.
- * @return The index of the component or -1 if the component is not a child.
- */
- public int getComponentIndex(Component component) {
- return components.indexOf(component);
- }
-
- /**
- * Returns the component at the given position.
- *
- * @param index
- * The position of the component.
- * @return The component at the given index.
- * @throws IndexOutOfBoundsException
- * If the index is out of range.
- */
- public Component getComponent(int index) throws IndexOutOfBoundsException {
- return components.get(index);
- }
-
-}
diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java
deleted file mode 100644
index 0a97ceb649..0000000000
--- a/src/com/vaadin/ui/AbstractSelect.java
+++ /dev/null
@@ -1,2029 +0,0 @@
-/*
- * @VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.util.IndexedContainer;
-import com.vaadin.event.DataBoundTransferable;
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.event.dd.TargetDetailsImpl;
-import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion;
-import com.vaadin.event.dd.acceptcriteria.ContainsDataFlavor;
-import com.vaadin.event.dd.acceptcriteria.TargetDetailIs;
-import com.vaadin.shared.ui.dd.VerticalDropLocation;
-import com.vaadin.terminal.KeyMapper;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
-
-/**
- * <p>
- * A class representing a selection of items the user has selected in a UI. The
- * set of choices is presented as a set of {@link com.vaadin.data.Item}s in a
- * {@link com.vaadin.data.Container}.
- * </p>
- *
- * <p>
- * A <code>Select</code> component may be in single- or multiselect mode.
- * Multiselect mode means that more than one item can be selected
- * simultaneously.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-@SuppressWarnings("serial")
-// TODO currently cannot specify type more precisely in case of multi-select
-public abstract class AbstractSelect extends AbstractField<Object> implements
- Container, Container.Viewer, Container.PropertySetChangeListener,
- Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier,
- Container.ItemSetChangeListener, Vaadin6Component {
-
- public enum ItemCaptionMode {
- /**
- * Item caption mode: Item's ID's <code>String</code> representation is
- * used as caption.
- */
- ID,
- /**
- * Item caption mode: Item's <code>String</code> representation is used
- * as caption.
- */
- ITEM,
- /**
- * Item caption mode: Index of the item is used as caption. The index
- * mode can only be used with the containers implementing the
- * {@link com.vaadin.data.Container.Indexed} interface.
- */
- INDEX,
- /**
- * Item caption mode: If an Item has a caption it's used, if not, Item's
- * ID's <code>String</code> representation is used as caption. <b>This
- * is the default</b>.
- */
- EXPLICIT_DEFAULTS_ID,
- /**
- * Item caption mode: Captions must be explicitly specified.
- */
- EXPLICIT,
- /**
- * Item caption mode: Only icons are shown, captions are hidden.
- */
- ICON_ONLY,
- /**
- * Item caption mode: Item captions are read from property specified
- * with <code>setItemCaptionPropertyId</code>.
- */
- PROPERTY;
- }
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_ID = ItemCaptionMode.ID;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_ITEM = ItemCaptionMode.ITEM;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_INDEX = ItemCaptionMode.INDEX;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = ItemCaptionMode.EXPLICIT_DEFAULTS_ID;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT = ItemCaptionMode.EXPLICIT;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_ICON_ONLY = ItemCaptionMode.ICON_ONLY;
-
- /**
- * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
- */
- @Deprecated
- public static final ItemCaptionMode ITEM_CAPTION_MODE_PROPERTY = ItemCaptionMode.PROPERTY;
-
- /**
- * Interface for option filtering, used to filter options based on user
- * entered value. The value is matched to the item caption.
- * <code>FILTERINGMODE_OFF</code> (0) turns the filtering off.
- * <code>FILTERINGMODE_STARTSWITH</code> (1) matches from the start of the
- * caption. <code>FILTERINGMODE_CONTAINS</code> (1) matches anywhere in the
- * caption.
- */
- public interface Filtering extends Serializable {
- public static final int FILTERINGMODE_OFF = 0;
- public static final int FILTERINGMODE_STARTSWITH = 1;
- public static final int FILTERINGMODE_CONTAINS = 2;
-
- /**
- * Sets the option filtering mode.
- *
- * @param filteringMode
- * the filtering mode to use
- */
- public void setFilteringMode(int filteringMode);
-
- /**
- * Gets the current filtering mode.
- *
- * @return the filtering mode in use
- */
- public int getFilteringMode();
-
- }
-
- /**
- * Multi select modes that controls how multi select behaves.
- */
- public enum MultiSelectMode {
- /**
- * The default behavior of the multi select mode
- */
- DEFAULT,
-
- /**
- * The previous more simple behavior of the multselect
- */
- SIMPLE
- }
-
- /**
- * Is the select in multiselect mode?
- */
- private boolean multiSelect = false;
-
- /**
- * Select options.
- */
- protected Container items;
-
- /**
- * Is the user allowed to add new options?
- */
- private boolean allowNewOptions;
-
- /**
- * Keymapper used to map key values.
- */
- protected KeyMapper<Object> itemIdMapper = new KeyMapper<Object>();
-
- /**
- * Item icons.
- */
- private final HashMap<Object, Resource> itemIcons = new HashMap<Object, Resource>();
-
- /**
- * Item captions.
- */
- private final HashMap<Object, String> itemCaptions = new HashMap<Object, String>();
-
- /**
- * Item caption mode.
- */
- private ItemCaptionMode itemCaptionMode = ItemCaptionMode.EXPLICIT_DEFAULTS_ID;
-
- /**
- * Item caption source property id.
- */
- private Object itemCaptionPropertyId = null;
-
- /**
- * Item icon source property id.
- */
- private Object itemIconPropertyId = null;
-
- /**
- * List of property set change event listeners.
- */
- private Set<Container.PropertySetChangeListener> propertySetEventListeners = null;
-
- /**
- * List of item set change event listeners.
- */
- private Set<Container.ItemSetChangeListener> itemSetEventListeners = null;
-
- /**
- * Item id that represents null selection of this select.
- *
- * <p>
- * Data interface does not support nulls as item ids. Selecting the item
- * identified by this id is the same as selecting no items at all. This
- * setting only affects the single select mode.
- * </p>
- */
- private Object nullSelectionItemId = null;
-
- // Null (empty) selection is enabled by default
- private boolean nullSelectionAllowed = true;
- private NewItemHandler newItemHandler;
-
- // Caption (Item / Property) change listeners
- CaptionChangeListener captionChangeListener;
-
- /* Constructors */
-
- /**
- * Creates an empty Select. The caption is not used.
- */
- public AbstractSelect() {
- setContainerDataSource(new IndexedContainer());
- }
-
- /**
- * Creates an empty Select with caption.
- */
- public AbstractSelect(String caption) {
- setContainerDataSource(new IndexedContainer());
- setCaption(caption);
- }
-
- /**
- * Creates a new select that is connected to a data-source.
- *
- * @param caption
- * the Caption of the component.
- * @param dataSource
- * the Container datasource to be selected from by this select.
- */
- public AbstractSelect(String caption, Container dataSource) {
- setCaption(caption);
- setContainerDataSource(dataSource);
- }
-
- /**
- * Creates a new select that is filled from a collection of option values.
- *
- * @param caption
- * the Caption of this field.
- * @param options
- * the Collection containing the options.
- */
- public AbstractSelect(String caption, Collection<?> options) {
-
- // Creates the options container and add given options to it
- final Container c = new IndexedContainer();
- if (options != null) {
- for (final Iterator<?> i = options.iterator(); i.hasNext();) {
- c.addItem(i.next());
- }
- }
-
- setCaption(caption);
- setContainerDataSource(c);
- }
-
- /* Component methods */
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- // Paints select attributes
- if (isMultiSelect()) {
- target.addAttribute("selectmode", "multi");
- }
- if (isNewItemsAllowed()) {
- target.addAttribute("allownewitem", true);
- }
- if (isNullSelectionAllowed()) {
- target.addAttribute("nullselect", true);
- if (getNullSelectionItemId() != null) {
- target.addAttribute("nullselectitem", true);
- }
- }
-
- // Constructs selected keys array
- String[] selectedKeys;
- if (isMultiSelect()) {
- selectedKeys = new String[((Set<?>) getValue()).size()];
- } else {
- selectedKeys = new String[(getValue() == null
- && getNullSelectionItemId() == null ? 0 : 1)];
- }
-
- // ==
- // first remove all previous item/property listeners
- getCaptionChangeListener().clear();
- // Paints the options and create array of selected id keys
-
- target.startTag("options");
- int keyIndex = 0;
- // Support for external null selection item id
- final Collection<?> ids = getItemIds();
- if (isNullSelectionAllowed() && getNullSelectionItemId() != null
- && !ids.contains(getNullSelectionItemId())) {
- final Object id = getNullSelectionItemId();
- // Paints option
- target.startTag("so");
- paintItem(target, id);
- if (isSelected(id)) {
- selectedKeys[keyIndex++] = itemIdMapper.key(id);
- }
- target.endTag("so");
- }
-
- final Iterator<?> i = getItemIds().iterator();
- // Paints the available selection options from data source
- while (i.hasNext()) {
- // Gets the option attribute values
- final Object id = i.next();
- if (!isNullSelectionAllowed() && id != null
- && id.equals(getNullSelectionItemId())) {
- // Remove item if it's the null selection item but null
- // selection is not allowed
- continue;
- }
- final String key = itemIdMapper.key(id);
- // add listener for each item, to cause repaint if an item changes
- getCaptionChangeListener().addNotifierForItem(id);
- target.startTag("so");
- paintItem(target, id);
- if (isSelected(id) && keyIndex < selectedKeys.length) {
- selectedKeys[keyIndex++] = key;
- }
- target.endTag("so");
- }
- target.endTag("options");
- // ==
-
- // Paint variables
- target.addVariable(this, "selected", selectedKeys);
- if (isNewItemsAllowed()) {
- target.addVariable(this, "newitem", "");
- }
-
- }
-
- protected void paintItem(PaintTarget target, Object itemId)
- throws PaintException {
- final String key = itemIdMapper.key(itemId);
- final String caption = getItemCaption(itemId);
- final Resource icon = getItemIcon(itemId);
- if (icon != null) {
- target.addAttribute("icon", icon);
- }
- target.addAttribute("caption", caption);
- if (itemId != null && itemId.equals(getNullSelectionItemId())) {
- target.addAttribute("nullselection", true);
- }
- target.addAttribute("key", key);
- if (isSelected(itemId)) {
- target.addAttribute("selected", true);
- }
- }
-
- /**
- * Invoked when the value of a variable has changed.
- *
- * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
-
- // New option entered (and it is allowed)
- if (isNewItemsAllowed()) {
- final String newitem = (String) variables.get("newitem");
- if (newitem != null && newitem.length() > 0) {
- getNewItemHandler().addNewItem(newitem);
- }
- }
-
- // Selection change
- if (variables.containsKey("selected")) {
- final String[] clientSideSelectedKeys = (String[]) variables
- .get("selected");
-
- // Multiselect mode
- if (isMultiSelect()) {
-
- // TODO Optimize by adding repaintNotNeeded when applicable
-
- // Converts the key-array to id-set
- final LinkedList<Object> acceptedSelections = new LinkedList<Object>();
- for (int i = 0; i < clientSideSelectedKeys.length; i++) {
- final Object id = itemIdMapper
- .get(clientSideSelectedKeys[i]);
- if (!isNullSelectionAllowed()
- && (id == null || id == getNullSelectionItemId())) {
- // skip empty selection if nullselection is not allowed
- requestRepaint();
- } else if (id != null && containsId(id)) {
- acceptedSelections.add(id);
- }
- }
-
- if (!isNullSelectionAllowed() && acceptedSelections.size() < 1) {
- // empty selection not allowed, keep old value
- requestRepaint();
- return;
- }
-
- // Limits the deselection to the set of visible items
- // (non-visible items can not be deselected)
- Collection<?> visibleNotSelected = getVisibleItemIds();
- if (visibleNotSelected != null) {
- visibleNotSelected = new HashSet<Object>(visibleNotSelected);
- // Don't remove those that will be added to preserve order
- visibleNotSelected.removeAll(acceptedSelections);
-
- @SuppressWarnings("unchecked")
- Set<Object> newsel = (Set<Object>) getValue();
- if (newsel == null) {
- newsel = new LinkedHashSet<Object>();
- } else {
- newsel = new LinkedHashSet<Object>(newsel);
- }
- newsel.removeAll(visibleNotSelected);
- newsel.addAll(acceptedSelections);
- setValue(newsel, true);
- }
- } else {
- // Single select mode
- if (!isNullSelectionAllowed()
- && (clientSideSelectedKeys.length == 0
- || clientSideSelectedKeys[0] == null || clientSideSelectedKeys[0] == getNullSelectionItemId())) {
- requestRepaint();
- return;
- }
- if (clientSideSelectedKeys.length == 0) {
- // Allows deselection only if the deselected item is
- // visible
- final Object current = getValue();
- final Collection<?> visible = getVisibleItemIds();
- if (visible != null && visible.contains(current)) {
- setValue(null, true);
- }
- } else {
- final Object id = itemIdMapper
- .get(clientSideSelectedKeys[0]);
- if (!isNullSelectionAllowed() && id == null) {
- requestRepaint();
- } else if (id != null
- && id.equals(getNullSelectionItemId())) {
- setValue(null, true);
- } else {
- setValue(id, true);
- }
- }
- }
- }
- }
-
- /**
- * TODO refine doc Setter for new item handler that is called when user adds
- * new item in newItemAllowed mode.
- *
- * @param newItemHandler
- */
- public void setNewItemHandler(NewItemHandler newItemHandler) {
- this.newItemHandler = newItemHandler;
- }
-
- /**
- * TODO refine doc
- *
- * @return
- */
- public NewItemHandler getNewItemHandler() {
- if (newItemHandler == null) {
- newItemHandler = new DefaultNewItemHandler();
- }
- return newItemHandler;
- }
-
- public interface NewItemHandler extends Serializable {
- void addNewItem(String newItemCaption);
- }
-
- /**
- * TODO refine doc
- *
- * This is a default class that handles adding new items that are typed by
- * user to selects container.
- *
- * By extending this class one may implement some logic on new item addition
- * like database inserts.
- *
- */
- public class DefaultNewItemHandler implements NewItemHandler {
- @Override
- public void addNewItem(String newItemCaption) {
- // Checks for readonly
- if (isReadOnly()) {
- throw new Property.ReadOnlyException();
- }
-
- // Adds new option
- if (addItem(newItemCaption) != null) {
-
- // Sets the caption property, if used
- if (getItemCaptionPropertyId() != null) {
- getContainerProperty(newItemCaption,
- getItemCaptionPropertyId())
- .setValue(newItemCaption);
- }
- if (isMultiSelect()) {
- Set values = new HashSet((Collection) getValue());
- values.add(newItemCaption);
- setValue(values);
- } else {
- setValue(newItemCaption);
- }
- }
- }
- }
-
- /**
- * Gets the visible item ids. In Select, this returns list of all item ids,
- * but can be overriden in subclasses if they paint only part of the items
- * to the terminal or null if no items is visible.
- */
- public Collection<?> getVisibleItemIds() {
- return getItemIds();
- }
-
- /* Property methods */
-
- /**
- * Returns the type of the property. <code>getValue</code> and
- * <code>setValue</code> methods must be compatible with this type: one can
- * safely cast <code>getValue</code> to given type and pass any variable
- * assignable to this type as a parameter to <code>setValue</code>.
- *
- * @return the Type of the property.
- */
- @Override
- public Class<?> getType() {
- if (isMultiSelect()) {
- return Set.class;
- } else {
- return Object.class;
- }
- }
-
- /**
- * Gets the selected item id or in multiselect mode a set of selected ids.
- *
- * @see com.vaadin.ui.AbstractField#getValue()
- */
- @Override
- public Object getValue() {
- final Object retValue = super.getValue();
-
- if (isMultiSelect()) {
-
- // If the return value is not a set
- if (retValue == null) {
- return new HashSet<Object>();
- }
- if (retValue instanceof Set) {
- return Collections.unmodifiableSet((Set<?>) retValue);
- } else if (retValue instanceof Collection) {
- return new HashSet<Object>((Collection<?>) retValue);
- } else {
- final Set<Object> s = new HashSet<Object>();
- if (items.containsId(retValue)) {
- s.add(retValue);
- }
- return s;
- }
-
- } else {
- return retValue;
- }
- }
-
- /**
- * Sets the visible value of the property.
- *
- * <p>
- * The value of the select is the selected item id. If the select is in
- * multiselect-mode, the value is a set of selected item keys. In
- * multiselect mode all collections of id:s can be assigned.
- * </p>
- *
- * @param newValue
- * the New selected item or collection of selected items.
- * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object)
- */
- @Override
- public void setValue(Object newValue) throws Property.ReadOnlyException {
- if (newValue == getNullSelectionItemId()) {
- newValue = null;
- }
-
- setValue(newValue, false);
- }
-
- /**
- * Sets the visible value of the property.
- *
- * <p>
- * The value of the select is the selected item id. If the select is in
- * multiselect-mode, the value is a set of selected item keys. In
- * multiselect mode all collections of id:s can be assigned.
- * </p>
- *
- * @param newValue
- * the New selected item or collection of selected items.
- * @param repaintIsNotNeeded
- * True if caller is sure that repaint is not needed.
- * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object,
- * java.lang.Boolean)
- */
- @Override
- protected void setValue(Object newValue, boolean repaintIsNotNeeded)
- throws Property.ReadOnlyException {
-
- if (isMultiSelect()) {
- if (newValue == null) {
- super.setValue(new LinkedHashSet<Object>(), repaintIsNotNeeded);
- } else if (Collection.class.isAssignableFrom(newValue.getClass())) {
- super.setValue(new LinkedHashSet<Object>(
- (Collection<?>) newValue), repaintIsNotNeeded);
- }
- } else if (newValue == null || items.containsId(newValue)) {
- super.setValue(newValue, repaintIsNotNeeded);
- }
- }
-
- /* Container methods */
-
- /**
- * Gets the item from the container with given id. If the container does not
- * contain the requested item, null is returned.
- *
- * @param itemId
- * the item id.
- * @return the item from the container.
- */
- @Override
- public Item getItem(Object itemId) {
- return items.getItem(itemId);
- }
-
- /**
- * Gets the item Id collection from the container.
- *
- * @return the Collection of item ids.
- */
- @Override
- public Collection<?> getItemIds() {
- return items.getItemIds();
- }
-
- /**
- * Gets the property Id collection from the container.
- *
- * @return the Collection of property ids.
- */
- @Override
- public Collection<?> getContainerPropertyIds() {
- return items.getContainerPropertyIds();
- }
-
- /**
- * Gets the property type.
- *
- * @param propertyId
- * the Id identifying the property.
- * @see com.vaadin.data.Container#getType(java.lang.Object)
- */
- @Override
- public Class<?> getType(Object propertyId) {
- return items.getType(propertyId);
- }
-
- /*
- * Gets the number of items in the container.
- *
- * @return the Number of items in the container.
- *
- * @see com.vaadin.data.Container#size()
- */
- @Override
- public int size() {
- return items.size();
- }
-
- /**
- * Tests, if the collection contains an item with given id.
- *
- * @param itemId
- * the Id the of item to be tested.
- */
- @Override
- public boolean containsId(Object itemId) {
- if (itemId != null) {
- return items.containsId(itemId);
- } else {
- return false;
- }
- }
-
- /**
- * Gets the Property identified by the given itemId and propertyId from the
- * Container
- *
- * @see com.vaadin.data.Container#getContainerProperty(Object, Object)
- */
- @Override
- public Property<?> getContainerProperty(Object itemId, Object propertyId) {
- return items.getContainerProperty(itemId, propertyId);
- }
-
- /**
- * Adds the new property to all items. Adds a property with given id, type
- * and default value to all items in the container.
- *
- * This functionality is optional. If the function is unsupported, it always
- * returns false.
- *
- * @return True if the operation succeeded.
- * @see com.vaadin.data.Container#addContainerProperty(java.lang.Object,
- * java.lang.Class, java.lang.Object)
- */
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
-
- final boolean retval = items.addContainerProperty(propertyId, type,
- defaultValue);
- if (retval && !(items instanceof Container.PropertySetChangeNotifier)) {
- firePropertySetChange();
- }
- return retval;
- }
-
- /**
- * Removes all items from the container.
- *
- * This functionality is optional. If the function is unsupported, it always
- * returns false.
- *
- * @return True if the operation succeeded.
- * @see com.vaadin.data.Container#removeAllItems()
- */
- @Override
- public boolean removeAllItems() throws UnsupportedOperationException {
-
- final boolean retval = items.removeAllItems();
- itemIdMapper.removeAll();
- if (retval) {
- setValue(null);
- if (!(items instanceof Container.ItemSetChangeNotifier)) {
- fireItemSetChange();
- }
- }
- return retval;
- }
-
- /**
- * Creates a new item into container with container managed id. The id of
- * the created new item is returned. The item can be fetched with getItem()
- * method. if the creation fails, null is returned.
- *
- * @return the Id of the created item or null in case of failure.
- * @see com.vaadin.data.Container#addItem()
- */
- @Override
- public Object addItem() throws UnsupportedOperationException {
-
- final Object retval = items.addItem();
- if (retval != null
- && !(items instanceof Container.ItemSetChangeNotifier)) {
- fireItemSetChange();
- }
- return retval;
- }
-
- /**
- * Create a new item into container. The created new item is returned and
- * ready for setting property values. if the creation fails, null is
- * returned. In case the container already contains the item, null is
- * returned.
- *
- * This functionality is optional. If the function is unsupported, it always
- * returns null.
- *
- * @param itemId
- * the Identification of the item to be created.
- * @return the Created item with the given id, or null in case of failure.
- * @see com.vaadin.data.Container#addItem(java.lang.Object)
- */
- @Override
- public Item addItem(Object itemId) throws UnsupportedOperationException {
-
- final Item retval = items.addItem(itemId);
- if (retval != null
- && !(items instanceof Container.ItemSetChangeNotifier)) {
- fireItemSetChange();
- }
- return retval;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container#removeItem(java.lang.Object)
- */
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
-
- unselect(itemId);
- final boolean retval = items.removeItem(itemId);
- itemIdMapper.remove(itemId);
- if (retval && !(items instanceof Container.ItemSetChangeNotifier)) {
- fireItemSetChange();
- }
- return retval;
- }
-
- /**
- * Removes the property from all items. Removes a property with given id
- * from all the items in the container.
- *
- * This functionality is optional. If the function is unsupported, it always
- * returns false.
- *
- * @return True if the operation succeeded.
- * @see com.vaadin.data.Container#removeContainerProperty(java.lang.Object)
- */
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
-
- final boolean retval = items.removeContainerProperty(propertyId);
- if (retval && !(items instanceof Container.PropertySetChangeNotifier)) {
- firePropertySetChange();
- }
- return retval;
- }
-
- /* Container.Viewer methods */
-
- /**
- * Sets the Container that serves as the data source of the viewer.
- *
- * As a side-effect the fields value (selection) is set to null due old
- * selection not necessary exists in new Container.
- *
- * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container)
- *
- * @param newDataSource
- * the new data source.
- */
- @Override
- public void setContainerDataSource(Container newDataSource) {
- if (newDataSource == null) {
- newDataSource = new IndexedContainer();
- }
-
- getCaptionChangeListener().clear();
-
- if (items != newDataSource) {
-
- // Removes listeners from the old datasource
- if (items != null) {
- if (items instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) items)
- .removeListener(this);
- }
- if (items instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) items)
- .removeListener(this);
- }
- }
-
- // Assigns new data source
- items = newDataSource;
-
- // Clears itemIdMapper also
- itemIdMapper.removeAll();
-
- // Adds listeners
- if (items != null) {
- if (items instanceof Container.ItemSetChangeNotifier) {
- ((Container.ItemSetChangeNotifier) items).addListener(this);
- }
- if (items instanceof Container.PropertySetChangeNotifier) {
- ((Container.PropertySetChangeNotifier) items)
- .addListener(this);
- }
- }
-
- /*
- * We expect changing the data source should also clean value. See
- * #810, #4607, #5281
- */
- setValue(null);
-
- requestRepaint();
-
- }
- }
-
- /**
- * Gets the viewing data-source container.
- *
- * @see com.vaadin.data.Container.Viewer#getContainerDataSource()
- */
- @Override
- public Container getContainerDataSource() {
- return items;
- }
-
- /* Select attributes */
-
- /**
- * Is the select in multiselect mode? In multiselect mode
- *
- * @return the Value of property multiSelect.
- */
- public boolean isMultiSelect() {
- return multiSelect;
- }
-
- /**
- * Sets the multiselect mode. Setting multiselect mode false may lose
- * selection information: if selected items set contains one or more
- * selected items, only one of the selected items is kept as selected.
- *
- * Subclasses of AbstractSelect can choose not to support changing the
- * multiselect mode, and may throw {@link UnsupportedOperationException}.
- *
- * @param multiSelect
- * the New value of property multiSelect.
- */
- public void setMultiSelect(boolean multiSelect) {
- if (multiSelect && getNullSelectionItemId() != null) {
- throw new IllegalStateException(
- "Multiselect and NullSelectionItemId can not be set at the same time.");
- }
- if (multiSelect != this.multiSelect) {
-
- // Selection before mode change
- final Object oldValue = getValue();
-
- this.multiSelect = multiSelect;
-
- // Convert the value type
- if (multiSelect) {
- final Set<Object> s = new HashSet<Object>();
- if (oldValue != null) {
- s.add(oldValue);
- }
- setValue(s);
- } else {
- final Set<?> s = (Set<?>) oldValue;
- if (s == null || s.isEmpty()) {
- setValue(null);
- } else {
- // Set the single select to contain only the first
- // selected value in the multiselect
- setValue(s.iterator().next());
- }
- }
-
- requestRepaint();
- }
- }
-
- /**
- * Does the select allow adding new options by the user. If true, the new
- * options can be added to the Container. The text entered by the user is
- * used as id. Note that data-source must allow adding new items.
- *
- * @return True if additions are allowed.
- */
- public boolean isNewItemsAllowed() {
-
- return allowNewOptions;
- }
-
- /**
- * Enables or disables possibility to add new options by the user.
- *
- * @param allowNewOptions
- * the New value of property allowNewOptions.
- */
- public void setNewItemsAllowed(boolean allowNewOptions) {
-
- // Only handle change requests
- if (this.allowNewOptions != allowNewOptions) {
-
- this.allowNewOptions = allowNewOptions;
-
- requestRepaint();
- }
- }
-
- /**
- * Override the caption of an item. Setting caption explicitly overrides id,
- * item and index captions.
- *
- * @param itemId
- * the id of the item to be recaptioned.
- * @param caption
- * the New caption.
- */
- public void setItemCaption(Object itemId, String caption) {
- if (itemId != null) {
- itemCaptions.put(itemId, caption);
- requestRepaint();
- }
- }
-
- /**
- * Gets the caption of an item. The caption is generated as specified by the
- * item caption mode. See <code>setItemCaptionMode()</code> for more
- * details.
- *
- * @param itemId
- * the id of the item to be queried.
- * @return the caption for specified item.
- */
- public String getItemCaption(Object itemId) {
-
- // Null items can not be found
- if (itemId == null) {
- return null;
- }
-
- String caption = null;
-
- switch (getItemCaptionMode()) {
-
- case ID:
- caption = itemId.toString();
- break;
-
- case INDEX:
- if (items instanceof Container.Indexed) {
- caption = String.valueOf(((Container.Indexed) items)
- .indexOfId(itemId));
- } else {
- caption = "ERROR: Container is not indexed";
- }
- break;
-
- case ITEM:
- final Item i = getItem(itemId);
- if (i != null) {
- caption = i.toString();
- }
- break;
-
- case EXPLICIT:
- caption = itemCaptions.get(itemId);
- break;
-
- case EXPLICIT_DEFAULTS_ID:
- caption = itemCaptions.get(itemId);
- if (caption == null) {
- caption = itemId.toString();
- }
- break;
-
- case PROPERTY:
- final Property<?> p = getContainerProperty(itemId,
- getItemCaptionPropertyId());
- if (p != null) {
- Object value = p.getValue();
- if (value != null) {
- caption = value.toString();
- }
- }
- break;
- }
-
- // All items must have some captions
- return caption != null ? caption : "";
- }
-
- /**
- * Sets tqhe icon for an item.
- *
- * @param itemId
- * the id of the item to be assigned an icon.
- * @param icon
- * the icon to use or null.
- */
- public void setItemIcon(Object itemId, Resource icon) {
- if (itemId != null) {
- if (icon == null) {
- itemIcons.remove(itemId);
- } else {
- itemIcons.put(itemId, icon);
- }
- requestRepaint();
- }
- }
-
- /**
- * Gets the item icon.
- *
- * @param itemId
- * the id of the item to be assigned an icon.
- * @return the icon for the item or null, if not specified.
- */
- public Resource getItemIcon(Object itemId) {
- final Resource explicit = itemIcons.get(itemId);
- if (explicit != null) {
- return explicit;
- }
-
- if (getItemIconPropertyId() == null) {
- return null;
- }
-
- final Property<?> ip = getContainerProperty(itemId,
- getItemIconPropertyId());
- if (ip == null) {
- return null;
- }
- final Object icon = ip.getValue();
- if (icon instanceof Resource) {
- return (Resource) icon;
- }
-
- return null;
- }
-
- /**
- * Sets the item caption mode.
- *
- * <p>
- * The mode can be one of the following ones:
- * <ul>
- * <li><code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> : Items
- * Id-objects <code>toString</code> is used as item caption. If caption is
- * explicitly specified, it overrides the id-caption.
- * <li><code>ITEM_CAPTION_MODE_ID</code> : Items Id-objects
- * <code>toString</code> is used as item caption.</li>
- * <li><code>ITEM_CAPTION_MODE_ITEM</code> : Item-objects
- * <code>toString</code> is used as item caption.</li>
- * <li><code>ITEM_CAPTION_MODE_INDEX</code> : The index of the item is used
- * as item caption. The index mode can only be used with the containers
- * implementing <code>Container.Indexed</code> interface.</li>
- * <li><code>ITEM_CAPTION_MODE_EXPLICIT</code> : The item captions must be
- * explicitly specified.</li>
- * <li><code>ITEM_CAPTION_MODE_PROPERTY</code> : The item captions are read
- * from property, that must be specified with
- * <code>setItemCaptionPropertyId</code>.</li>
- * </ul>
- * The <code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> is the default
- * mode.
- * </p>
- *
- * @param mode
- * the One of the modes listed above.
- */
- public void setItemCaptionMode(ItemCaptionMode mode) {
- if (mode != null) {
- itemCaptionMode = mode;
- requestRepaint();
- }
- }
-
- /**
- * Gets the item caption mode.
- *
- * <p>
- * The mode can be one of the following ones:
- * <ul>
- * <li><code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> : Items
- * Id-objects <code>toString</code> is used as item caption. If caption is
- * explicitly specified, it overrides the id-caption.
- * <li><code>ITEM_CAPTION_MODE_ID</code> : Items Id-objects
- * <code>toString</code> is used as item caption.</li>
- * <li><code>ITEM_CAPTION_MODE_ITEM</code> : Item-objects
- * <code>toString</code> is used as item caption.</li>
- * <li><code>ITEM_CAPTION_MODE_INDEX</code> : The index of the item is used
- * as item caption. The index mode can only be used with the containers
- * implementing <code>Container.Indexed</code> interface.</li>
- * <li><code>ITEM_CAPTION_MODE_EXPLICIT</code> : The item captions must be
- * explicitly specified.</li>
- * <li><code>ITEM_CAPTION_MODE_PROPERTY</code> : The item captions are read
- * from property, that must be specified with
- * <code>setItemCaptionPropertyId</code>.</li>
- * </ul>
- * The <code>ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID</code> is the default
- * mode.
- * </p>
- *
- * @return the One of the modes listed above.
- */
- public ItemCaptionMode getItemCaptionMode() {
- return itemCaptionMode;
- }
-
- /**
- * Sets the item caption property.
- *
- * <p>
- * Setting the id to a existing property implicitly sets the item caption
- * mode to <code>ITEM_CAPTION_MODE_PROPERTY</code>. If the object is in
- * <code>ITEM_CAPTION_MODE_PROPERTY</code> mode, setting caption property id
- * null resets the item caption mode to
- * <code>ITEM_CAPTION_EXPLICIT_DEFAULTS_ID</code>.
- * </p>
- * <p>
- * Note that the type of the property used for caption must be String
- * </p>
- * <p>
- * Setting the property id to null disables this feature. The id is null by
- * default
- * </p>
- * .
- *
- * @param propertyId
- * the id of the property.
- *
- */
- public void setItemCaptionPropertyId(Object propertyId) {
- if (propertyId != null) {
- itemCaptionPropertyId = propertyId;
- setItemCaptionMode(ITEM_CAPTION_MODE_PROPERTY);
- requestRepaint();
- } else {
- itemCaptionPropertyId = null;
- if (getItemCaptionMode() == ITEM_CAPTION_MODE_PROPERTY) {
- setItemCaptionMode(ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID);
- }
- requestRepaint();
- }
- }
-
- /**
- * Gets the item caption property.
- *
- * @return the Id of the property used as item caption source.
- */
- public Object getItemCaptionPropertyId() {
- return itemCaptionPropertyId;
- }
-
- /**
- * Sets the item icon property.
- *
- * <p>
- * If the property id is set to a valid value, each item is given an icon
- * got from the given property of the items. The type of the property must
- * be assignable to Resource.
- * </p>
- *
- * <p>
- * Note : The icons set with <code>setItemIcon</code> function override the
- * icons from the property.
- * </p>
- *
- * <p>
- * Setting the property id to null disables this feature. The id is null by
- * default
- * </p>
- * .
- *
- * @param propertyId
- * the id of the property that specifies icons for items or null
- * @throws IllegalArgumentException
- * If the propertyId is not in the container or is not of a
- * valid type
- */
- public void setItemIconPropertyId(Object propertyId)
- throws IllegalArgumentException {
- if (propertyId == null) {
- itemIconPropertyId = null;
- } else if (!getContainerPropertyIds().contains(propertyId)) {
- throw new IllegalArgumentException(
- "Property id not found in the container");
- } else if (Resource.class.isAssignableFrom(getType(propertyId))) {
- itemIconPropertyId = propertyId;
- } else {
- throw new IllegalArgumentException(
- "Property type must be assignable to Resource");
- }
- requestRepaint();
- }
-
- /**
- * Gets the item icon property.
- *
- * <p>
- * If the property id is set to a valid value, each item is given an icon
- * got from the given property of the items. The type of the property must
- * be assignable to Icon.
- * </p>
- *
- * <p>
- * Note : The icons set with <code>setItemIcon</code> function override the
- * icons from the property.
- * </p>
- *
- * <p>
- * Setting the property id to null disables this feature. The id is null by
- * default
- * </p>
- * .
- *
- * @return the Id of the property containing the item icons.
- */
- public Object getItemIconPropertyId() {
- return itemIconPropertyId;
- }
-
- /**
- * Tests if an item is selected.
- *
- * <p>
- * In single select mode testing selection status of the item identified by
- * {@link #getNullSelectionItemId()} returns true if the value of the
- * property is null.
- * </p>
- *
- * @param itemId
- * the Id the of the item to be tested.
- * @see #getNullSelectionItemId()
- * @see #setNullSelectionItemId(Object)
- *
- */
- public boolean isSelected(Object itemId) {
- if (itemId == null) {
- return false;
- }
- if (isMultiSelect()) {
- return ((Set<?>) getValue()).contains(itemId);
- } else {
- final Object value = getValue();
- return itemId.equals(value == null ? getNullSelectionItemId()
- : value);
- }
- }
-
- /**
- * Selects an item.
- *
- * <p>
- * In single select mode selecting item identified by
- * {@link #getNullSelectionItemId()} sets the value of the property to null.
- * </p>
- *
- * @param itemId
- * the identifier of Item to be selected.
- * @see #getNullSelectionItemId()
- * @see #setNullSelectionItemId(Object)
- *
- */
- public void select(Object itemId) {
- if (!isMultiSelect()) {
- setValue(itemId);
- } else if (!isSelected(itemId) && itemId != null
- && items.containsId(itemId)) {
- final Set<Object> s = new HashSet<Object>((Set<?>) getValue());
- s.add(itemId);
- setValue(s);
- }
- }
-
- /**
- * Unselects an item.
- *
- * @param itemId
- * the identifier of the Item to be unselected.
- * @see #getNullSelectionItemId()
- * @see #setNullSelectionItemId(Object)
- *
- */
- public void unselect(Object itemId) {
- if (isSelected(itemId)) {
- if (isMultiSelect()) {
- final Set<Object> s = new HashSet<Object>((Set<?>) getValue());
- s.remove(itemId);
- setValue(s);
- } else {
- setValue(null);
- }
- }
- }
-
- /**
- * Notifies this listener that the Containers contents has changed.
- *
- * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent)
- */
- @Override
- public void containerPropertySetChange(
- Container.PropertySetChangeEvent event) {
- firePropertySetChange();
- }
-
- /**
- * Adds a new Property set change listener for this Container.
- *
- * @see com.vaadin.data.Container.PropertySetChangeNotifier#addListener(com.vaadin.data.Container.PropertySetChangeListener)
- */
- @Override
- public void addListener(Container.PropertySetChangeListener listener) {
- if (propertySetEventListeners == null) {
- propertySetEventListeners = new LinkedHashSet<Container.PropertySetChangeListener>();
- }
- propertySetEventListeners.add(listener);
- }
-
- /**
- * Removes a previously registered Property set change listener.
- *
- * @see com.vaadin.data.Container.PropertySetChangeNotifier#removeListener(com.vaadin.data.Container.PropertySetChangeListener)
- */
- @Override
- public void removeListener(Container.PropertySetChangeListener listener) {
- if (propertySetEventListeners != null) {
- propertySetEventListeners.remove(listener);
- if (propertySetEventListeners.isEmpty()) {
- propertySetEventListeners = null;
- }
- }
- }
-
- /**
- * Adds an Item set change listener for the object.
- *
- * @see com.vaadin.data.Container.ItemSetChangeNotifier#addListener(com.vaadin.data.Container.ItemSetChangeListener)
- */
- @Override
- public void addListener(Container.ItemSetChangeListener listener) {
- if (itemSetEventListeners == null) {
- itemSetEventListeners = new LinkedHashSet<Container.ItemSetChangeListener>();
- }
- itemSetEventListeners.add(listener);
- }
-
- /**
- * Removes the Item set change listener from the object.
- *
- * @see com.vaadin.data.Container.ItemSetChangeNotifier#removeListener(com.vaadin.data.Container.ItemSetChangeListener)
- */
- @Override
- public void removeListener(Container.ItemSetChangeListener listener) {
- if (itemSetEventListeners != null) {
- itemSetEventListeners.remove(listener);
- if (itemSetEventListeners.isEmpty()) {
- itemSetEventListeners = null;
- }
- }
- }
-
- @Override
- public Collection<?> getListeners(Class<?> eventType) {
- if (Container.ItemSetChangeEvent.class.isAssignableFrom(eventType)) {
- if (itemSetEventListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(itemSetEventListeners);
- }
- } else if (Container.PropertySetChangeEvent.class
- .isAssignableFrom(eventType)) {
- if (propertySetEventListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections
- .unmodifiableCollection(propertySetEventListeners);
- }
- }
-
- return super.getListeners(eventType);
- }
-
- /**
- * Lets the listener know a Containers Item set has changed.
- *
- * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent)
- */
- @Override
- public void containerItemSetChange(Container.ItemSetChangeEvent event) {
- // Clears the item id mapping table
- itemIdMapper.removeAll();
-
- // Notify all listeners
- fireItemSetChange();
- }
-
- /**
- * Fires the property set change event.
- */
- protected void firePropertySetChange() {
- if (propertySetEventListeners != null
- && !propertySetEventListeners.isEmpty()) {
- final Container.PropertySetChangeEvent event = new PropertySetChangeEvent();
- final Object[] listeners = propertySetEventListeners.toArray();
- for (int i = 0; i < listeners.length; i++) {
- ((Container.PropertySetChangeListener) listeners[i])
- .containerPropertySetChange(event);
- }
- }
- requestRepaint();
- }
-
- /**
- * Fires the item set change event.
- */
- protected void fireItemSetChange() {
- if (itemSetEventListeners != null && !itemSetEventListeners.isEmpty()) {
- final Container.ItemSetChangeEvent event = new ItemSetChangeEvent();
- final Object[] listeners = itemSetEventListeners.toArray();
- for (int i = 0; i < listeners.length; i++) {
- ((Container.ItemSetChangeListener) listeners[i])
- .containerItemSetChange(event);
- }
- }
- requestRepaint();
- }
-
- /**
- * Implementation of item set change event.
- */
- private class ItemSetChangeEvent implements Serializable,
- Container.ItemSetChangeEvent {
-
- /**
- * Gets the Property where the event occurred.
- *
- * @see com.vaadin.data.Container.ItemSetChangeEvent#getContainer()
- */
- @Override
- public Container getContainer() {
- return AbstractSelect.this;
- }
-
- }
-
- /**
- * Implementation of property set change event.
- */
- private class PropertySetChangeEvent implements
- Container.PropertySetChangeEvent, Serializable {
-
- /**
- * Retrieves the Container whose contents have been modified.
- *
- * @see com.vaadin.data.Container.PropertySetChangeEvent#getContainer()
- */
- @Override
- public Container getContainer() {
- return AbstractSelect.this;
- }
-
- }
-
- /**
- * For multi-selectable fields, also an empty collection of values is
- * considered to be an empty field.
- *
- * @see AbstractField#isEmpty().
- */
- @Override
- protected boolean isEmpty() {
- if (!multiSelect) {
- return super.isEmpty();
- } else {
- Object value = getValue();
- return super.isEmpty()
- || (value instanceof Collection && ((Collection<?>) value)
- .isEmpty());
- }
- }
-
- /**
- * Allow or disallow empty selection by the user. If the select is in
- * single-select mode, you can make an item represent the empty selection by
- * calling <code>setNullSelectionItemId()</code>. This way you can for
- * instance set an icon and caption for the null selection item.
- *
- * @param nullSelectionAllowed
- * whether or not to allow empty selection
- * @see #setNullSelectionItemId(Object)
- * @see #isNullSelectionAllowed()
- */
- public void setNullSelectionAllowed(boolean nullSelectionAllowed) {
- if (nullSelectionAllowed != this.nullSelectionAllowed) {
- this.nullSelectionAllowed = nullSelectionAllowed;
- requestRepaint();
- }
- }
-
- /**
- * Checks if null empty selection is allowed by the user.
- *
- * @return whether or not empty selection is allowed
- * @see #setNullSelectionAllowed(boolean)
- */
- public boolean isNullSelectionAllowed() {
- return nullSelectionAllowed;
- }
-
- /**
- * Returns the item id that represents null value of this select in single
- * select mode.
- *
- * <p>
- * Data interface does not support nulls as item ids. Selecting the item
- * identified by this id is the same as selecting no items at all. This
- * setting only affects the single select mode.
- * </p>
- *
- * @return the Object Null value item id.
- * @see #setNullSelectionItemId(Object)
- * @see #isSelected(Object)
- * @see #select(Object)
- */
- public Object getNullSelectionItemId() {
- return nullSelectionItemId;
- }
-
- /**
- * Sets the item id that represents null value of this select.
- *
- * <p>
- * Data interface does not support nulls as item ids. Selecting the item
- * identified by this id is the same as selecting no items at all. This
- * setting only affects the single select mode.
- * </p>
- *
- * @param nullSelectionItemId
- * the nullSelectionItemId to set.
- * @see #getNullSelectionItemId()
- * @see #isSelected(Object)
- * @see #select(Object)
- */
- public void setNullSelectionItemId(Object nullSelectionItemId) {
- if (nullSelectionItemId != null && isMultiSelect()) {
- throw new IllegalStateException(
- "Multiselect and NullSelectionItemId can not be set at the same time.");
- }
- this.nullSelectionItemId = nullSelectionItemId;
- }
-
- /**
- * Notifies the component that it is connected to an application.
- *
- * @see com.vaadin.ui.AbstractField#attach()
- */
- @Override
- public void attach() {
- super.attach();
- }
-
- /**
- * Detaches the component from application.
- *
- * @see com.vaadin.ui.AbstractComponent#detach()
- */
- @Override
- public void detach() {
- getCaptionChangeListener().clear();
- super.detach();
- }
-
- // Caption change listener
- protected CaptionChangeListener getCaptionChangeListener() {
- if (captionChangeListener == null) {
- captionChangeListener = new CaptionChangeListener();
- }
- return captionChangeListener;
- }
-
- /**
- * This is a listener helper for Item and Property changes that should cause
- * a repaint. It should be attached to all items that are displayed, and the
- * default implementation does this in paintContent(). Especially
- * "lazyloading" components should take care to add and remove listeners as
- * appropriate. Call addNotifierForItem() for each painted item (and
- * remember to clear).
- *
- * NOTE: singleton, use getCaptionChangeListener().
- *
- */
- protected class CaptionChangeListener implements
- Item.PropertySetChangeListener, Property.ValueChangeListener {
-
- // TODO clean this up - type is either Item.PropertySetChangeNotifier or
- // Property.ValueChangeNotifier
- HashSet<Object> captionChangeNotifiers = new HashSet<Object>();
-
- public void addNotifierForItem(Object itemId) {
- switch (getItemCaptionMode()) {
- case ITEM:
- final Item i = getItem(itemId);
- if (i == null) {
- return;
- }
- if (i instanceof Item.PropertySetChangeNotifier) {
- ((Item.PropertySetChangeNotifier) i)
- .addListener(getCaptionChangeListener());
- captionChangeNotifiers.add(i);
- }
- Collection<?> pids = i.getItemPropertyIds();
- if (pids != null) {
- for (Iterator<?> it = pids.iterator(); it.hasNext();) {
- Property<?> p = i.getItemProperty(it.next());
- if (p != null
- && p instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) p)
- .addListener(getCaptionChangeListener());
- captionChangeNotifiers.add(p);
- }
- }
-
- }
- break;
- case PROPERTY:
- final Property<?> p = getContainerProperty(itemId,
- getItemCaptionPropertyId());
- if (p != null && p instanceof Property.ValueChangeNotifier) {
- ((Property.ValueChangeNotifier) p)
- .addListener(getCaptionChangeListener());
- captionChangeNotifiers.add(p);
- }
- break;
-
- }
- }
-
- public void clear() {
- for (Iterator<Object> it = captionChangeNotifiers.iterator(); it
- .hasNext();) {
- Object notifier = it.next();
- if (notifier instanceof Item.PropertySetChangeNotifier) {
- ((Item.PropertySetChangeNotifier) notifier)
- .removeListener(getCaptionChangeListener());
- } else {
- ((Property.ValueChangeNotifier) notifier)
- .removeListener(getCaptionChangeListener());
- }
- }
- captionChangeNotifiers.clear();
- }
-
- @Override
- public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
- requestRepaint();
- }
-
- @Override
- public void itemPropertySetChange(
- com.vaadin.data.Item.PropertySetChangeEvent event) {
- requestRepaint();
- }
-
- }
-
- /**
- * Criterion which accepts a drop only if the drop target is (one of) the
- * given Item identifier(s). Criterion can be used only on a drop targets
- * that extends AbstractSelect like {@link Table} and {@link Tree}. The
- * target and identifiers of valid Items are given in constructor.
- *
- * @since 6.3
- */
- public static class TargetItemIs extends AbstractItemSetCriterion {
-
- /**
- * @param select
- * the select implementation that is used as a drop target
- * @param itemId
- * the identifier(s) that are valid drop locations
- */
- public TargetItemIs(AbstractSelect select, Object... itemId) {
- super(select, itemId);
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent
- .getTargetDetails();
- if (dropTargetData.getTarget() != select) {
- return false;
- }
- return itemIds.contains(dropTargetData.getItemIdOver());
- }
-
- }
-
- /**
- * Abstract helper class to implement item id based criterion.
- *
- * Note, inner class used not to open itemIdMapper for public access.
- *
- * @since 6.3
- *
- */
- private static abstract class AbstractItemSetCriterion extends
- ClientSideCriterion {
- protected final Collection<Object> itemIds = new HashSet<Object>();
- protected AbstractSelect select;
-
- public AbstractItemSetCriterion(AbstractSelect select, Object... itemId) {
- if (itemIds == null || select == null) {
- throw new IllegalArgumentException(
- "Accepted item identifiers must be accepted.");
- }
- Collections.addAll(itemIds, itemId);
- this.select = select;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- String[] keys = new String[itemIds.size()];
- int i = 0;
- for (Object itemId : itemIds) {
- String key = select.itemIdMapper.key(itemId);
- keys[i++] = key;
- }
- target.addAttribute("keys", keys);
- target.addAttribute("s", select);
- }
-
- }
-
- /**
- * This criterion accepts a only a {@link Transferable} that contains given
- * Item (practically its identifier) from a specific AbstractSelect.
- *
- * @since 6.3
- */
- public static class AcceptItem extends AbstractItemSetCriterion {
-
- /**
- * @param select
- * the select from which the item id's are checked
- * @param itemId
- * the item identifier(s) of the select that are accepted
- */
- public AcceptItem(AbstractSelect select, Object... itemId) {
- super(select, itemId);
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- DataBoundTransferable transferable = (DataBoundTransferable) dragEvent
- .getTransferable();
- if (transferable.getSourceComponent() != select) {
- return false;
- }
- return itemIds.contains(transferable.getItemId());
- }
-
- /**
- * A simple accept criterion which ensures that {@link Transferable}
- * contains an {@link Item} (or actually its identifier). In other words
- * the criterion check that drag is coming from a {@link Container} like
- * {@link Tree} or {@link Table}.
- */
- public static final ClientSideCriterion ALL = new ContainsDataFlavor(
- "itemId");
-
- }
-
- /**
- * TargetDetails implementation for subclasses of {@link AbstractSelect}
- * that implement {@link DropTarget}.
- *
- * @since 6.3
- */
- public class AbstractSelectTargetDetails extends TargetDetailsImpl {
-
- /**
- * The item id over which the drag event happened.
- */
- protected Object idOver;
-
- /**
- * Constructor that automatically converts itemIdOver key to
- * corresponding item Id
- *
- */
- protected AbstractSelectTargetDetails(Map<String, Object> rawVariables) {
- super(rawVariables, (DropTarget) AbstractSelect.this);
- // eagar fetch itemid, mapper may be emptied
- String keyover = (String) getData("itemIdOver");
- if (keyover != null) {
- idOver = itemIdMapper.get(keyover);
- }
- }
-
- /**
- * If the drag operation is currently over an {@link Item}, this method
- * returns the identifier of that {@link Item}.
- *
- */
- public Object getItemIdOver() {
- return idOver;
- }
-
- /**
- * Returns a detailed vertical location where the drop happened on Item.
- */
- public VerticalDropLocation getDropLocation() {
- String detail = (String) getData("detail");
- if (detail == null) {
- return null;
- }
- return VerticalDropLocation.valueOf(detail);
- }
-
- }
-
- /**
- * An accept criterion to accept drops only on a specific vertical location
- * of an item.
- * <p>
- * This accept criterion is currently usable in Tree and Table
- * implementations.
- */
- public static class VerticalLocationIs extends TargetDetailIs {
- public static VerticalLocationIs TOP = new VerticalLocationIs(
- VerticalDropLocation.TOP);
- public static VerticalLocationIs BOTTOM = new VerticalLocationIs(
- VerticalDropLocation.BOTTOM);
- public static VerticalLocationIs MIDDLE = new VerticalLocationIs(
- VerticalDropLocation.MIDDLE);
-
- private VerticalLocationIs(VerticalDropLocation l) {
- super("detail", l.name());
- }
- }
-
- /**
- * Implement this interface and pass it to Tree.setItemDescriptionGenerator
- * or Table.setItemDescriptionGenerator to generate mouse over descriptions
- * ("tooltips") for the rows and cells in Table or for the items in Tree.
- */
- public interface ItemDescriptionGenerator extends Serializable {
-
- /**
- * Called by Table when a cell (and row) is painted or a item is painted
- * in Tree
- *
- * @param source
- * The source of the generator, the Tree or Table the
- * generator is attached to
- * @param itemId
- * The itemId of the painted cell
- * @param propertyId
- * The propertyId of the cell, null when getting row
- * description
- * @return The description or "tooltip" of the item.
- */
- public String generateDescription(Component source, Object itemId,
- Object propertyId);
- }
-}
diff --git a/src/com/vaadin/ui/AbstractSplitPanel.java b/src/com/vaadin/ui/AbstractSplitPanel.java
deleted file mode 100644
index 90dc38ff65..0000000000
--- a/src/com/vaadin/ui/AbstractSplitPanel.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Iterator;
-
-import com.vaadin.event.ComponentEventListener;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelRpc;
-import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState;
-import com.vaadin.shared.ui.splitpanel.AbstractSplitPanelState.SplitterState;
-import com.vaadin.terminal.Sizeable;
-import com.vaadin.terminal.gwt.client.ui.ClickEventHandler;
-import com.vaadin.tools.ReflectTools;
-
-/**
- * AbstractSplitPanel.
- *
- * <code>AbstractSplitPanel</code> is base class for a component container that
- * can contain two components. The components are split by a divider element.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.5
- */
-public abstract class AbstractSplitPanel extends AbstractComponentContainer {
-
- // TODO use Unit in AbstractSplitPanelState and remove these
- private Unit posUnit;
- private Unit posMinUnit;
- private Unit posMaxUnit;
-
- private AbstractSplitPanelRpc rpc = new AbstractSplitPanelRpc() {
-
- @Override
- public void splitterClick(MouseEventDetails mouseDetails) {
- fireEvent(new SplitterClickEvent(AbstractSplitPanel.this,
- mouseDetails));
- }
-
- @Override
- public void setSplitterPosition(float position) {
- getSplitterState().setPosition(position);
- }
- };
-
- public AbstractSplitPanel() {
- registerRpc(rpc);
- setSplitPosition(50, Unit.PERCENTAGE, false);
- setSplitPositionLimits(0, Unit.PERCENTAGE, 100, Unit.PERCENTAGE);
- }
-
- /**
- * Modifiable and Serializable Iterator for the components, used by
- * {@link AbstractSplitPanel#getComponentIterator()}.
- */
- private class ComponentIterator implements Iterator<Component>,
- Serializable {
-
- int i = 0;
-
- @Override
- public boolean hasNext() {
- if (i < getComponentCount()) {
- return true;
- }
- return false;
- }
-
- @Override
- public Component next() {
- if (!hasNext()) {
- return null;
- }
- i++;
- if (i == 1) {
- return (getFirstComponent() == null ? getSecondComponent()
- : getFirstComponent());
- } else if (i == 2) {
- return getSecondComponent();
- }
- return null;
- }
-
- @Override
- public void remove() {
- if (i == 1) {
- if (getFirstComponent() != null) {
- setFirstComponent(null);
- i = 0;
- } else {
- setSecondComponent(null);
- }
- } else if (i == 2) {
- setSecondComponent(null);
- }
- }
- }
-
- /**
- * Add a component into this container. The component is added to the right
- * or under the previous component.
- *
- * @param c
- * the component to be added.
- */
-
- @Override
- public void addComponent(Component c) {
- if (getFirstComponent() == null) {
- setFirstComponent(c);
- } else if (getSecondComponent() == null) {
- setSecondComponent(c);
- } else {
- throw new UnsupportedOperationException(
- "Split panel can contain only two components");
- }
- }
-
- /**
- * Sets the first component of this split panel. Depending on the direction
- * the first component is shown at the top or to the left.
- *
- * @param c
- * The component to use as first component
- */
- public void setFirstComponent(Component c) {
- if (getFirstComponent() == c) {
- // Nothing to do
- return;
- }
-
- if (getFirstComponent() != null) {
- // detach old
- removeComponent(getFirstComponent());
- }
- getState().setFirstChild(c);
- if (c != null) {
- super.addComponent(c);
- }
-
- requestRepaint();
- }
-
- /**
- * Sets the second component of this split panel. Depending on the direction
- * the second component is shown at the bottom or to the left.
- *
- * @param c
- * The component to use as first component
- */
- public void setSecondComponent(Component c) {
- if (getSecondComponent() == c) {
- // Nothing to do
- return;
- }
-
- if (getSecondComponent() != null) {
- // detach old
- removeComponent(getSecondComponent());
- }
- getState().setSecondChild(c);
- if (c != null) {
- super.addComponent(c);
- }
- requestRepaint();
- }
-
- /**
- * Gets the first component of this split panel. Depending on the direction
- * this is either the component shown at the top or to the left.
- *
- * @return the first component of this split panel
- */
- public Component getFirstComponent() {
- return (Component) getState().getFirstChild();
- }
-
- /**
- * Gets the second component of this split panel. Depending on the direction
- * this is either the component shown at the top or to the left.
- *
- * @return the second component of this split panel
- */
- public Component getSecondComponent() {
- return (Component) getState().getSecondChild();
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
-
- @Override
- public void removeComponent(Component c) {
- super.removeComponent(c);
- if (c == getFirstComponent()) {
- getState().setFirstChild(null);
- } else if (c == getSecondComponent()) {
- getState().setSecondChild(null);
- }
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
-
- @Override
- public Iterator<Component> getComponentIterator() {
- return new ComponentIterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components (zero, one or two)
- */
-
- @Override
- public int getComponentCount() {
- int count = 0;
- if (getFirstComponent() != null) {
- count++;
- }
- if (getSecondComponent() != null) {
- count++;
- }
- return count;
- }
-
- /* Documented in superclass */
-
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- if (oldComponent == getFirstComponent()) {
- setFirstComponent(newComponent);
- } else if (oldComponent == getSecondComponent()) {
- setSecondComponent(newComponent);
- }
- requestRepaint();
- }
-
- /**
- * Moves the position of the splitter.
- *
- * @param pos
- * the new size of the first region in the unit that was last
- * used (default is percentage). Fractions are only allowed when
- * unit is percentage.
- */
- public void setSplitPosition(float pos) {
- setSplitPosition(pos, posUnit, false);
- }
-
- /**
- * Moves the position of the splitter.
- *
- * @param pos
- * the new size of the region in the unit that was last used
- * (default is percentage). Fractions are only allowed when unit
- * is percentage.
- *
- * @param reverse
- * if set to true the split splitter position is measured by the
- * second region else it is measured by the first region
- */
- public void setSplitPosition(float pos, boolean reverse) {
- setSplitPosition(pos, posUnit, reverse);
- }
-
- /**
- * Moves the position of the splitter with given position and unit.
- *
- * @param pos
- * the new size of the first region. Fractions are only allowed
- * when unit is percentage.
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- */
- public void setSplitPosition(float pos, Unit unit) {
- setSplitPosition(pos, unit, false);
- }
-
- /**
- * Moves the position of the splitter with given position and unit.
- *
- * @param pos
- * the new size of the first region. Fractions are only allowed
- * when unit is percentage.
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * @param reverse
- * if set to true the split splitter position is measured by the
- * second region else it is measured by the first region
- *
- */
- public void setSplitPosition(float pos, Unit unit, boolean reverse) {
- if (unit != Unit.PERCENTAGE && unit != Unit.PIXELS) {
- throw new IllegalArgumentException(
- "Only percentage and pixel units are allowed");
- }
- if (unit != Unit.PERCENTAGE) {
- pos = Math.round(pos);
- }
- SplitterState splitterState = getSplitterState();
- splitterState.setPosition(pos);
- splitterState.setPositionUnit(unit.getSymbol());
- splitterState.setPositionReversed(reverse);
- posUnit = unit;
-
- requestRepaint();
- }
-
- /**
- * Returns the current position of the splitter, in
- * {@link #getSplitPositionUnit()} units.
- *
- * @return position of the splitter
- */
- public float getSplitPosition() {
- return getSplitterState().getPosition();
- }
-
- /**
- * Returns the unit of position of the splitter
- *
- * @return unit of position of the splitter
- */
- public Unit getSplitPositionUnit() {
- return posUnit;
- }
-
- /**
- * Sets the minimum split position to the given position and unit. If the
- * split position is reversed, maximum and minimum are also reversed.
- *
- * @param pos
- * the minimum position of the split
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS
- */
- public void setMinSplitPosition(int pos, Unit unit) {
- setSplitPositionLimits(pos, unit, getSplitterState().getMaxPosition(),
- posMaxUnit);
- }
-
- /**
- * Returns the current minimum position of the splitter, in
- * {@link #getMinSplitPositionUnit()} units.
- *
- * @return the minimum position of the splitter
- */
- public float getMinSplitPosition() {
- return getSplitterState().getMinPosition();
- }
-
- /**
- * Returns the unit of the minimum position of the splitter.
- *
- * @return the unit of the minimum position of the splitter
- */
- public Unit getMinSplitPositionUnit() {
- return posMinUnit;
- }
-
- /**
- * Sets the maximum split position to the given position and unit. If the
- * split position is reversed, maximum and minimum are also reversed.
- *
- * @param pos
- * the maximum position of the split
- * @param unit
- * the unit (from {@link Sizeable}) in which the size is given.
- * Allowed units are UNITS_PERCENTAGE and UNITS_PIXELS
- */
- public void setMaxSplitPosition(float pos, Unit unit) {
- setSplitPositionLimits(getSplitterState().getMinPosition(), posMinUnit,
- pos, unit);
- }
-
- /**
- * Returns the current maximum position of the splitter, in
- * {@link #getMaxSplitPositionUnit()} units.
- *
- * @return the maximum position of the splitter
- */
- public float getMaxSplitPosition() {
- return getSplitterState().getMaxPosition();
- }
-
- /**
- * Returns the unit of the maximum position of the splitter
- *
- * @return the unit of the maximum position of the splitter
- */
- public Unit getMaxSplitPositionUnit() {
- return posMaxUnit;
- }
-
- /**
- * Sets the maximum and minimum position of the splitter. If the split
- * position is reversed, maximum and minimum are also reversed.
- *
- * @param minPos
- * the new minimum position
- * @param minPosUnit
- * the unit (from {@link Sizeable}) in which the minimum position
- * is given.
- * @param maxPos
- * the new maximum position
- * @param maxPosUnit
- * the unit (from {@link Sizeable}) in which the maximum position
- * is given.
- */
- private void setSplitPositionLimits(float minPos, Unit minPosUnit,
- float maxPos, Unit maxPosUnit) {
- if ((minPosUnit != Unit.PERCENTAGE && minPosUnit != Unit.PIXELS)
- || (maxPosUnit != Unit.PERCENTAGE && maxPosUnit != Unit.PIXELS)) {
- throw new IllegalArgumentException(
- "Only percentage and pixel units are allowed");
- }
-
- SplitterState state = getSplitterState();
-
- state.setMinPosition(minPos);
- state.setMinPositionUnit(minPosUnit.getSymbol());
- posMinUnit = minPosUnit;
-
- state.setMaxPosition(maxPos);
- state.setMaxPositionUnit(maxPosUnit.getSymbol());
- posMaxUnit = maxPosUnit;
-
- requestRepaint();
- }
-
- /**
- * Lock the SplitPanels position, disabling the user from dragging the split
- * handle.
- *
- * @param locked
- * Set <code>true</code> if locked, <code>false</code> otherwise.
- */
- public void setLocked(boolean locked) {
- getSplitterState().setLocked(locked);
- requestRepaint();
- }
-
- /**
- * Is the SplitPanel handle locked (user not allowed to change split
- * position by dragging).
- *
- * @return <code>true</code> if locked, <code>false</code> otherwise.
- */
- public boolean isLocked() {
- return getSplitterState().isLocked();
- }
-
- /**
- * <code>SplitterClickListener</code> interface for listening for
- * <code>SplitterClickEvent</code> fired by a <code>SplitPanel</code>.
- *
- * @see SplitterClickEvent
- * @since 6.2
- */
- public interface SplitterClickListener extends ComponentEventListener {
-
- public static final Method clickMethod = ReflectTools.findMethod(
- SplitterClickListener.class, "splitterClick",
- SplitterClickEvent.class);
-
- /**
- * SplitPanel splitter has been clicked
- *
- * @param event
- * SplitterClickEvent event.
- */
- public void splitterClick(SplitterClickEvent event);
- }
-
- public class SplitterClickEvent extends ClickEvent {
-
- public SplitterClickEvent(Component source,
- MouseEventDetails mouseEventDetails) {
- super(source, mouseEventDetails);
- }
-
- }
-
- public void addListener(SplitterClickListener listener) {
- addListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER,
- SplitterClickEvent.class, listener,
- SplitterClickListener.clickMethod);
- }
-
- public void removeListener(SplitterClickListener listener) {
- removeListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER,
- SplitterClickEvent.class, listener);
- }
-
- @Override
- public AbstractSplitPanelState getState() {
- return (AbstractSplitPanelState) super.getState();
- }
-
- private SplitterState getSplitterState() {
- return getState().getSplitterState();
- }
-}
diff --git a/src/com/vaadin/ui/AbstractTextField.java b/src/com/vaadin/ui/AbstractTextField.java
deleted file mode 100644
index 2326c07d97..0000000000
--- a/src/com/vaadin/ui/AbstractTextField.java
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Map;
-
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.BlurNotifier;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.event.FieldEvents.FocusNotifier;
-import com.vaadin.event.FieldEvents.TextChangeEvent;
-import com.vaadin.event.FieldEvents.TextChangeListener;
-import com.vaadin.event.FieldEvents.TextChangeNotifier;
-import com.vaadin.shared.ui.textfield.AbstractTextFieldState;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.textfield.VTextField;
-
-public abstract class AbstractTextField extends AbstractField<String> implements
- BlurNotifier, FocusNotifier, TextChangeNotifier, Vaadin6Component {
-
- /**
- * Null representation.
- */
- private String nullRepresentation = "null";
- /**
- * Is setting to null from non-null value allowed by setting with null
- * representation .
- */
- private boolean nullSettingAllowed = false;
- /**
- * The text content when the last messages to the server was sent. Cleared
- * when value is changed.
- */
- private String lastKnownTextContent;
-
- /**
- * The position of the cursor when the last message to the server was sent.
- */
- private int lastKnownCursorPosition;
-
- /**
- * Flag indicating that a text change event is pending to be triggered.
- * Cleared by {@link #setInternalValue(Object)} and when the event is fired.
- */
- private boolean textChangeEventPending;
-
- private boolean isFiringTextChangeEvent = false;
-
- private TextChangeEventMode textChangeEventMode = TextChangeEventMode.LAZY;
-
- private final int DEFAULT_TEXTCHANGE_TIMEOUT = 400;
-
- private int textChangeEventTimeout = DEFAULT_TEXTCHANGE_TIMEOUT;
-
- /**
- * Temporarily holds the new selection position. Cleared on paint.
- */
- private int selectionPosition = -1;
-
- /**
- * Temporarily holds the new selection length.
- */
- private int selectionLength;
-
- /**
- * Flag used to determine whether we are currently handling a state change
- * triggered by a user. Used to properly fire text change event before value
- * change event triggered by the client side.
- */
- private boolean changingVariables;
-
- protected AbstractTextField() {
- super();
- }
-
- @Override
- public AbstractTextFieldState getState() {
- return (AbstractTextFieldState) super.getState();
- }
-
- @Override
- public void updateState() {
- super.updateState();
-
- String value = getValue();
- if (value == null) {
- value = getNullRepresentation();
- }
- getState().setText(value);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- if (selectionPosition != -1) {
- target.addAttribute("selpos", selectionPosition);
- target.addAttribute("sellen", selectionLength);
- selectionPosition = -1;
- }
-
- if (hasListeners(TextChangeEvent.class)) {
- target.addAttribute(VTextField.ATTR_TEXTCHANGE_EVENTMODE,
- getTextChangeEventMode().toString());
- target.addAttribute(VTextField.ATTR_TEXTCHANGE_TIMEOUT,
- getTextChangeTimeout());
- if (lastKnownTextContent != null) {
- /*
- * The field has be repainted for some reason (e.g. caption,
- * size, stylename), but the value has not been changed since
- * the last text change event. Let the client side know about
- * the value the server side knows. Client side may then ignore
- * the actual value, depending on its state.
- */
- target.addAttribute(
- VTextField.ATTR_NO_VALUE_CHANGE_BETWEEN_PAINTS, true);
- }
- }
-
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- changingVariables = true;
-
- try {
-
- if (variables.containsKey(VTextField.VAR_CURSOR)) {
- Integer object = (Integer) variables.get(VTextField.VAR_CURSOR);
- lastKnownCursorPosition = object.intValue();
- }
-
- if (variables.containsKey(VTextField.VAR_CUR_TEXT)) {
- /*
- * NOTE, we might want to develop this further so that on a
- * value change event the whole text content don't need to be
- * sent from the client to server. Just "commit" the value from
- * currentText to the value.
- */
- handleInputEventTextChange(variables);
- }
-
- // Sets the text
- if (variables.containsKey("text") && !isReadOnly()) {
-
- // Only do the setting if the string representation of the value
- // has been updated
- String newValue = (String) variables.get("text");
-
- // server side check for max length
- if (getMaxLength() != -1 && newValue.length() > getMaxLength()) {
- newValue = newValue.substring(0, getMaxLength());
- }
- final String oldValue = getValue();
- if (newValue != null
- && (oldValue == null || isNullSettingAllowed())
- && newValue.equals(getNullRepresentation())) {
- newValue = null;
- }
- if (newValue != oldValue
- && (newValue == null || !newValue.equals(oldValue))) {
- boolean wasModified = isModified();
- setValue(newValue, true);
-
- // If the modified status changes, or if we have a
- // formatter, repaint is needed after all.
- if (wasModified != isModified()) {
- requestRepaint();
- }
- }
- }
- firePendingTextChangeEvent();
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
- } finally {
- changingVariables = false;
-
- }
-
- }
-
- @Override
- public Class<String> getType() {
- return String.class;
- }
-
- /**
- * Gets the null-string representation.
- *
- * <p>
- * The null-valued strings are represented on the user interface by
- * replacing the null value with this string. If the null representation is
- * set null (not 'null' string), painting null value throws exception.
- * </p>
- *
- * <p>
- * The default value is string 'null'.
- * </p>
- *
- * @return the String Textual representation for null strings.
- * @see TextField#isNullSettingAllowed()
- */
- public String getNullRepresentation() {
- return nullRepresentation;
- }
-
- /**
- * Is setting nulls with null-string representation allowed.
- *
- * <p>
- * If this property is true, writing null-representation string to text
- * field always sets the field value to real null. If this property is
- * false, null setting is not made, but the null values are maintained.
- * Maintenance of null-values is made by only converting the textfield
- * contents to real null, if the text field matches the null-string
- * representation and the current value of the field is null.
- * </p>
- *
- * <p>
- * By default this setting is false
- * </p>
- *
- * @return boolean Should the null-string represenation be always converted
- * to null-values.
- * @see TextField#getNullRepresentation()
- */
- public boolean isNullSettingAllowed() {
- return nullSettingAllowed;
- }
-
- /**
- * Sets the null-string representation.
- *
- * <p>
- * The null-valued strings are represented on the user interface by
- * replacing the null value with this string. If the null representation is
- * set null (not 'null' string), painting null value throws exception.
- * </p>
- *
- * <p>
- * The default value is string 'null'
- * </p>
- *
- * @param nullRepresentation
- * Textual representation for null strings.
- * @see TextField#setNullSettingAllowed(boolean)
- */
- public void setNullRepresentation(String nullRepresentation) {
- this.nullRepresentation = nullRepresentation;
- requestRepaint();
- }
-
- /**
- * Sets the null conversion mode.
- *
- * <p>
- * If this property is true, writing null-representation string to text
- * field always sets the field value to real null. If this property is
- * false, null setting is not made, but the null values are maintained.
- * Maintenance of null-values is made by only converting the textfield
- * contents to real null, if the text field matches the null-string
- * representation and the current value of the field is null.
- * </p>
- *
- * <p>
- * By default this setting is false.
- * </p>
- *
- * @param nullSettingAllowed
- * Should the null-string representation always be converted to
- * null-values.
- * @see TextField#getNullRepresentation()
- */
- public void setNullSettingAllowed(boolean nullSettingAllowed) {
- this.nullSettingAllowed = nullSettingAllowed;
- requestRepaint();
- }
-
- @Override
- protected boolean isEmpty() {
- return super.isEmpty() || getValue().length() == 0;
- }
-
- /**
- * Returns the maximum number of characters in the field. Value -1 is
- * considered unlimited. Terminal may however have some technical limits.
- *
- * @return the maxLength
- */
- public int getMaxLength() {
- return getState().getMaxLength();
- }
-
- /**
- * Sets the maximum number of characters in the field. Value -1 is
- * considered unlimited. Terminal may however have some technical limits.
- *
- * @param maxLength
- * the maxLength to set
- */
- public void setMaxLength(int maxLength) {
- getState().setMaxLength(maxLength);
- requestRepaint();
- }
-
- /**
- * Gets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- *
- * @return the number of columns in the editor.
- */
- public int getColumns() {
- return getState().getColumns();
- }
-
- /**
- * Sets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- *
- * @param columns
- * the number of columns to set.
- */
- public void setColumns(int columns) {
- if (columns < 0) {
- columns = 0;
- }
- getState().setColumns(columns);
- requestRepaint();
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return getState().getInputPrompt();
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the field
- * would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- */
- public void setInputPrompt(String inputPrompt) {
- getState().setInputPrompt(inputPrompt);
- requestRepaint();
- }
-
- /* ** Text Change Events ** */
-
- private void firePendingTextChangeEvent() {
- if (textChangeEventPending && !isFiringTextChangeEvent) {
- isFiringTextChangeEvent = true;
- textChangeEventPending = false;
- try {
- fireEvent(new TextChangeEventImpl(this));
- } finally {
- isFiringTextChangeEvent = false;
- }
- }
- }
-
- @Override
- protected void setInternalValue(String newValue) {
- if (changingVariables && !textChangeEventPending) {
-
- /*
- * TODO check for possible (minor?) issue (not tested)
- *
- * -field with e.g. PropertyFormatter.
- *
- * -TextChangeListener and it changes value.
- *
- * -if formatter again changes the value, do we get an extra
- * simulated text change event ?
- */
-
- /*
- * Fire a "simulated" text change event before value change event if
- * change is coming from the client side.
- *
- * Iff there is both value change and textChangeEvent in same
- * variable burst, it is a text field in non immediate mode and the
- * text change event "flushed" queued value change event. In this
- * case textChangeEventPending flag is already on and text change
- * event will be fired after the value change event.
- */
- if (newValue == null && lastKnownTextContent != null
- && !lastKnownTextContent.equals(getNullRepresentation())) {
- // Value was changed from something to null representation
- lastKnownTextContent = getNullRepresentation();
- textChangeEventPending = true;
- } else if (newValue != null
- && !newValue.toString().equals(lastKnownTextContent)) {
- // Value was changed to something else than null representation
- lastKnownTextContent = newValue.toString();
- textChangeEventPending = true;
- }
- firePendingTextChangeEvent();
- }
-
- super.setInternalValue(newValue);
- }
-
- @Override
- public void setValue(Object newValue) throws ReadOnlyException {
- super.setValue(newValue);
- /*
- * Make sure w reset lastKnownTextContent field on value change. The
- * clearing must happen here as well because TextChangeListener can
- * revert the original value. Client must respect the value in this
- * case. AbstractField optimizes value change if the existing value is
- * reset. Also we need to force repaint if the flag is on.
- */
- if (lastKnownTextContent != null) {
- lastKnownTextContent = null;
- requestRepaint();
- }
- }
-
- private void handleInputEventTextChange(Map<String, Object> variables) {
- /*
- * TODO we could vastly optimize the communication of values by using
- * some sort of diffs instead of always sending the whole text content.
- * Also on value change events we could use the mechanism.
- */
- String object = (String) variables.get(VTextField.VAR_CUR_TEXT);
- lastKnownTextContent = object;
- textChangeEventPending = true;
- }
-
- /**
- * Sets the mode how the TextField triggers {@link TextChangeEvent}s.
- *
- * @param inputEventMode
- * the new mode
- *
- * @see TextChangeEventMode
- */
- public void setTextChangeEventMode(TextChangeEventMode inputEventMode) {
- textChangeEventMode = inputEventMode;
- requestRepaint();
- }
-
- /**
- * @return the mode used to trigger {@link TextChangeEvent}s.
- */
- public TextChangeEventMode getTextChangeEventMode() {
- return textChangeEventMode;
- }
-
- /**
- * Different modes how the TextField can trigger {@link TextChangeEvent}s.
- */
- public enum TextChangeEventMode {
-
- /**
- * An event is triggered on each text content change, most commonly key
- * press events.
- */
- EAGER,
- /**
- * Each text change event in the UI causes the event to be communicated
- * to the application after a timeout. The length of the timeout can be
- * controlled with {@link TextField#setInputEventTimeout(int)}. Only the
- * last input event is reported to the server side if several text
- * change events happen during the timeout.
- * <p>
- * In case of a {@link ValueChangeEvent} the schedule is not kept
- * strictly. Before a {@link ValueChangeEvent} a {@link TextChangeEvent}
- * is triggered if the text content has changed since the previous
- * TextChangeEvent regardless of the schedule.
- */
- TIMEOUT,
- /**
- * An event is triggered when there is a pause of text modifications.
- * The length of the pause can be modified with
- * {@link TextField#setInputEventTimeout(int)}. Like with the
- * {@link #TIMEOUT} mode, an event is forced before
- * {@link ValueChangeEvent}s, even if the user did not keep a pause
- * while entering the text.
- * <p>
- * This is the default mode.
- */
- LAZY
- }
-
- @Override
- public void addListener(TextChangeListener listener) {
- addListener(TextChangeListener.EVENT_ID, TextChangeEvent.class,
- listener, TextChangeListener.EVENT_METHOD);
- }
-
- @Override
- public void removeListener(TextChangeListener listener) {
- removeListener(TextChangeListener.EVENT_ID, TextChangeEvent.class,
- listener);
- }
-
- /**
- * The text change timeout modifies how often text change events are
- * communicated to the application when {@link #getTextChangeEventMode()} is
- * {@link TextChangeEventMode#LAZY} or {@link TextChangeEventMode#TIMEOUT}.
- *
- *
- * @see #getTextChangeEventMode()
- *
- * @param timeout
- * the timeout in milliseconds
- */
- public void setTextChangeTimeout(int timeout) {
- textChangeEventTimeout = timeout;
- requestRepaint();
- }
-
- /**
- * Gets the timeout used to fire {@link TextChangeEvent}s when the
- * {@link #getTextChangeEventMode()} is {@link TextChangeEventMode#LAZY} or
- * {@link TextChangeEventMode#TIMEOUT}.
- *
- * @return the timeout value in milliseconds
- */
- public int getTextChangeTimeout() {
- return textChangeEventTimeout;
- }
-
- public class TextChangeEventImpl extends TextChangeEvent {
- private String curText;
- private int cursorPosition;
-
- private TextChangeEventImpl(final AbstractTextField tf) {
- super(tf);
- curText = tf.getCurrentTextContent();
- cursorPosition = tf.getCursorPosition();
- }
-
- @Override
- public AbstractTextField getComponent() {
- return (AbstractTextField) super.getComponent();
- }
-
- @Override
- public String getText() {
- return curText;
- }
-
- @Override
- public int getCursorPosition() {
- return cursorPosition;
- }
-
- }
-
- /**
- * Gets the current (or the last known) text content in the field.
- * <p>
- * Note the text returned by this method is not necessary the same that is
- * returned by the {@link #getValue()} method. The value is updated when the
- * terminal fires a value change event via e.g. blurring the field or by
- * pressing enter. The value returned by this method is updated also on
- * {@link TextChangeEvent}s. Due to this high dependency to the terminal
- * implementation this method is (at least at this point) not published.
- *
- * @return the text which is currently displayed in the field.
- */
- private String getCurrentTextContent() {
- if (lastKnownTextContent != null) {
- return lastKnownTextContent;
- } else {
- Object text = getValue();
- if (text == null) {
- return getNullRepresentation();
- }
- return text.toString();
- }
- }
-
- /**
- * Selects all text in the field.
- *
- * @since 6.4
- */
- public void selectAll() {
- String text = getValue() == null ? "" : getValue().toString();
- setSelectionRange(0, text.length());
- }
-
- /**
- * Sets the range of text to be selected.
- *
- * As a side effect the field will become focused.
- *
- * @since 6.4
- *
- * @param pos
- * the position of the first character to be selected
- * @param length
- * the number of characters to be selected
- */
- public void setSelectionRange(int pos, int length) {
- selectionPosition = pos;
- selectionLength = length;
- focus();
- requestRepaint();
- }
-
- /**
- * Sets the cursor position in the field. As a side effect the field will
- * become focused.
- *
- * @since 6.4
- *
- * @param pos
- * the position for the cursor
- * */
- public void setCursorPosition(int pos) {
- setSelectionRange(pos, 0);
- lastKnownCursorPosition = pos;
- }
-
- /**
- * Returns the last known cursor position of the field.
- *
- * <p>
- * Note that due to the client server nature or the GWT terminal, Vaadin
- * cannot provide the exact value of the cursor position in most situations.
- * The value is updated only when the client side terminal communicates to
- * TextField, like on {@link ValueChangeEvent}s and {@link TextChangeEvent}
- * s. This may change later if a deep push integration is built to Vaadin.
- *
- * @return the cursor position
- */
- public int getCursorPosition() {
- return lastKnownCursorPosition;
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
-}
diff --git a/src/com/vaadin/ui/Accordion.java b/src/com/vaadin/ui/Accordion.java
deleted file mode 100644
index b937c7bc2b..0000000000
--- a/src/com/vaadin/ui/Accordion.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-/**
- * An accordion is a component similar to a {@link TabSheet}, but with a
- * vertical orientation and the selected component presented between tabs.
- *
- * Closable tabs are not supported by the accordion.
- *
- * The {@link Accordion} can be styled with the .v-accordion, .v-accordion-item,
- * .v-accordion-item-first and .v-accordion-item-caption styles.
- *
- * @see TabSheet
- */
-public class Accordion extends TabSheet {
-
-}
diff --git a/src/com/vaadin/ui/Alignment.java b/src/com/vaadin/ui/Alignment.java
deleted file mode 100644
index 0d73da8504..0000000000
--- a/src/com/vaadin/ui/Alignment.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.shared.ui.AlignmentInfo.Bits;
-
-/**
- * Class containing information about alignment of a component. Use the
- * pre-instantiated classes.
- */
-@SuppressWarnings("serial")
-public final class Alignment implements Serializable {
-
- public static final Alignment TOP_RIGHT = new Alignment(Bits.ALIGNMENT_TOP
- + Bits.ALIGNMENT_RIGHT);
- public static final Alignment TOP_LEFT = new Alignment(Bits.ALIGNMENT_TOP
- + Bits.ALIGNMENT_LEFT);
- public static final Alignment TOP_CENTER = new Alignment(Bits.ALIGNMENT_TOP
- + Bits.ALIGNMENT_HORIZONTAL_CENTER);
- public static final Alignment MIDDLE_RIGHT = new Alignment(
- Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_RIGHT);
- public static final Alignment MIDDLE_LEFT = new Alignment(
- Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_LEFT);
- public static final Alignment MIDDLE_CENTER = new Alignment(
- Bits.ALIGNMENT_VERTICAL_CENTER + Bits.ALIGNMENT_HORIZONTAL_CENTER);
- public static final Alignment BOTTOM_RIGHT = new Alignment(
- Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_RIGHT);
- public static final Alignment BOTTOM_LEFT = new Alignment(
- Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_LEFT);
- public static final Alignment BOTTOM_CENTER = new Alignment(
- Bits.ALIGNMENT_BOTTOM + Bits.ALIGNMENT_HORIZONTAL_CENTER);
-
- private final int bitMask;
-
- public Alignment(int bitMask) {
- this.bitMask = bitMask;
- }
-
- /**
- * Returns a bitmask representation of the alignment value. Used internally
- * by terminal.
- *
- * @return the bitmask representation of the alignment value
- */
- public int getBitMask() {
- return bitMask;
- }
-
- /**
- * Checks if component is aligned to the top of the available space.
- *
- * @return true if aligned top
- */
- public boolean isTop() {
- return (bitMask & Bits.ALIGNMENT_TOP) == Bits.ALIGNMENT_TOP;
- }
-
- /**
- * Checks if component is aligned to the bottom of the available space.
- *
- * @return true if aligned bottom
- */
- public boolean isBottom() {
- return (bitMask & Bits.ALIGNMENT_BOTTOM) == Bits.ALIGNMENT_BOTTOM;
- }
-
- /**
- * Checks if component is aligned to the left of the available space.
- *
- * @return true if aligned left
- */
- public boolean isLeft() {
- return (bitMask & Bits.ALIGNMENT_LEFT) == Bits.ALIGNMENT_LEFT;
- }
-
- /**
- * Checks if component is aligned to the right of the available space.
- *
- * @return true if aligned right
- */
- public boolean isRight() {
- return (bitMask & Bits.ALIGNMENT_RIGHT) == Bits.ALIGNMENT_RIGHT;
- }
-
- /**
- * Checks if component is aligned middle (vertically center) of the
- * available space.
- *
- * @return true if aligned bottom
- */
- public boolean isMiddle() {
- return (bitMask & Bits.ALIGNMENT_VERTICAL_CENTER) == Bits.ALIGNMENT_VERTICAL_CENTER;
- }
-
- /**
- * Checks if component is aligned center (horizontally) of the available
- * space.
- *
- * @return true if aligned center
- */
- public boolean isCenter() {
- return (bitMask & Bits.ALIGNMENT_HORIZONTAL_CENTER) == Bits.ALIGNMENT_HORIZONTAL_CENTER;
- }
-
- /**
- * Returns string representation of vertical alignment.
- *
- * @return vertical alignment as CSS value
- */
- public String getVerticalAlignment() {
- if (isBottom()) {
- return "bottom";
- } else if (isMiddle()) {
- return "middle";
- }
- return "top";
- }
-
- /**
- * Returns string representation of horizontal alignment.
- *
- * @return horizontal alignment as CSS value
- */
- public String getHorizontalAlignment() {
- if (isRight()) {
- return "right";
- } else if (isCenter()) {
- return "center";
- }
- return "left";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if ((obj == null) || (obj.getClass() != this.getClass())) {
- return false;
- }
- Alignment a = (Alignment) obj;
- return bitMask == a.bitMask;
- }
-
- @Override
- public int hashCode() {
- return bitMask;
- }
-
- @Override
- public String toString() {
- return String.valueOf(bitMask);
- }
-
-}
diff --git a/src/com/vaadin/ui/Audio.java b/src/com/vaadin/ui/Audio.java
deleted file mode 100644
index ac2ee869a6..0000000000
--- a/src/com/vaadin/ui/Audio.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.terminal.Resource;
-
-/**
- * The Audio component translates into an HTML5 &lt;audio&gt; element and as
- * such is only supported in browsers that support HTML5 media markup. Browsers
- * that do not support HTML5 display the text or HTML set by calling
- * {@link #setAltText(String)}.
- *
- * A flash-player fallback can be implemented by setting HTML content allowed (
- * {@link #setHtmlContentAllowed(boolean)} and calling
- * {@link #setAltText(String)} with the flash player markup. An example of flash
- * fallback can be found at the <a href=
- * "https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Using_Flash"
- * >Mozilla Developer Network</a>.
- *
- * Multiple sources can be specified. Which of the sources is used is selected
- * by the browser depending on which file formats it supports. See <a
- * href="http://en.wikipedia.org/wiki/HTML5_video#Table">wikipedia</a> for a
- * table of formats supported by different browsers.
- *
- * @author Vaadin Ltd
- * @since 6.7.0
- */
-public class Audio extends AbstractMedia {
-
- public Audio() {
- this("", null);
- }
-
- /**
- * @param caption
- * The caption of the audio component.
- */
- public Audio(String caption) {
- this(caption, null);
- }
-
- /**
- * @param caption
- * The caption of the audio component
- * @param source
- * The audio file to play.
- */
- public Audio(String caption, Resource source) {
- setCaption(caption);
- setSource(source);
- setShowControls(true);
- }
-}
diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java
deleted file mode 100644
index 0cb667d527..0000000000
--- a/src/com/vaadin/ui/Button.java
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import com.vaadin.event.Action;
-import com.vaadin.event.FieldEvents;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.event.ShortcutAction;
-import com.vaadin.event.ShortcutAction.KeyCode;
-import com.vaadin.event.ShortcutAction.ModifierKey;
-import com.vaadin.event.ShortcutListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.button.ButtonServerRpc;
-import com.vaadin.shared.ui.button.ButtonState;
-import com.vaadin.tools.ReflectTools;
-import com.vaadin.ui.Component.Focusable;
-
-/**
- * A generic button component.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Button extends AbstractComponent implements
- FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, Focusable,
- Action.ShortcutNotifier {
-
- private ButtonServerRpc rpc = new ButtonServerRpc() {
-
- @Override
- public void click(MouseEventDetails mouseEventDetails) {
- fireClick(mouseEventDetails);
- }
-
- @Override
- public void disableOnClick() {
- // Could be optimized so the button is not repainted because of
- // this (client side has already disabled the button)
- setEnabled(false);
- }
- };
-
- FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(this) {
-
- @Override
- protected void fireEvent(Event event) {
- Button.this.fireEvent(event);
- }
- };
-
- /**
- * Creates a new push button.
- */
- public Button() {
- registerRpc(rpc);
- registerRpc(focusBlurRpc);
- }
-
- /**
- * Creates a new push button with the given caption.
- *
- * @param caption
- * the Button caption.
- */
- public Button(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Creates a new push button with a click listener.
- *
- * @param caption
- * the Button caption.
- * @param listener
- * the Button click listener.
- */
- public Button(String caption, ClickListener listener) {
- this(caption);
- addListener(listener);
- }
-
- /**
- * Click event. This event is thrown, when the button is clicked.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class ClickEvent extends Component.Event {
-
- private final MouseEventDetails details;
-
- /**
- * New instance of text change event.
- *
- * @param source
- * the Source of the event.
- */
- public ClickEvent(Component source) {
- super(source);
- details = null;
- }
-
- /**
- * Constructor with mouse details
- *
- * @param source
- * The source where the click took place
- * @param details
- * Details about the mouse click
- */
- public ClickEvent(Component source, MouseEventDetails details) {
- super(source);
- this.details = details;
- }
-
- /**
- * Gets the Button where the event occurred.
- *
- * @return the Source of the event.
- */
- public Button getButton() {
- return (Button) getSource();
- }
-
- /**
- * Returns the mouse position (x coordinate) when the click took place.
- * The position is relative to the browser client area.
- *
- * @return The mouse cursor x position or -1 if unknown
- */
- public int getClientX() {
- if (null != details) {
- return details.getClientX();
- } else {
- return -1;
- }
- }
-
- /**
- * Returns the mouse position (y coordinate) when the click took place.
- * The position is relative to the browser client area.
- *
- * @return The mouse cursor y position or -1 if unknown
- */
- public int getClientY() {
- if (null != details) {
- return details.getClientY();
- } else {
- return -1;
- }
- }
-
- /**
- * Returns the relative mouse position (x coordinate) when the click
- * took place. The position is relative to the clicked component.
- *
- * @return The mouse cursor x position relative to the clicked layout
- * component or -1 if no x coordinate available
- */
- public int getRelativeX() {
- if (null != details) {
- return details.getRelativeX();
- } else {
- return -1;
- }
- }
-
- /**
- * Returns the relative mouse position (y coordinate) when the click
- * took place. The position is relative to the clicked component.
- *
- * @return The mouse cursor y position relative to the clicked layout
- * component or -1 if no y coordinate available
- */
- public int getRelativeY() {
- if (null != details) {
- return details.getRelativeY();
- } else {
- return -1;
- }
- }
-
- /**
- * Checks if the Alt key was down when the mouse event took place.
- *
- * @return true if Alt was down when the event occured, false otherwise
- * or if unknown
- */
- public boolean isAltKey() {
- if (null != details) {
- return details.isAltKey();
- } else {
- return false;
- }
- }
-
- /**
- * Checks if the Ctrl key was down when the mouse event took place.
- *
- * @return true if Ctrl was pressed when the event occured, false
- * otherwise or if unknown
- */
- public boolean isCtrlKey() {
- if (null != details) {
- return details.isCtrlKey();
- } else {
- return false;
- }
- }
-
- /**
- * Checks if the Meta key was down when the mouse event took place.
- *
- * @return true if Meta was pressed when the event occured, false
- * otherwise or if unknown
- */
- public boolean isMetaKey() {
- if (null != details) {
- return details.isMetaKey();
- } else {
- return false;
- }
- }
-
- /**
- * Checks if the Shift key was down when the mouse event took place.
- *
- * @return true if Shift was pressed when the event occured, false
- * otherwise or if unknown
- */
- public boolean isShiftKey() {
- if (null != details) {
- return details.isShiftKey();
- } else {
- return false;
- }
- }
- }
-
- /**
- * Interface for listening for a {@link ClickEvent} fired by a
- * {@link Component}.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ClickListener extends Serializable {
-
- public static final Method BUTTON_CLICK_METHOD = ReflectTools
- .findMethod(ClickListener.class, "buttonClick",
- ClickEvent.class);
-
- /**
- * Called when a {@link Button} has been clicked. A reference to the
- * button is given by {@link ClickEvent#getButton()}.
- *
- * @param event
- * An event containing information about the click.
- */
- public void buttonClick(ClickEvent event);
-
- }
-
- /**
- * Adds the button click listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(ClickListener listener) {
- addListener(ClickEvent.class, listener,
- ClickListener.BUTTON_CLICK_METHOD);
- }
-
- /**
- * Removes the button click listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(ClickListener listener) {
- removeListener(ClickEvent.class, listener,
- ClickListener.BUTTON_CLICK_METHOD);
- }
-
- /**
- * Simulates a button click, notifying all server-side listeners.
- *
- * No action is taken is the button is disabled.
- */
- public void click() {
- if (isEnabled() && !isReadOnly()) {
- fireClick();
- }
- }
-
- /**
- * Fires a click event to all listeners without any event details.
- *
- * In subclasses, override {@link #fireClick(MouseEventDetails)} instead of
- * this method.
- */
- protected void fireClick() {
- fireEvent(new Button.ClickEvent(this));
- }
-
- /**
- * Fires a click event to all listeners.
- *
- * @param details
- * MouseEventDetails from which keyboard modifiers and other
- * information about the mouse click can be obtained. If the
- * button was clicked by a keyboard event, some of the fields may
- * be empty/undefined.
- */
- protected void fireClick(MouseEventDetails details) {
- fireEvent(new Button.ClickEvent(this, details));
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
-
- }
-
- /*
- * Actions
- */
-
- protected ClickShortcut clickShortcut;
-
- /**
- * Makes it possible to invoke a click on this button by pressing the given
- * {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
- * The shortcut is global (bound to the containing Window).
- *
- * @param keyCode
- * the keycode for invoking the shortcut
- * @param modifiers
- * the (optional) modifiers for invoking the shortcut, null for
- * none
- */
- public void setClickShortcut(int keyCode, int... modifiers) {
- if (clickShortcut != null) {
- removeShortcutListener(clickShortcut);
- }
- clickShortcut = new ClickShortcut(this, keyCode, modifiers);
- addShortcutListener(clickShortcut);
- getState().setClickShortcutKeyCode(clickShortcut.getKeyCode());
- }
-
- /**
- * Removes the keyboard shortcut previously set with
- * {@link #setClickShortcut(int, int...)}.
- */
- public void removeClickShortcut() {
- if (clickShortcut != null) {
- removeShortcutListener(clickShortcut);
- clickShortcut = null;
- getState().setClickShortcutKeyCode(0);
- }
- }
-
- /**
- * A {@link ShortcutListener} specifically made to define a keyboard
- * shortcut that invokes a click on the given button.
- *
- */
- public static class ClickShortcut extends ShortcutListener {
- protected Button button;
-
- /**
- * Creates a keyboard shortcut for clicking the given button using the
- * shorthand notation defined in {@link ShortcutAction}.
- *
- * @param button
- * to be clicked when the shortcut is invoked
- * @param shorthandCaption
- * the caption with shortcut keycode and modifiers indicated
- */
- public ClickShortcut(Button button, String shorthandCaption) {
- super(shorthandCaption);
- this.button = button;
- }
-
- /**
- * Creates a keyboard shortcut for clicking the given button using the
- * given {@link KeyCode} and {@link ModifierKey}s.
- *
- * @param button
- * to be clicked when the shortcut is invoked
- * @param keyCode
- * KeyCode to react to
- * @param modifiers
- * optional modifiers for shortcut
- */
- public ClickShortcut(Button button, int keyCode, int... modifiers) {
- super(null, keyCode, modifiers);
- this.button = button;
- }
-
- /**
- * Creates a keyboard shortcut for clicking the given button using the
- * given {@link KeyCode}.
- *
- * @param button
- * to be clicked when the shortcut is invoked
- * @param keyCode
- * KeyCode to react to
- */
- public ClickShortcut(Button button, int keyCode) {
- this(button, keyCode, null);
- }
-
- @Override
- public void handleAction(Object sender, Object target) {
- button.click();
- }
- }
-
- /**
- * Determines if a button is automatically disabled when clicked. See
- * {@link #setDisableOnClick(boolean)} for details.
- *
- * @return true if the button is disabled when clicked, false otherwise
- */
- public boolean isDisableOnClick() {
- return getState().isDisableOnClick();
- }
-
- /**
- * Determines if a button is automatically disabled when clicked. If this is
- * set to true the button will be automatically disabled when clicked,
- * typically to prevent (accidental) extra clicks on a button.
- *
- * @param disableOnClick
- * true to disable button when it is clicked, false otherwise
- */
- public void setDisableOnClick(boolean disableOnClick) {
- getState().setDisableOnClick(disableOnClick);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#getTabIndex()
- */
- @Override
- public int getTabIndex() {
- return getState().getTabIndex();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
- */
- @Override
- public void setTabIndex(int tabIndex) {
- getState().setTabIndex(tabIndex);
- requestRepaint();
- }
-
- @Override
- public void focus() {
- // Overridden only to make public
- super.focus();
- }
-
- @Override
- public ButtonState getState() {
- return (ButtonState) super.getState();
- }
-
- /**
- * Set whether the caption text is rendered as HTML or not. You might need
- * to retheme button to allow higher content than the original text style.
- *
- * If set to true, the captions are passed to the browser as html and the
- * developer is responsible for ensuring no harmful html is used. If set to
- * false, the content is passed to the browser as plain text.
- *
- * @param htmlContentAllowed
- * <code>true</code> if caption is rendered as HTML,
- * <code>false</code> otherwise
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- if (getState().isHtmlContentAllowed() != htmlContentAllowed) {
- getState().setHtmlContentAllowed(htmlContentAllowed);
- requestRepaint();
- }
- }
-
- /**
- * Return HTML rendering setting
- *
- * @return <code>true</code> if the caption text is to be rendered as HTML,
- * <code>false</code> otherwise
- */
- public boolean isHtmlContentAllowed() {
- return getState().isHtmlContentAllowed();
- }
-
-}
diff --git a/src/com/vaadin/ui/CheckBox.java b/src/com/vaadin/ui/CheckBox.java
deleted file mode 100644
index 30ac9b4626..0000000000
--- a/src/com/vaadin/ui/CheckBox.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.data.Property;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusAndBlurServerRpcImpl;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.checkbox.CheckBoxServerRpc;
-import com.vaadin.shared.ui.checkbox.CheckBoxState;
-
-public class CheckBox extends AbstractField<Boolean> {
-
- private CheckBoxServerRpc rpc = new CheckBoxServerRpc() {
-
- @Override
- public void setChecked(boolean checked,
- MouseEventDetails mouseEventDetails) {
- if (isReadOnly()) {
- return;
- }
-
- final Boolean oldValue = getValue();
- final Boolean newValue = checked;
-
- if (!newValue.equals(oldValue)) {
- // The event is only sent if the switch state is changed
- setValue(newValue);
- }
-
- }
- };
-
- FocusAndBlurServerRpcImpl focusBlurRpc = new FocusAndBlurServerRpcImpl(this) {
- @Override
- protected void fireEvent(Event event) {
- CheckBox.this.fireEvent(event);
- }
- };
-
- /**
- * Creates a new checkbox.
- */
- public CheckBox() {
- registerRpc(rpc);
- registerRpc(focusBlurRpc);
- setValue(Boolean.FALSE);
- }
-
- /**
- * Creates a new checkbox with a set caption.
- *
- * @param caption
- * the Checkbox caption.
- */
- public CheckBox(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Creates a new checkbox with a caption and a set initial state.
- *
- * @param caption
- * the caption of the checkbox
- * @param initialState
- * the initial state of the checkbox
- */
- public CheckBox(String caption, boolean initialState) {
- this(caption);
- setValue(initialState);
- }
-
- /**
- * Creates a new checkbox that is connected to a boolean property.
- *
- * @param state
- * the Initial state of the switch-button.
- * @param dataSource
- */
- public CheckBox(String caption, Property<?> dataSource) {
- this(caption);
- setPropertyDataSource(dataSource);
- }
-
- @Override
- public Class<Boolean> getType() {
- return Boolean.class;
- }
-
- @Override
- public CheckBoxState getState() {
- return (CheckBoxState) super.getState();
- }
-
- @Override
- protected void setInternalValue(Boolean newValue) {
- super.setInternalValue(newValue);
- if (newValue == null) {
- newValue = false;
- }
- getState().setChecked(newValue);
- }
-
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
- }
-
- /**
- * Get the boolean value of the button state.
- *
- * @return True iff the button is pressed down or checked.
- *
- * @deprecated Use {@link #getValue()} instead and, if needed, handle null
- * values.
- */
- @Deprecated
- public boolean booleanValue() {
- Boolean value = getValue();
- return (null == value) ? false : value.booleanValue();
- }
-}
diff --git a/src/com/vaadin/ui/ComboBox.java b/src/com/vaadin/ui/ComboBox.java
deleted file mode 100644
index 6286dad124..0000000000
--- a/src/com/vaadin/ui/ComboBox.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.combobox.VFilterSelect;
-
-/**
- * A filtering dropdown single-select. Suitable for newItemsAllowed, but it's
- * turned of by default to avoid mistakes. Items are filtered based on user
- * input, and loaded dynamically ("lazy-loading") from the server. You can turn
- * on newItemsAllowed and change filtering mode (and also turn it off), but you
- * can not turn on multi-select mode.
- *
- */
-@SuppressWarnings("serial")
-public class ComboBox extends Select {
-
- private String inputPrompt = null;
-
- /**
- * If text input is not allowed, the ComboBox behaves like a pretty
- * NativeSelect - the user can not enter any text and clicking the text
- * field opens the drop down with options
- */
- private boolean textInputAllowed = true;
-
- public ComboBox() {
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Collection<?> options) {
- super(caption, options);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption, Container dataSource) {
- super(caption, dataSource);
- setNewItemsAllowed(false);
- }
-
- public ComboBox(String caption) {
- super(caption);
- setNewItemsAllowed(false);
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the
- * select would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- * the desired input prompt, or null to disable
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- super.paintContent(target);
-
- if (!textInputAllowed) {
- target.addAttribute(VFilterSelect.ATTR_NO_TEXT_INPUT, true);
- }
- }
-
- /**
- * Sets whether it is possible to input text into the field or whether the
- * field area of the component is just used to show what is selected. By
- * disabling text input, the comboBox will work in the same way as a
- * {@link NativeSelect}
- *
- * @see #isTextInputAllowed()
- *
- * @param textInputAllowed
- * true to allow entering text, false to just show the current
- * selection
- */
- public void setTextInputAllowed(boolean textInputAllowed) {
- this.textInputAllowed = textInputAllowed;
- requestRepaint();
- }
-
- /**
- * Returns true if the user can enter text into the field to either filter
- * the selections or enter a new value if {@link #isNewItemsAllowed()}
- * returns true. If text input is disabled, the comboBox will work in the
- * same way as a {@link NativeSelect}
- *
- * @return
- */
- public boolean isTextInputAllowed() {
- return textInputAllowed;
- }
-
-}
diff --git a/src/com/vaadin/ui/Component.java b/src/com/vaadin/ui/Component.java
deleted file mode 100644
index a2c257ab68..0000000000
--- a/src/com/vaadin/ui/Component.java
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.EventListener;
-import java.util.EventObject;
-import java.util.Locale;
-
-import com.vaadin.Application;
-import com.vaadin.event.FieldEvents;
-import com.vaadin.shared.ComponentState;
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Sizeable;
-import com.vaadin.terminal.VariableOwner;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * {@code Component} is the top-level interface that is and must be implemented
- * by all Vaadin components. {@code Component} is paired with
- * {@link AbstractComponent}, which provides a default implementation for all
- * the methods defined in this interface.
- *
- * <p>
- * Components are laid out in the user interface hierarchically. The layout is
- * managed by layout components, or more generally by components that implement
- * the {@link ComponentContainer} interface. Such a container is the
- * <i>parent</i> of the contained components.
- * </p>
- *
- * <p>
- * The {@link #getParent()} method allows retrieving the parent component of a
- * component. While there is a {@link #setParent(Component) setParent()}, you
- * rarely need it as you normally add components with the
- * {@link ComponentContainer#addComponent(Component) addComponent()} method of
- * the layout or other {@code ComponentContainer}, which automatically sets the
- * parent.
- * </p>
- *
- * <p>
- * A component becomes <i>attached</i> to an application (and the
- * {@link #attach()} is called) when it or one of its parents is attached to the
- * main window of the application through its containment hierarchy.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Component extends ClientConnector, Sizeable, Serializable {
-
- /**
- * Gets all user-defined CSS style names of a component. If the component
- * has multiple style names defined, the return string is a space-separated
- * list of style names. Built-in style names defined in Vaadin or GWT are
- * not returned.
- *
- * <p>
- * The style names are returned only in the basic form in which they were
- * added; each user-defined style name shows as two CSS style class names in
- * the rendered HTML: one as it was given and one prefixed with the
- * component-specific style name. Only the former is returned.
- * </p>
- *
- * @return the style name or a space-separated list of user-defined style
- * names of the component
- * @see #setStyleName(String)
- * @see #addStyleName(String)
- * @see #removeStyleName(String)
- */
- public String getStyleName();
-
- /**
- * Sets one or more user-defined style names of the component, replacing any
- * previous user-defined styles. Multiple styles can be specified as a
- * space-separated list of style names. The style names must be valid CSS
- * class names and should not conflict with any built-in style names in
- * Vaadin or GWT.
- *
- * <pre>
- * Label label = new Label(&quot;This text has a lot of style&quot;);
- * label.setStyleName(&quot;myonestyle myotherstyle&quot;);
- * </pre>
- *
- * <p>
- * Each style name will occur in two versions: one as specified and one that
- * is prefixed with the style name of the component. For example, if you
- * have a {@code Button} component and give it "{@code mystyle}" style, the
- * component will have both "{@code mystyle}" and "{@code v-button-mystyle}"
- * styles. You could then style the component either with:
- * </p>
- *
- * <pre>
- * .myonestyle {background: blue;}
- * </pre>
- *
- * <p>
- * or
- * </p>
- *
- * <pre>
- * .v-button-myonestyle {background: blue;}
- * </pre>
- *
- * <p>
- * It is normally a good practice to use {@link #addStyleName(String)
- * addStyleName()} rather than this setter, as different software
- * abstraction layers can then add their own styles without accidentally
- * removing those defined in other layers.
- * </p>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent}.
- * </p>
- *
- * @param style
- * the new style or styles of the component as a space-separated
- * list
- * @see #getStyleName()
- * @see #addStyleName(String)
- * @see #removeStyleName(String)
- */
- public void setStyleName(String style);
-
- /**
- * Adds a style name to component. The style name will be rendered as a HTML
- * class name, which can be used in a CSS definition.
- *
- * <pre>
- * Label label = new Label(&quot;This text has style&quot;);
- * label.addStyleName(&quot;mystyle&quot;);
- * </pre>
- *
- * <p>
- * Each style name will occur in two versions: one as specified and one that
- * is prefixed wil the style name of the component. For example, if you have
- * a {@code Button} component and give it "{@code mystyle}" style, the
- * component will have both "{@code mystyle}" and "{@code v-button-mystyle}"
- * styles. You could then style the component either with:
- * </p>
- *
- * <pre>
- * .mystyle {font-style: italic;}
- * </pre>
- *
- * <p>
- * or
- * </p>
- *
- * <pre>
- * .v-button-mystyle {font-style: italic;}
- * </pre>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent}.
- * </p>
- *
- * @param style
- * the new style to be added to the component
- * @see #getStyleName()
- * @see #setStyleName(String)
- * @see #removeStyleName(String)
- */
- public void addStyleName(String style);
-
- /**
- * Removes one or more style names from component. Multiple styles can be
- * specified as a space-separated list of style names.
- *
- * <p>
- * The parameter must be a valid CSS style name. Only user-defined style
- * names added with {@link #addStyleName(String) addStyleName()} or
- * {@link #setStyleName(String) setStyleName()} can be removed; built-in
- * style names defined in Vaadin or GWT can not be removed.
- * </p>
- *
- * * This method will trigger a {@link RepaintRequestEvent}.
- *
- * @param style
- * the style name or style names to be removed
- * @see #getStyleName()
- * @see #setStyleName(String)
- * @see #addStyleName(String)
- */
- public void removeStyleName(String style);
-
- /**
- * Tests whether the component is enabled or not. A user can not interact
- * with disabled components. Disabled components are rendered in a style
- * that indicates the status, usually in gray color. Children of a disabled
- * component are also disabled. Components are enabled by default.
- *
- * <p>
- * As a security feature, all updates for disabled components are blocked on
- * the server-side.
- * </p>
- *
- * <p>
- * Note that this method only returns the status of the component and does
- * not take parents into account. Even though this method returns true the
- * component can be disabled to the user if a parent is disabled.
- * </p>
- *
- * @return <code>true</code> if the component and its parent are enabled,
- * <code>false</code> otherwise.
- * @see VariableOwner#isEnabled()
- */
- public boolean isEnabled();
-
- /**
- * Enables or disables the component. The user can not interact disabled
- * components, which are shown with a style that indicates the status,
- * usually shaded in light gray color. Components are enabled by default.
- *
- * <pre>
- * Button enabled = new Button(&quot;Enabled&quot;);
- * enabled.setEnabled(true); // The default
- * layout.addComponent(enabled);
- *
- * Button disabled = new Button(&quot;Disabled&quot;);
- * disabled.setEnabled(false);
- * layout.addComponent(disabled);
- * </pre>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent} for the component
- * and, if it is a {@link ComponentContainer}, for all its children
- * recursively.
- * </p>
- *
- * @param enabled
- * a boolean value specifying if the component should be enabled
- * or not
- */
- public void setEnabled(boolean enabled);
-
- /**
- * Tests the <i>visibility</i> property of the component.
- *
- * <p>
- * Visible components are drawn in the user interface, while invisible ones
- * are not. The effect is not merely a cosmetic CSS change - no information
- * about an invisible component will be sent to the client. The effect is
- * thus the same as removing the component from its parent. Making a
- * component invisible through this property can alter the positioning of
- * other components.
- * </p>
- *
- * <p>
- * A component is visible only if all its parents are also visible. This is
- * not checked by this method though, so even if this method returns true,
- * the component can be hidden from the user because a parent is set to
- * invisible.
- * </p>
- *
- * @return <code>true</code> if the component has been set to be visible in
- * the user interface, <code>false</code> if not
- * @see #setVisible(boolean)
- * @see #attach()
- */
- public boolean isVisible();
-
- /**
- * Sets the visibility of the component.
- *
- * <p>
- * Visible components are drawn in the user interface, while invisible ones
- * are not. The effect is not merely a cosmetic CSS change - no information
- * about an invisible component will be sent to the client. The effect is
- * thus the same as removing the component from its parent.
- * </p>
- *
- * <pre>
- * TextField readonly = new TextField(&quot;Read-Only&quot;);
- * readonly.setValue(&quot;You can't see this!&quot;);
- * readonly.setVisible(false);
- * layout.addComponent(readonly);
- * </pre>
- *
- * <p>
- * A component is visible only if all of its parents are also visible. If a
- * component is explicitly set to be invisible, changes in the visibility of
- * its parents will not change the visibility of the component.
- * </p>
- *
- * @param visible
- * the boolean value specifying if the component should be
- * visible after the call or not.
- * @see #isVisible()
- */
- public void setVisible(boolean visible);
-
- /**
- * Gets the parent component of the component.
- *
- * <p>
- * Components can be nested but a component can have only one parent. A
- * component that contains other components, that is, can be a parent,
- * should usually inherit the {@link ComponentContainer} interface.
- * </p>
- *
- * @return the parent component
- */
- @Override
- public HasComponents getParent();
-
- /**
- * Tests whether the component is in the read-only mode. The user can not
- * change the value of a read-only component. As only {@link Field}
- * components normally have a value that can be input or changed by the
- * user, this is mostly relevant only to field components, though not
- * restricted to them.
- *
- * <p>
- * Notice that the read-only mode only affects whether the user can change
- * the <i>value</i> of the component; it is possible to, for example, scroll
- * a read-only table.
- * </p>
- *
- * <p>
- * The method will return {@code true} if the component or any of its
- * parents is in the read-only mode.
- * </p>
- *
- * @return <code>true</code> if the component or any of its parents is in
- * read-only mode, <code>false</code> if not.
- * @see #setReadOnly(boolean)
- */
- public boolean isReadOnly();
-
- /**
- * Sets the read-only mode of the component to the specified mode. The user
- * can not change the value of a read-only component.
- *
- * <p>
- * As only {@link Field} components normally have a value that can be input
- * or changed by the user, this is mostly relevant only to field components,
- * though not restricted to them.
- * </p>
- *
- * <p>
- * Notice that the read-only mode only affects whether the user can change
- * the <i>value</i> of the component; it is possible to, for example, scroll
- * a read-only table.
- * </p>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent}.
- * </p>
- *
- * @param readOnly
- * a boolean value specifying whether the component is put
- * read-only mode or not
- */
- public void setReadOnly(boolean readOnly);
-
- /**
- * Gets the caption of the component.
- *
- * <p>
- * See {@link #setCaption(String)} for a detailed description of the
- * caption.
- * </p>
- *
- * @return the caption of the component or {@code null} if the caption is
- * not set.
- * @see #setCaption(String)
- */
- public String getCaption();
-
- /**
- * Sets the caption of the component.
- *
- * <p>
- * A <i>caption</i> is an explanatory textual label accompanying a user
- * interface component, usually shown above, left of, or inside the
- * component. <i>Icon</i> (see {@link #setIcon(Resource) setIcon()} is
- * closely related to caption and is usually displayed horizontally before
- * or after it, depending on the component and the containing layout.
- * </p>
- *
- * <p>
- * The caption can usually also be given as the first parameter to a
- * constructor, though some components do not support it.
- * </p>
- *
- * <pre>
- * RichTextArea area = new RichTextArea();
- * area.setCaption(&quot;You can edit stuff here&quot;);
- * area.setValue(&quot;&lt;h1&gt;Helpful Heading&lt;/h1&gt;&quot;
- * + &quot;&lt;p&gt;All this is for you to edit.&lt;/p&gt;&quot;);
- * </pre>
- *
- * <p>
- * The contents of a caption are automatically quoted, so no raw XHTML can
- * be rendered in a caption. The validity of the used character encoding,
- * usually UTF-8, is not checked.
- * </p>
- *
- * <p>
- * The caption of a component is, by default, managed and displayed by the
- * layout component or component container in which the component is placed.
- * For example, the {@link VerticalLayout} component shows the captions
- * left-aligned above the contained components, while the {@link FormLayout}
- * component shows the captions on the left side of the vertically laid
- * components, with the captions and their associated components
- * left-aligned in their own columns. The {@link CustomComponent} does not
- * manage the caption of its composition root, so if the root component has
- * a caption, it will not be rendered. Some components, such as
- * {@link Button} and {@link Panel}, manage the caption themselves and
- * display it inside the component.
- * </p>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent}. A
- * reimplementation should call the superclass implementation.
- * </p>
- *
- * @param caption
- * the new caption for the component. If the caption is
- * {@code null}, no caption is shown and it does not normally
- * take any space
- */
- public void setCaption(String caption);
-
- /**
- * Gets the icon resource of the component.
- *
- * <p>
- * See {@link #setIcon(Resource)} for a detailed description of the icon.
- * </p>
- *
- * @return the icon resource of the component or {@code null} if the
- * component has no icon
- * @see #setIcon(Resource)
- */
- public Resource getIcon();
-
- /**
- * Sets the icon of the component.
- *
- * <p>
- * An icon is an explanatory graphical label accompanying a user interface
- * component, usually shown above, left of, or inside the component. Icon is
- * closely related to caption (see {@link #setCaption(String) setCaption()})
- * and is usually displayed horizontally before or after it, depending on
- * the component and the containing layout.
- * </p>
- *
- * <p>
- * The image is loaded by the browser from a resource, typically a
- * {@link com.vaadin.terminal.ThemeResource}.
- * </p>
- *
- * <pre>
- * // Component with an icon from a custom theme
- * TextField name = new TextField(&quot;Name&quot;);
- * name.setIcon(new ThemeResource(&quot;icons/user.png&quot;));
- * layout.addComponent(name);
- *
- * // Component with an icon from another theme ('runo')
- * Button ok = new Button(&quot;OK&quot;);
- * ok.setIcon(new ThemeResource(&quot;../runo/icons/16/ok.png&quot;));
- * layout.addComponent(ok);
- * </pre>
- *
- * <p>
- * The icon of a component is, by default, managed and displayed by the
- * layout component or component container in which the component is placed.
- * For example, the {@link VerticalLayout} component shows the icons
- * left-aligned above the contained components, while the {@link FormLayout}
- * component shows the icons on the left side of the vertically laid
- * components, with the icons and their associated components left-aligned
- * in their own columns. The {@link CustomComponent} does not manage the
- * icon of its composition root, so if the root component has an icon, it
- * will not be rendered.
- * </p>
- *
- * <p>
- * An icon will be rendered inside an HTML element that has the
- * {@code v-icon} CSS style class. The containing layout may enclose an icon
- * and a caption inside elements related to the caption, such as
- * {@code v-caption} .
- * </p>
- *
- * This method will trigger a {@link RepaintRequestEvent}.
- *
- * @param icon
- * the icon of the component. If null, no icon is shown and it
- * does not normally take any space.
- * @see #getIcon()
- * @see #setCaption(String)
- */
- public void setIcon(Resource icon);
-
- /**
- * Gets the Root the component is attached to.
- *
- * <p>
- * If the component is not attached to a Root through a component
- * containment hierarchy, <code>null</code> is returned.
- * </p>
- *
- * @return the Root of the component or <code>null</code> if it is not
- * attached to a Root
- */
- @Override
- public Root getRoot();
-
- /**
- * Gets the application object to which the component is attached.
- *
- * <p>
- * The method will return {@code null} if the component is not currently
- * attached to an application.
- * </p>
- *
- * <p>
- * Getting a null value is often a problem in constructors of regular
- * components and in the initializers of custom composite components. A
- * standard workaround is to use {@link Application#getCurrent()} to
- * retrieve the application instance that the current request relates to.
- * Another way is to move the problematic initialization to
- * {@link #attach()}, as described in the documentation of the method.
- * </p>
- *
- * @return the parent application of the component or <code>null</code>.
- * @see #attach()
- */
- public Application getApplication();
-
- /**
- * {@inheritDoc}
- *
- * <p>
- * Reimplementing the {@code attach()} method is useful for tasks that need
- * to get a reference to the parent, window, or application object with the
- * {@link #getParent()}, {@link #getRoot()}, and {@link #getApplication()}
- * methods. A component does not yet know these objects in the constructor,
- * so in such case, the methods will return {@code null}. For example, the
- * following is invalid:
- * </p>
- *
- * <pre>
- * public class AttachExample extends CustomComponent {
- * public AttachExample() {
- * // ERROR: We can't access the application object yet.
- * ClassResource r = new ClassResource(&quot;smiley.jpg&quot;, getApplication());
- * Embedded image = new Embedded(&quot;Image:&quot;, r);
- * setCompositionRoot(image);
- * }
- * }
- * </pre>
- *
- * <p>
- * Adding a component to an application triggers calling the
- * {@link #attach()} method for the component. Correspondingly, removing a
- * component from a container triggers calling the {@link #detach()} method.
- * If the parent of an added component is already connected to the
- * application, the {@code attach()} is called immediately from
- * {@link #setParent(Component)}.
- * </p>
- * <p>
- * This method must call {@link Root#componentAttached(Component)} to let
- * the Root know that a new Component has been attached.
- * </p>
- *
- *
- * <pre>
- * public class AttachExample extends CustomComponent {
- * public AttachExample() {
- * }
- *
- * &#064;Override
- * public void attach() {
- * super.attach(); // Must call.
- *
- * // Now we know who ultimately owns us.
- * ClassResource r = new ClassResource(&quot;smiley.jpg&quot;, getApplication());
- * Embedded image = new Embedded(&quot;Image:&quot;, r);
- * setCompositionRoot(image);
- * }
- * }
- * </pre>
- */
- @Override
- public void attach();
-
- /**
- * Gets the locale of the component.
- *
- * <p>
- * If a component does not have a locale set, the locale of its parent is
- * returned, and so on. Eventually, if no parent has locale set, the locale
- * of the application is returned. If the application does not have a locale
- * set, it is determined by <code>Locale.getDefault()</code>.
- * </p>
- *
- * <p>
- * As the component must be attached before its locale can be acquired,
- * using this method in the internationalization of component captions, etc.
- * is generally not feasible. For such use case, we recommend using an
- * otherwise acquired reference to the application locale.
- * </p>
- *
- * @return Locale of this component or {@code null} if the component and
- * none of its parents has a locale set and the component is not yet
- * attached to an application.
- */
- public Locale getLocale();
-
- /**
- * Returns the current shared state bean for the component. The state (or
- * changes to it) is communicated from the server to the client.
- *
- * Subclasses can use a more specific return type for this method.
- *
- * @return The state object for the component
- *
- * @since 7.0
- */
- @Override
- public ComponentState getState();
-
- /**
- * Called before the shared state is sent to the client. Gives the component
- * an opportunity to set computed/dynamic state values e.g. state values
- * that depend on other component features.
- * <p>
- * This method must not alter the component hierarchy in any way.
- * </p>
- *
- * @since 7.0
- */
- public void updateState();
-
- /**
- * Adds an unique id for component that get's transferred to terminal for
- * testing purposes. Keeping identifiers unique is the responsibility of the
- * programmer.
- *
- * @param id
- * An alphanumeric id
- */
- public void setDebugId(String id);
-
- /**
- * Get's currently set debug identifier
- *
- * @return current debug id, null if not set
- */
- public String getDebugId();
-
- /* Component event framework */
-
- /**
- * Superclass of all component originated events.
- *
- * <p>
- * Events are the basis of all user interaction handling in Vaadin. To
- * handle events, you provide a listener object that receives the events of
- * the particular event type.
- * </p>
- *
- * <pre>
- * Button button = new Button(&quot;Click Me!&quot;);
- * button.addListener(new Button.ClickListener() {
- * public void buttonClick(ClickEvent event) {
- * getWindow().showNotification(&quot;Thank You!&quot;);
- * }
- * });
- * layout.addComponent(button);
- * </pre>
- *
- * <p>
- * Notice that while each of the event types have their corresponding
- * listener types; the listener interfaces are not required to inherit the
- * {@code Component.Listener} interface.
- * </p>
- *
- * @see Component.Listener
- */
- @SuppressWarnings("serial")
- public class Event extends EventObject {
-
- /**
- * Constructs a new event with the specified source component.
- *
- * @param source
- * the source component of the event
- */
- public Event(Component source) {
- super(source);
- }
-
- /**
- * Gets the component where the event occurred.
- *
- * @return the source component of the event
- */
- public Component getComponent() {
- return (Component) getSource();
- }
- }
-
- /**
- * Listener interface for receiving <code>Component.Event</code>s.
- *
- * <p>
- * Listener interfaces are the basis of all user interaction handling in
- * Vaadin. You have or create a listener object that receives the events.
- * All event types have their corresponding listener types; they are not,
- * however, required to inherit the {@code Component.Listener} interface,
- * and they rarely do so.
- * </p>
- *
- * <p>
- * This generic listener interface is useful typically when you wish to
- * handle events from different component types in a single listener method
- * ({@code componentEvent()}. If you handle component events in an anonymous
- * listener class, you normally use the component specific listener class,
- * such as {@link com.vaadin.ui.Button.ClickEvent}.
- * </p>
- *
- * <pre>
- * class Listening extends CustomComponent implements Listener {
- * Button ok; // Stored for determining the source of an event
- *
- * Label status; // For displaying info about the event
- *
- * public Listening() {
- * VerticalLayout layout = new VerticalLayout();
- *
- * // Some miscellaneous component
- * TextField name = new TextField(&quot;Say it all here&quot;);
- * name.addListener(this);
- * name.setImmediate(true);
- * layout.addComponent(name);
- *
- * // Handle button clicks as generic events instead
- * // of Button.ClickEvent events
- * ok = new Button(&quot;OK&quot;);
- * ok.addListener(this);
- * layout.addComponent(ok);
- *
- * // For displaying information about an event
- * status = new Label(&quot;&quot;);
- * layout.addComponent(status);
- *
- * setCompositionRoot(layout);
- * }
- *
- * public void componentEvent(Event event) {
- * // Act according to the source of the event
- * if (event.getSource() == ok
- * &amp;&amp; event.getClass() == Button.ClickEvent.class)
- * getWindow().showNotification(&quot;Click!&quot;);
- *
- * // Display source component and event class names
- * status.setValue(&quot;Event from &quot; + event.getSource().getClass().getName()
- * + &quot;: &quot; + event.getClass().getName());
- * }
- * }
- *
- * Listening listening = new Listening();
- * layout.addComponent(listening);
- * </pre>
- *
- * @see Component#addListener(Listener)
- */
- public interface Listener extends EventListener, Serializable {
-
- /**
- * Notifies the listener of a component event.
- *
- * <p>
- * As the event can typically come from one of many source components,
- * you may need to differentiate between the event source by component
- * reference, class, etc.
- * </p>
- *
- * <pre>
- * public void componentEvent(Event event) {
- * // Act according to the source of the event
- * if (event.getSource() == ok &amp;&amp; event.getClass() == Button.ClickEvent.class)
- * getWindow().showNotification(&quot;Click!&quot;);
- *
- * // Display source component and event class names
- * status.setValue(&quot;Event from &quot; + event.getSource().getClass().getName()
- * + &quot;: &quot; + event.getClass().getName());
- * }
- * </pre>
- *
- * @param event
- * the event that has occured.
- */
- public void componentEvent(Component.Event event);
- }
-
- /**
- * Registers a new (generic) component event listener for the component.
- *
- * <pre>
- * class Listening extends CustomComponent implements Listener {
- * // Stored for determining the source of an event
- * Button ok;
- *
- * Label status; // For displaying info about the event
- *
- * public Listening() {
- * VerticalLayout layout = new VerticalLayout();
- *
- * // Some miscellaneous component
- * TextField name = new TextField(&quot;Say it all here&quot;);
- * name.addListener(this);
- * name.setImmediate(true);
- * layout.addComponent(name);
- *
- * // Handle button clicks as generic events instead
- * // of Button.ClickEvent events
- * ok = new Button(&quot;OK&quot;);
- * ok.addListener(this);
- * layout.addComponent(ok);
- *
- * // For displaying information about an event
- * status = new Label(&quot;&quot;);
- * layout.addComponent(status);
- *
- * setCompositionRoot(layout);
- * }
- *
- * public void componentEvent(Event event) {
- * // Act according to the source of the event
- * if (event.getSource() == ok)
- * getWindow().showNotification(&quot;Click!&quot;);
- *
- * status.setValue(&quot;Event from &quot; + event.getSource().getClass().getName()
- * + &quot;: &quot; + event.getClass().getName());
- * }
- * }
- *
- * Listening listening = new Listening();
- * layout.addComponent(listening);
- * </pre>
- *
- * @param listener
- * the new Listener to be registered.
- * @see Component.Event
- * @see #removeListener(Listener)
- */
- public void addListener(Component.Listener listener);
-
- /**
- * Removes a previously registered component event listener from this
- * component.
- *
- * @param listener
- * the listener to be removed.
- * @see #addListener(Listener)
- */
- public void removeListener(Component.Listener listener);
-
- /**
- * Class of all component originated error events.
- *
- * <p>
- * The component error event is normally fired by
- * {@link AbstractComponent#setComponentError(ErrorMessage)}. The component
- * errors are set by the framework in some situations and can be set by user
- * code. They are indicated in a component with an error indicator.
- * </p>
- */
- @SuppressWarnings("serial")
- public class ErrorEvent extends Event {
-
- private final ErrorMessage message;
-
- /**
- * Constructs a new event with a specified source component.
- *
- * @param message
- * the error message.
- * @param component
- * the source component.
- */
- public ErrorEvent(ErrorMessage message, Component component) {
- super(component);
- this.message = message;
- }
-
- /**
- * Gets the error message.
- *
- * @return the error message.
- */
- public ErrorMessage getErrorMessage() {
- return message;
- }
- }
-
- /**
- * Listener interface for receiving <code>Component.Errors</code>s.
- */
- public interface ErrorListener extends EventListener, Serializable {
-
- /**
- * Notifies the listener of a component error.
- *
- * @param event
- * the event that has occured.
- */
- public void componentError(Component.ErrorEvent event);
- }
-
- /**
- * A sub-interface implemented by components that can obtain input focus.
- * This includes all {@link Field} components as well as some other
- * components, such as {@link Upload}.
- *
- * <p>
- * Focus can be set with {@link #focus()}. This interface does not provide
- * an accessor that would allow finding out the currently focused component;
- * focus information can be acquired for some (but not all) {@link Field}
- * components through the {@link com.vaadin.event.FieldEvents.FocusListener}
- * and {@link com.vaadin.event.FieldEvents.BlurListener} interfaces.
- * </p>
- *
- * @see FieldEvents
- */
- public interface Focusable extends Component {
-
- /**
- * Sets the focus to this component.
- *
- * <pre>
- * Form loginBox = new Form();
- * loginBox.setCaption(&quot;Login&quot;);
- * layout.addComponent(loginBox);
- *
- * // Create the first field which will be focused
- * TextField username = new TextField(&quot;User name&quot;);
- * loginBox.addField(&quot;username&quot;, username);
- *
- * // Set focus to the user name
- * username.focus();
- *
- * TextField password = new TextField(&quot;Password&quot;);
- * loginBox.addField(&quot;password&quot;, password);
- *
- * Button login = new Button(&quot;Login&quot;);
- * loginBox.getFooter().addComponent(login);
- * </pre>
- *
- * <p>
- * Notice that this interface does not provide an accessor that would
- * allow finding out the currently focused component. Focus information
- * can be acquired for some (but not all) {@link Field} components
- * through the {@link com.vaadin.event.FieldEvents.FocusListener} and
- * {@link com.vaadin.event.FieldEvents.BlurListener} interfaces.
- * </p>
- *
- * @see com.vaadin.event.FieldEvents
- * @see com.vaadin.event.FieldEvents.FocusEvent
- * @see com.vaadin.event.FieldEvents.FocusListener
- * @see com.vaadin.event.FieldEvents.BlurEvent
- * @see com.vaadin.event.FieldEvents.BlurListener
- */
- public void focus();
-
- /**
- * Gets the <i>tabulator index</i> of the {@code Focusable} component.
- *
- * @return tab index set for the {@code Focusable} component
- * @see #setTabIndex(int)
- */
- public int getTabIndex();
-
- /**
- * Sets the <i>tabulator index</i> of the {@code Focusable} component.
- * The tab index property is used to specify the order in which the
- * fields are focused when the user presses the Tab key. Components with
- * a defined tab index are focused sequentially first, and then the
- * components with no tab index.
- *
- * <pre>
- * Form loginBox = new Form();
- * loginBox.setCaption(&quot;Login&quot;);
- * layout.addComponent(loginBox);
- *
- * // Create the first field which will be focused
- * TextField username = new TextField(&quot;User name&quot;);
- * loginBox.addField(&quot;username&quot;, username);
- *
- * // Set focus to the user name
- * username.focus();
- *
- * TextField password = new TextField(&quot;Password&quot;);
- * loginBox.addField(&quot;password&quot;, password);
- *
- * Button login = new Button(&quot;Login&quot;);
- * loginBox.getFooter().addComponent(login);
- *
- * // An additional component which natural focus order would
- * // be after the button.
- * CheckBox remember = new CheckBox(&quot;Remember me&quot;);
- * loginBox.getFooter().addComponent(remember);
- *
- * username.setTabIndex(1);
- * password.setTabIndex(2);
- * remember.setTabIndex(3); // Different than natural place
- * login.setTabIndex(4);
- * </pre>
- *
- * <p>
- * After all focusable user interface components are done, the browser
- * can begin again from the component with the smallest tab index, or it
- * can take the focus out of the page, for example, to the location bar.
- * </p>
- *
- * <p>
- * If the tab index is not set (is set to zero), the default tab order
- * is used. The order is somewhat browser-dependent, but generally
- * follows the HTML structure of the page.
- * </p>
- *
- * <p>
- * A negative value means that the component is completely removed from
- * the tabulation order and can not be reached by pressing the Tab key
- * at all.
- * </p>
- *
- * @param tabIndex
- * the tab order of this component. Indexes usually start
- * from 1. Zero means that default tab order should be used.
- * A negative value means that the field should not be
- * included in the tabbing sequence.
- * @see #getTabIndex()
- */
- public void setTabIndex(int tabIndex);
-
- }
-
-}
diff --git a/src/com/vaadin/ui/ComponentContainer.java b/src/com/vaadin/ui/ComponentContainer.java
deleted file mode 100644
index 8182d54b56..0000000000
--- a/src/com/vaadin/ui/ComponentContainer.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-/**
- * Extension to the {@link Component} interface which adds to it the capacity to
- * contain other components. All UI elements that can have child elements
- * implement this interface.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface ComponentContainer extends HasComponents {
-
- /**
- * Adds the component into this container.
- *
- * @param c
- * the component to be added.
- */
- public void addComponent(Component c);
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
- public void removeComponent(Component c);
-
- /**
- * Removes all components from this container.
- */
- public void removeAllComponents();
-
- /**
- * Replaces the component in the container with another one without changing
- * position.
- *
- * <p>
- * This method replaces component with another one is such way that the new
- * component overtakes the position of the old component. If the old
- * component is not in the container, the new component is added to the
- * container. If the both component are already in the container, their
- * positions are swapped. Component attach and detach events should be taken
- * care as with add and remove.
- * </p>
- *
- * @param oldComponent
- * the old component that will be replaced.
- * @param newComponent
- * the new component to be replaced.
- */
- public void replaceComponent(Component oldComponent, Component newComponent);
-
- /**
- * Gets the number of children this {@link ComponentContainer} has. This
- * must be symmetric with what {@link #getComponentIterator()} returns.
- *
- * @return The number of child components this container has.
- * @since 7.0.0
- */
- public int getComponentCount();
-
- /**
- * Moves all components from an another container into this container. The
- * components are removed from <code>source</code>.
- *
- * @param source
- * the container which contains the components that are to be
- * moved to this container.
- */
- public void moveComponentsFrom(ComponentContainer source);
-
- /**
- * Listens the component attach events.
- *
- * @param listener
- * the listener to add.
- */
- public void addListener(ComponentAttachListener listener);
-
- /**
- * Stops the listening component attach events.
- *
- * @param listener
- * the listener to removed.
- */
- public void removeListener(ComponentAttachListener listener);
-
- /**
- * Listens the component detach events.
- */
- public void addListener(ComponentDetachListener listener);
-
- /**
- * Stops the listening component detach events.
- */
- public void removeListener(ComponentDetachListener listener);
-
- /**
- * Component attach listener interface.
- */
- public interface ComponentAttachListener extends Serializable {
-
- /**
- * A new component is attached to container.
- *
- * @param event
- * the component attach event.
- */
- public void componentAttachedToContainer(ComponentAttachEvent event);
- }
-
- /**
- * Component detach listener interface.
- */
- public interface ComponentDetachListener extends Serializable {
-
- /**
- * A component has been detached from container.
- *
- * @param event
- * the component detach event.
- */
- public void componentDetachedFromContainer(ComponentDetachEvent event);
- }
-
- /**
- * Component attach event sent when a component is attached to container.
- */
- @SuppressWarnings("serial")
- public class ComponentAttachEvent extends Component.Event {
-
- private final Component component;
-
- /**
- * Creates a new attach event.
- *
- * @param container
- * the component container the component has been detached
- * to.
- * @param attachedComponent
- * the component that has been attached.
- */
- public ComponentAttachEvent(ComponentContainer container,
- Component attachedComponent) {
- super(container);
- component = attachedComponent;
- }
-
- /**
- * Gets the component container.
- *
- * @param the
- * component container.
- */
- public ComponentContainer getContainer() {
- return (ComponentContainer) getSource();
- }
-
- /**
- * Gets the attached component.
- *
- * @param the
- * attach component.
- */
- public Component getAttachedComponent() {
- return component;
- }
- }
-
- /**
- * Component detach event sent when a component is detached from container.
- */
- @SuppressWarnings("serial")
- public class ComponentDetachEvent extends Component.Event {
-
- private final Component component;
-
- /**
- * Creates a new detach event.
- *
- * @param container
- * the component container the component has been detached
- * from.
- * @param detachedComponent
- * the component that has been detached.
- */
- public ComponentDetachEvent(ComponentContainer container,
- Component detachedComponent) {
- super(container);
- component = detachedComponent;
- }
-
- /**
- * Gets the component container.
- *
- * @param the
- * component container.
- */
- public ComponentContainer getContainer() {
- return (ComponentContainer) getSource();
- }
-
- /**
- * Gets the detached component.
- *
- * @return the detached component.
- */
- public Component getDetachedComponent() {
- return component;
- }
- }
-
-}
diff --git a/src/com/vaadin/ui/ConnectorTracker.java b/src/com/vaadin/ui/ConnectorTracker.java
deleted file mode 100644
index e3d1bf86db..0000000000
--- a/src/com/vaadin/ui/ConnectorTracker.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.terminal.AbstractClientConnector;
-import com.vaadin.terminal.gwt.client.ServerConnector;
-import com.vaadin.terminal.gwt.server.ClientConnector;
-
-/**
- * A class which takes care of book keeping of {@link ClientConnector}s for a
- * Root.
- * <p>
- * Provides {@link #getConnector(String)} which can be used to lookup a
- * connector from its id. This is for framework use only and should not be
- * needed in applications.
- * </p>
- * <p>
- * Tracks which {@link ClientConnector}s are dirty so they can be updated to the
- * client when the following response is sent. A connector is dirty when an
- * operation has been performed on it on the server and as a result of this
- * operation new information needs to be sent to its {@link ServerConnector}.
- * </p>
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- *
- */
-public class ConnectorTracker implements Serializable {
-
- private final HashMap<String, ClientConnector> connectorIdToConnector = new HashMap<String, ClientConnector>();
- private Set<ClientConnector> dirtyConnectors = new HashSet<ClientConnector>();
-
- private Root root;
-
- /**
- * Gets a logger for this class
- *
- * @return A logger instance for logging within this class
- *
- */
- public static Logger getLogger() {
- return Logger.getLogger(ConnectorTracker.class.getName());
- }
-
- /**
- * Creates a new ConnectorTracker for the given root. A tracker is always
- * attached to a root and the root cannot be changed during the lifetime of
- * a {@link ConnectorTracker}.
- *
- * @param root
- * The root to attach to. Cannot be null.
- */
- public ConnectorTracker(Root root) {
- this.root = root;
- }
-
- /**
- * Register the given connector.
- * <p>
- * The lookup method {@link #getConnector(String)} only returns registered
- * connectors.
- * </p>
- *
- * @param connector
- * The connector to register.
- */
- public void registerConnector(ClientConnector connector) {
- String connectorId = connector.getConnectorId();
- ClientConnector previouslyRegistered = connectorIdToConnector
- .get(connectorId);
- if (previouslyRegistered == null) {
- connectorIdToConnector.put(connectorId, connector);
- getLogger().fine(
- "Registered " + connector.getClass().getSimpleName() + " ("
- + connectorId + ")");
- } else if (previouslyRegistered != connector) {
- throw new RuntimeException("A connector with id " + connectorId
- + " is already registered!");
- } else {
- getLogger().warning(
- "An already registered connector was registered again: "
- + connector.getClass().getSimpleName() + " ("
- + connectorId + ")");
- }
-
- }
-
- /**
- * Unregister the given connector.
- *
- * <p>
- * The lookup method {@link #getConnector(String)} only returns registered
- * connectors.
- * </p>
- *
- * @param connector
- * The connector to unregister
- */
- public void unregisterConnector(ClientConnector connector) {
- String connectorId = connector.getConnectorId();
- if (!connectorIdToConnector.containsKey(connectorId)) {
- getLogger().warning(
- "Tried to unregister "
- + connector.getClass().getSimpleName() + " ("
- + connectorId + ") which is not registered");
- return;
- }
- if (connectorIdToConnector.get(connectorId) != connector) {
- throw new RuntimeException("The given connector with id "
- + connectorId
- + " is not the one that was registered for that id");
- }
-
- getLogger().fine(
- "Unregistered " + connector.getClass().getSimpleName() + " ("
- + connectorId + ")");
- connectorIdToConnector.remove(connectorId);
- }
-
- /**
- * Gets a connector by its id.
- *
- * @param connectorId
- * The connector id to look for
- * @return The connector with the given id or null if no connector has the
- * given id
- */
- public ClientConnector getConnector(String connectorId) {
- return connectorIdToConnector.get(connectorId);
- }
-
- /**
- * Cleans the connector map from all connectors that are no longer attached
- * to the application. This should only be called by the framework.
- */
- public void cleanConnectorMap() {
- // remove detached components from paintableIdMap so they
- // can be GC'ed
- Iterator<String> iterator = connectorIdToConnector.keySet().iterator();
-
- while (iterator.hasNext()) {
- String connectorId = iterator.next();
- ClientConnector connector = connectorIdToConnector.get(connectorId);
- if (getRootForConnector(connector) != root) {
- // If connector is no longer part of this root,
- // remove it from the map. If it is re-attached to the
- // application at some point it will be re-added through
- // registerConnector(connector)
-
- // This code should never be called as cleanup should take place
- // in detach()
- getLogger()
- .warning(
- "cleanConnectorMap unregistered connector "
- + getConnectorAndParentInfo(connector)
- + "). This should have been done when the connector was detached.");
- iterator.remove();
- }
- }
-
- }
-
- /**
- * Finds the root that the connector is attached to.
- *
- * @param connector
- * The connector to lookup
- * @return The root the connector is attached to or null if it is not
- * attached to any root.
- */
- private Root getRootForConnector(ClientConnector connector) {
- if (connector == null) {
- return null;
- }
- if (connector instanceof Component) {
- return ((Component) connector).getRoot();
- }
-
- return getRootForConnector(connector.getParent());
- }
-
- /**
- * Mark the connector as dirty.
- *
- * @see #getDirtyConnectors()
- *
- * @param connector
- * The connector that should be marked clean.
- */
- public void markDirty(ClientConnector connector) {
- if (getLogger().isLoggable(Level.FINE)) {
- if (!dirtyConnectors.contains(connector)) {
- getLogger().fine(
- getConnectorAndParentInfo(connector) + " "
- + "is now dirty");
- }
- }
-
- dirtyConnectors.add(connector);
- }
-
- /**
- * Mark the connector as clean.
- *
- * @param connector
- * The connector that should be marked clean.
- */
- public void markClean(ClientConnector connector) {
- if (getLogger().isLoggable(Level.FINE)) {
- if (dirtyConnectors.contains(connector)) {
- getLogger().fine(
- getConnectorAndParentInfo(connector) + " "
- + "is no longer dirty");
- }
- }
-
- dirtyConnectors.remove(connector);
- }
-
- /**
- * Returns {@link #getConnectorString(ClientConnector)} for the connector
- * and its parent (if it has a parent).
- *
- * @param connector
- * The connector
- * @return A string describing the connector and its parent
- */
- private String getConnectorAndParentInfo(ClientConnector connector) {
- String message = getConnectorString(connector);
- if (connector.getParent() != null) {
- message += " (parent: " + getConnectorString(connector.getParent())
- + ")";
- }
- return message;
- }
-
- /**
- * Returns a string with the connector name and id. Useful mostly for
- * debugging and logging.
- *
- * @param connector
- * The connector
- * @return A string that describes the connector
- */
- private String getConnectorString(ClientConnector connector) {
- if (connector == null) {
- return "(null)";
- }
-
- String connectorId;
- try {
- connectorId = connector.getConnectorId();
- } catch (RuntimeException e) {
- // This happens if the connector is not attached to the application.
- // SHOULD not happen in this case but theoretically can.
- connectorId = "@" + Integer.toHexString(connector.hashCode());
- }
- return connector.getClass().getName() + "(" + connectorId + ")";
- }
-
- /**
- * Mark all connectors in this root as dirty.
- */
- public void markAllConnectorsDirty() {
- markConnectorsDirtyRecursively(root);
- getLogger().fine("All connectors are now dirty");
- }
-
- /**
- * Mark all connectors in this root as clean.
- */
- public void markAllConnectorsClean() {
- dirtyConnectors.clear();
- getLogger().fine("All connectors are now clean");
- }
-
- /**
- * Marks all visible connectors dirty, starting from the given connector and
- * going downwards in the hierarchy.
- *
- * @param c
- * The component to start iterating downwards from
- */
- private void markConnectorsDirtyRecursively(ClientConnector c) {
- if (c instanceof Component && !((Component) c).isVisible()) {
- return;
- }
- markDirty(c);
- for (ClientConnector child : AbstractClientConnector
- .getAllChildrenIterable(c)) {
- markConnectorsDirtyRecursively(child);
- }
- }
-
- /**
- * Returns a collection of all connectors which have been marked as dirty.
- * <p>
- * The state and pending RPC calls for dirty connectors are sent to the
- * client in the following request.
- * </p>
- *
- * @return A collection of all dirty connectors for this root. This list may
- * contain invisible connectors.
- */
- public Collection<ClientConnector> getDirtyConnectors() {
- return dirtyConnectors;
- }
-
-}
diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java
deleted file mode 100644
index 356f0a3843..0000000000
--- a/src/com/vaadin/ui/CssLayout.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import com.vaadin.event.LayoutEvents.LayoutClickEvent;
-import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.csslayout.CssLayoutServerRpc;
-import com.vaadin.shared.ui.csslayout.CssLayoutState;
-import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
-
-/**
- * CssLayout is a layout component that can be used in browser environment only.
- * It simply renders components and their captions into a same div element.
- * Component layout can then be adjusted with css.
- * <p>
- * In comparison to {@link HorizontalLayout} and {@link VerticalLayout}
- * <ul>
- * <li>rather similar server side api
- * <li>no spacing, alignment or expand ratios
- * <li>much simpler DOM that can be styled by skilled web developer
- * <li>no abstraction of browser differences (developer must ensure that the
- * result works properly on each browser)
- * <li>different kind of handling for relative sizes (that are set from server
- * side) (*)
- * <li>noticeably faster rendering time in some situations as we rely more on
- * the browser's rendering engine.
- * </ul>
- * <p>
- * With {@link CustomLayout} one can often achieve similar results (good looking
- * layouts with web technologies), but with CustomLayout developer needs to work
- * with fixed templates.
- * <p>
- * By extending CssLayout one can also inject some css rules straight to child
- * components using {@link #getCss(Component)}.
- *
- * <p>
- * (*) Relative sizes (set from server side) are treated bit differently than in
- * other layouts in Vaadin. In cssLayout the size is calculated relatively to
- * CSS layouts content area which is pretty much as in html and css. In other
- * layouts the size of component is calculated relatively to the "slot" given by
- * layout.
- * <p>
- * Also note that client side framework in Vaadin modifies inline style
- * properties width and height. This happens on each update to component. If one
- * wants to set component sizes with CSS, component must have undefined size on
- * server side (which is not the default for all components) and the size must
- * be defined with class styles - not by directly injecting width and height.
- *
- * @since 6.1 brought in from "FastLayouts" incubator project
- *
- */
-public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
-
- private CssLayoutServerRpc rpc = new CssLayoutServerRpc() {
-
- @Override
- public void layoutClick(MouseEventDetails mouseDetails,
- Connector clickedConnector) {
- fireEvent(LayoutClickEvent.createEvent(CssLayout.this,
- mouseDetails, clickedConnector));
- }
- };
- /**
- * Custom layout slots containing the components.
- */
- protected LinkedList<Component> components = new LinkedList<Component>();
-
- public CssLayout() {
- registerRpc(rpc);
- }
-
- /**
- * Add a component into this container. The component is added to the right
- * or under the previous component.
- *
- * @param c
- * the component to be added.
- */
- @Override
- public void addComponent(Component c) {
- // Add to components before calling super.addComponent
- // so that it is available to AttachListeners
- components.add(c);
- try {
- super.addComponent(c);
- requestRepaint();
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
- }
-
- /**
- * Adds a component into this container. The component is added to the left
- * or on top of the other components.
- *
- * @param c
- * the component to be added.
- */
- public void addComponentAsFirst(Component c) {
- // If c is already in this, we must remove it before proceeding
- // see ticket #7668
- if (c.getParent() == this) {
- removeComponent(c);
- }
- components.addFirst(c);
- try {
- super.addComponent(c);
- requestRepaint();
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
- }
-
- /**
- * Adds a component into indexed position in this container.
- *
- * @param c
- * the component to be added.
- * @param index
- * the index of the component position. The components currently
- * in and after the position are shifted forwards.
- */
- public void addComponent(Component c, int index) {
- // If c is already in this, we must remove it before proceeding
- // see ticket #7668
- if (c.getParent() == this) {
- // When c is removed, all components after it are shifted down
- if (index > getComponentIndex(c)) {
- index--;
- }
- removeComponent(c);
- }
- components.add(index, c);
- try {
- super.addComponent(c);
- requestRepaint();
- } catch (IllegalArgumentException e) {
- components.remove(c);
- throw e;
- }
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
- @Override
- public void removeComponent(Component c) {
- components.remove(c);
- super.removeComponent(c);
- requestRepaint();
- }
-
- /**
- * Gets the component container iterator for going trough all the components
- * in the container.
- *
- * @return the Iterator of the components inside the container.
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return components.iterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
- @Override
- public int getComponentCount() {
- return components.size();
- }
-
- @Override
- public void updateState() {
- super.updateState();
- getState().getChildCss().clear();
- for (Iterator<Component> ci = getComponentIterator(); ci.hasNext();) {
- Component child = ci.next();
- String componentCssString = getCss(child);
- if (componentCssString != null) {
- getState().getChildCss().put(child, componentCssString);
- }
-
- }
- }
-
- @Override
- public CssLayoutState getState() {
- return (CssLayoutState) super.getState();
- }
-
- /**
- * Returns styles to be applied to given component. Override this method to
- * inject custom style rules to components.
- *
- * <p>
- * Note that styles are injected over previous styles before actual child
- * rendering. Previous styles are not cleared, but overridden.
- *
- * <p>
- * Note that one most often achieves better code style, by separating
- * styling to theme (with custom theme and {@link #addStyleName(String)}.
- * With own custom styles it is also very easy to break browser
- * compatibility.
- *
- * @param c
- * the component
- * @return css rules to be applied to component
- */
- protected String getCss(Component c) {
- return null;
- }
-
- /* Documented in superclass */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- // Gets the locations
- int oldLocation = -1;
- int newLocation = -1;
- int location = 0;
- for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
- final Component component = i.next();
-
- if (component == oldComponent) {
- oldLocation = location;
- }
- if (component == newComponent) {
- newLocation = location;
- }
-
- location++;
- }
-
- if (oldLocation == -1) {
- addComponent(newComponent);
- } else if (newLocation == -1) {
- removeComponent(oldComponent);
- addComponent(newComponent, oldLocation);
- } else {
- if (oldLocation > newLocation) {
- components.remove(oldComponent);
- components.add(newLocation, oldComponent);
- components.remove(newComponent);
- components.add(oldLocation, newComponent);
- } else {
- components.remove(newComponent);
- components.add(oldLocation, newComponent);
- components.remove(oldComponent);
- components.add(newLocation, oldComponent);
- }
-
- requestRepaint();
- }
- }
-
- @Override
- public void addListener(LayoutClickListener listener) {
- addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener,
- LayoutClickListener.clickMethod);
- }
-
- @Override
- public void removeListener(LayoutClickListener listener) {
- removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener);
- }
-
- /**
- * Returns the index of the given component.
- *
- * @param component
- * The component to look up.
- * @return The index of the component or -1 if the component is not a child.
- */
- public int getComponentIndex(Component component) {
- return components.indexOf(component);
- }
-
- /**
- * Returns the component at the given position.
- *
- * @param index
- * The position of the component.
- * @return The component at the given index.
- * @throws IndexOutOfBoundsException
- * If the index is out of range.
- */
- public Component getComponent(int index) throws IndexOutOfBoundsException {
- return components.get(index);
- }
-
-}
diff --git a/src/com/vaadin/ui/CustomComponent.java b/src/com/vaadin/ui/CustomComponent.java
deleted file mode 100644
index 40b5dcd636..0000000000
--- a/src/com/vaadin/ui/CustomComponent.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.Iterator;
-
-/**
- * Custom component provides simple implementation of Component interface for
- * creation of new UI components by composition of existing components.
- * <p>
- * The component is used by inheriting the CustomComponent class and setting
- * composite root inside the Custom component. The composite root itself can
- * contain more components, but their interfaces are hidden from the users.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class CustomComponent extends AbstractComponentContainer {
-
- /**
- * The root component implementing the custom component.
- */
- private Component root = null;
-
- /**
- * Constructs a new custom component.
- *
- * <p>
- * The component is implemented by wrapping the methods of the composition
- * root component given as parameter. The composition root must be set
- * before the component can be used.
- * </p>
- */
- public CustomComponent() {
- // expand horizontally by default
- setWidth(100, UNITS_PERCENTAGE);
- }
-
- /**
- * Constructs a new custom component.
- *
- * <p>
- * The component is implemented by wrapping the methods of the composition
- * root component given as parameter. The composition root must not be null
- * and can not be changed after the composition.
- * </p>
- *
- * @param compositionRoot
- * the root of the composition component tree.
- */
- public CustomComponent(Component compositionRoot) {
- this();
- setCompositionRoot(compositionRoot);
- }
-
- /**
- * Returns the composition root.
- *
- * @return the Component Composition root.
- */
- protected Component getCompositionRoot() {
- return root;
- }
-
- /**
- * Sets the compositions root.
- * <p>
- * The composition root must be set to non-null value before the component
- * can be used. The composition root can only be set once.
- * </p>
- *
- * @param compositionRoot
- * the root of the composition component tree.
- */
- protected void setCompositionRoot(Component compositionRoot) {
- if (compositionRoot != root) {
- if (root != null) {
- // remove old component
- super.removeComponent(root);
- }
- if (compositionRoot != null) {
- // set new component
- super.addComponent(compositionRoot);
- }
- root = compositionRoot;
- requestRepaint();
- }
- }
-
- /* Basic component features ------------------------------------------ */
-
- private class ComponentIterator implements Iterator<Component>,
- Serializable {
- boolean first = getCompositionRoot() != null;
-
- @Override
- public boolean hasNext() {
- return first;
- }
-
- @Override
- public Component next() {
- first = false;
- return root;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- @Override
- public Iterator<Component> getComponentIterator() {
- return new ComponentIterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components (zero or one)
- */
- @Override
- public int getComponentCount() {
- return (root != null ? 1 : 0);
- }
-
- /**
- * This method is not supported by CustomComponent.
- *
- * @see com.vaadin.ui.ComponentContainer#replaceComponent(com.vaadin.ui.Component,
- * com.vaadin.ui.Component)
- */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * This method is not supported by CustomComponent. Use
- * {@link CustomComponent#setCompositionRoot(Component)} to set
- * CustomComponents "child".
- *
- * @see com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component)
- */
- @Override
- public void addComponent(Component c) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * This method is not supported by CustomComponent.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#moveComponentsFrom(com.vaadin.ui.ComponentContainer)
- */
- @Override
- public void moveComponentsFrom(ComponentContainer source) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * This method is not supported by CustomComponent.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#removeAllComponents()
- */
- @Override
- public void removeAllComponents() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * This method is not supported by CustomComponent.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui.Component)
- */
- @Override
- public void removeComponent(Component c) {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/src/com/vaadin/ui/CustomField.java b/src/com/vaadin/ui/CustomField.java
deleted file mode 100644
index ab3797a58c..0000000000
--- a/src/com/vaadin/ui/CustomField.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Iterator;
-
-import com.vaadin.data.Property;
-
-/**
- * A {@link Field} whose UI content can be constructed by the user, enabling the
- * creation of e.g. form fields by composing Vaadin components. Customization of
- * both the visual presentation and the logic of the field is possible.
- *
- * Subclasses must implement {@link #getType()} and {@link #initContent()}.
- *
- * Most custom fields can simply compose a user interface that calls the methods
- * {@link #setInternalValue(Object)} and {@link #getInternalValue()} when
- * necessary.
- *
- * It is also possible to override {@link #validate()},
- * {@link #setInternalValue(Object)}, {@link #commit()},
- * {@link #setPropertyDataSource(Property)}, {@link #isEmpty()} and other logic
- * of the field. Methods overriding {@link #setInternalValue(Object)} should
- * also call the corresponding superclass method.
- *
- * @param <T>
- * field value type
- *
- * @since 7.0
- */
-public abstract class CustomField<T> extends AbstractField<T> implements
- ComponentContainer {
-
- /**
- * The root component implementing the custom component.
- */
- private Component root = null;
-
- /**
- * Constructs a new custom field.
- *
- * <p>
- * The component is implemented by wrapping the methods of the composition
- * root component given as parameter. The composition root must be set
- * before the component can be used.
- * </p>
- */
- public CustomField() {
- // expand horizontally by default
- setWidth(100, Unit.PERCENTAGE);
- }
-
- /**
- * Constructs the content and notifies it that the {@link CustomField} is
- * attached to a window.
- *
- * @see com.vaadin.ui.Component#attach()
- */
- @Override
- public void attach() {
- // First call super attach to notify all children (none if content has
- // not yet been created)
- super.attach();
-
- // If the content has not yet been created, we create and attach it at
- // this point.
- if (root == null) {
- // Ensure content is created and its parent is set.
- // The getContent() call creates the content and attaches the
- // content
- fireComponentAttachEvent(getContent());
- }
- }
-
- /**
- * Returns the content (UI) of the custom component.
- *
- * @return Component
- */
- protected Component getContent() {
- if (null == root) {
- root = initContent();
- root.setParent(this);
- }
- return root;
- }
-
- /**
- * Create the content component or layout for the field. Subclasses of
- * {@link CustomField} should implement this method.
- *
- * Note that this method is called when the CustomField is attached to a
- * layout or when {@link #getContent()} is called explicitly for the first
- * time. It is only called once for a {@link CustomField}.
- *
- * @return {@link Component} representing the UI of the CustomField
- */
- protected abstract Component initContent();
-
- // Size related methods
- // TODO might not be necessary to override but following the pattern from
- // AbstractComponentContainer
-
- @Override
- public void setHeight(float height, Unit unit) {
- super.setHeight(height, unit);
- requestRepaintAll();
- }
-
- @Override
- public void setWidth(float height, Unit unit) {
- super.setWidth(height, unit);
- requestRepaintAll();
- }
-
- // ComponentContainer methods
-
- private class ComponentIterator implements Iterator<Component>,
- Serializable {
- boolean first = (root != null);
-
- @Override
- public boolean hasNext() {
- return first;
- }
-
- @Override
- public Component next() {
- first = false;
- return getContent();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- @Override
- public Iterator<Component> getComponentIterator() {
- return new ComponentIterator();
- }
-
- @Override
- public Iterator<Component> iterator() {
- return getComponentIterator();
- }
-
- @Override
- public int getComponentCount() {
- return (null != getContent()) ? 1 : 0;
- }
-
- /**
- * Fires the component attached event. This should be called by the
- * addComponent methods after the component have been added to this
- * container.
- *
- * @param component
- * the component that has been added to this container.
- */
- protected void fireComponentAttachEvent(Component component) {
- fireEvent(new ComponentAttachEvent(this, component));
- }
-
- // TODO remove these methods when ComponentContainer interface is cleaned up
-
- @Override
- public void addComponent(Component c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeComponent(Component c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeAllComponents() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void moveComponentsFrom(ComponentContainer source) {
- throw new UnsupportedOperationException();
- }
-
- private static final Method COMPONENT_ATTACHED_METHOD;
-
- static {
- try {
- COMPONENT_ATTACHED_METHOD = ComponentAttachListener.class
- .getDeclaredMethod("componentAttachedToContainer",
- new Class[] { ComponentAttachEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in CustomField");
- }
- }
-
- @Override
- public void addListener(ComponentAttachListener listener) {
- addListener(ComponentContainer.ComponentAttachEvent.class, listener,
- COMPONENT_ATTACHED_METHOD);
- }
-
- @Override
- public void removeListener(ComponentAttachListener listener) {
- removeListener(ComponentContainer.ComponentAttachEvent.class, listener,
- COMPONENT_ATTACHED_METHOD);
- }
-
- @Override
- public void addListener(ComponentDetachListener listener) {
- // content never detached
- }
-
- @Override
- public void removeListener(ComponentDetachListener listener) {
- // content never detached
- }
-
- @Override
- public boolean isComponentVisible(Component childComponent) {
- return true;
- }
-}
diff --git a/src/com/vaadin/ui/CustomLayout.java b/src/com/vaadin/ui/CustomLayout.java
deleted file mode 100644
index d7830603f0..0000000000
--- a/src/com/vaadin/ui/CustomLayout.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import com.vaadin.shared.ui.customlayout.CustomLayoutState;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.server.JsonPaintTarget;
-
-/**
- * <p>
- * A container component with freely designed layout and style. The layout
- * consists of items with textually represented locations. Each item contains
- * one sub-component, which can be any Vaadin component, such as a layout. The
- * adapter and theme are responsible for rendering the layout with a given style
- * by placing the items in the defined locations.
- * </p>
- *
- * <p>
- * The placement of the locations is not fixed - different themes can define the
- * locations in a way that is suitable for them. One typical example would be to
- * create visual design for a web site as a custom layout: the visual design
- * would define locations for "menu", "body", and "title", for example. The
- * layout would then be implemented as an XHTML template for each theme.
- * </p>
- *
- * <p>
- * The default theme handles the styles that are not defined by drawing the
- * subcomponents just as in OrderedLayout.
- * </p>
- *
- * @author Vaadin Ltd.
- * @author Duy B. Vo (<a
- * href="mailto:devduy@gmail.com?subject=Vaadin">devduy@gmail.com</a>)
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class CustomLayout extends AbstractLayout implements Vaadin6Component {
-
- private static final int BUFFER_SIZE = 10000;
-
- /**
- * Custom layout slots containing the components.
- */
- private final HashMap<String, Component> slots = new HashMap<String, Component>();
-
- /**
- * Default constructor only used by subclasses. Subclasses are responsible
- * for setting the appropriate fields. Either
- * {@link #setTemplateName(String)}, that makes layout fetch the template
- * from theme, or {@link #setTemplateContents(String)}.
- */
- protected CustomLayout() {
- setWidth(100, UNITS_PERCENTAGE);
- }
-
- /**
- * Constructs a custom layout with the template given in the stream.
- *
- * @param templateStream
- * Stream containing template data. Must be using UTF-8 encoding.
- * To use a String as a template use for instance new
- * ByteArrayInputStream("<template>".getBytes()).
- * @param streamLength
- * Length of the templateStream
- * @throws IOException
- */
- public CustomLayout(InputStream templateStream) throws IOException {
- this();
- initTemplateContentsFromInputStream(templateStream);
- }
-
- /**
- * Constructor for custom layout with given template name. Template file is
- * fetched from "<theme>/layout/<templateName>".
- */
- public CustomLayout(String template) {
- this();
- setTemplateName(template);
- }
-
- protected void initTemplateContentsFromInputStream(
- InputStream templateStream) throws IOException {
- InputStreamReader reader = new InputStreamReader(templateStream,
- "UTF-8");
- StringBuilder b = new StringBuilder(BUFFER_SIZE);
-
- char[] cbuf = new char[BUFFER_SIZE];
- int offset = 0;
-
- while (true) {
- int nrRead = reader.read(cbuf, offset, BUFFER_SIZE);
- b.append(cbuf, 0, nrRead);
- if (nrRead < BUFFER_SIZE) {
- break;
- }
- }
-
- setTemplateContents(b.toString());
- }
-
- @Override
- public CustomLayoutState getState() {
- return (CustomLayoutState) super.getState();
- }
-
- /**
- * Adds the component into this container to given location. If the location
- * is already populated, the old component is removed.
- *
- * @param c
- * the component to be added.
- * @param location
- * the location of the component.
- */
- public void addComponent(Component c, String location) {
- final Component old = slots.get(location);
- if (old != null) {
- removeComponent(old);
- }
- slots.put(location, c);
- getState().getChildLocations().put(c, location);
- c.setParent(this);
- fireComponentAttachEvent(c);
- requestRepaint();
- }
-
- /**
- * Adds the component into this container. The component is added without
- * specifying the location (empty string is then used as location). Only one
- * component can be added to the default "" location and adding more
- * components into that location overwrites the old components.
- *
- * @param c
- * the component to be added.
- */
- @Override
- public void addComponent(Component c) {
- this.addComponent(c, "");
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * the component to be removed.
- */
- @Override
- public void removeComponent(Component c) {
- if (c == null) {
- return;
- }
- slots.values().remove(c);
- getState().getChildLocations().remove(c);
- super.removeComponent(c);
- requestRepaint();
- }
-
- /**
- * Removes the component from this container from given location.
- *
- * @param location
- * the Location identifier of the component.
- */
- public void removeComponent(String location) {
- this.removeComponent(slots.get(location));
- }
-
- /**
- * Gets the component container iterator for going trough all the components
- * in the container.
- *
- * @return the Iterator of the components inside the container.
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return slots.values().iterator();
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
- @Override
- public int getComponentCount() {
- return slots.values().size();
- }
-
- /**
- * Gets the child-component by its location.
- *
- * @param location
- * the name of the location where the requested component
- * resides.
- * @return the Component in the given location or null if not found.
- */
- public Component getComponent(String location) {
- return slots.get(location);
- }
-
- /* Documented in superclass */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- // Gets the locations
- String oldLocation = null;
- String newLocation = null;
- for (final Iterator<String> i = slots.keySet().iterator(); i.hasNext();) {
- final String location = i.next();
- final Component component = slots.get(location);
- if (component == oldComponent) {
- oldLocation = location;
- }
- if (component == newComponent) {
- newLocation = location;
- }
- }
-
- if (oldLocation == null) {
- addComponent(newComponent);
- } else if (newLocation == null) {
- removeComponent(oldLocation);
- addComponent(newComponent, oldLocation);
- } else {
- slots.put(newLocation, oldComponent);
- slots.put(oldLocation, newComponent);
- getState().getChildLocations().put(newComponent, oldLocation);
- getState().getChildLocations().put(oldComponent, newLocation);
- requestRepaint();
- }
- }
-
- /** Get the name of the template */
- public String getTemplateName() {
- return getState().getTemplateName();
- }
-
- /** Get the contents of the template */
- public String getTemplateContents() {
- return getState().getTemplateContents();
- }
-
- /**
- * Set the name of the template used to draw custom layout.
- *
- * With GWT-adapter, the template with name 'templatename' is loaded from
- * VAADIN/themes/themename/layouts/templatename.html. If the theme has not
- * been set (with Application.setTheme()), themename is 'default'.
- *
- * @param templateName
- */
- public void setTemplateName(String templateName) {
- getState().setTemplateName(templateName);
- getState().setTemplateContents(null);
- requestRepaint();
- }
-
- /**
- * Set the contents of the template used to draw the custom layout.
- *
- * @param templateContents
- */
- public void setTemplateContents(String templateContents) {
- getState().setTemplateContents(templateContents);
- getState().setTemplateName(null);
- requestRepaint();
- }
-
- /**
- * Although most layouts support margins, CustomLayout does not. The
- * behaviour of this layout is determined almost completely by the actual
- * template.
- *
- * @throws UnsupportedOperationException
- */
- @Override
- public void setMargin(boolean enabled) {
- throw new UnsupportedOperationException(
- "CustomLayout does not support margins.");
- }
-
- /**
- * Although most layouts support margins, CustomLayout does not. The
- * behaviour of this layout is determined almost completely by the actual
- * template.
- *
- * @throws UnsupportedOperationException
- */
- @Override
- public void setMargin(boolean topEnabled, boolean rightEnabled,
- boolean bottomEnabled, boolean leftEnabled) {
- throw new UnsupportedOperationException(
- "CustomLayout does not support margins.");
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // Nothing to see here
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- // Workaround to make the CommunicationManager read the template file
- // and send it to the client
- String templateName = getState().getTemplateName();
- if (templateName != null && templateName.length() != 0) {
- Set<Object> usedResources = ((JsonPaintTarget) target)
- .getUsedResources();
- String resourceName = "layouts/" + templateName + ".html";
- usedResources.add(resourceName);
- }
- }
-
-}
diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java
deleted file mode 100644
index d0a22f3c29..0000000000
--- a/src/com/vaadin/ui/DateField.java
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.Validator;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.event.FieldEvents;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.datefield.VDateField;
-
-/**
- * <p>
- * A date editor component that can be bound to any {@link Property} that is
- * compatible with <code>java.util.Date</code>.
- * </p>
- * <p>
- * Since <code>DateField</code> extends <code>AbstractField</code> it implements
- * the {@link com.vaadin.data.Buffered}interface.
- * </p>
- * <p>
- * A <code>DateField</code> is in write-through mode by default, so
- * {@link com.vaadin.ui.AbstractField#setWriteThrough(boolean)}must be called to
- * enable buffering.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class DateField extends AbstractField<Date> implements
- FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, Vaadin6Component {
-
- /**
- * Resolutions for DateFields
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 7.0
- */
- public enum Resolution {
- SECOND(Calendar.SECOND), MINUTE(Calendar.MINUTE), HOUR(
- Calendar.HOUR_OF_DAY), DAY(Calendar.DAY_OF_MONTH), MONTH(
- Calendar.MONTH), YEAR(Calendar.YEAR);
-
- private int calendarField;
-
- private Resolution(int calendarField) {
- this.calendarField = calendarField;
- }
-
- /**
- * Returns the field in {@link Calendar} that corresponds to this
- * resolution.
- *
- * @return one of the field numbers used by Calendar
- */
- public int getCalendarField() {
- return calendarField;
- }
-
- /**
- * Returns the resolutions that are higher or equal to the given
- * resolution, starting from the given resolution. In other words
- * passing DAY to this methods returns DAY,MONTH,YEAR
- *
- * @param r
- * The resolution to start from
- * @return An iterable for the resolutions higher or equal to r
- */
- public static Iterable<Resolution> getResolutionsHigherOrEqualTo(
- Resolution r) {
- List<Resolution> resolutions = new ArrayList<DateField.Resolution>();
- Resolution[] values = Resolution.values();
- for (int i = r.ordinal(); i < values.length; i++) {
- resolutions.add(values[i]);
- }
- return resolutions;
- }
-
- /**
- * Returns the resolutions that are lower than the given resolution,
- * starting from the given resolution. In other words passing DAY to
- * this methods returns HOUR,MINUTE,SECOND.
- *
- * @param r
- * The resolution to start from
- * @return An iterable for the resolutions lower than r
- */
- public static List<Resolution> getResolutionsLowerThan(Resolution r) {
- List<Resolution> resolutions = new ArrayList<DateField.Resolution>();
- Resolution[] values = Resolution.values();
- for (int i = r.ordinal() - 1; i >= 0; i--) {
- resolutions.add(values[i]);
- }
- return resolutions;
- }
- };
-
- /**
- * Resolution identifier: seconds.
- *
- * @deprecated Use {@link Resolution#SECOND}
- */
- @Deprecated
- public static final Resolution RESOLUTION_SEC = Resolution.SECOND;
-
- /**
- * Resolution identifier: minutes.
- *
- * @deprecated Use {@link Resolution#MINUTE}
- */
- @Deprecated
- public static final Resolution RESOLUTION_MIN = Resolution.MINUTE;
-
- /**
- * Resolution identifier: hours.
- *
- * @deprecated Use {@link Resolution#HOUR}
- */
- @Deprecated
- public static final Resolution RESOLUTION_HOUR = Resolution.HOUR;
-
- /**
- * Resolution identifier: days.
- *
- * @deprecated Use {@link Resolution#DAY}
- */
- @Deprecated
- public static final Resolution RESOLUTION_DAY = Resolution.DAY;
-
- /**
- * Resolution identifier: months.
- *
- * @deprecated Use {@link Resolution#MONTH}
- */
- @Deprecated
- public static final Resolution RESOLUTION_MONTH = Resolution.MONTH;
-
- /**
- * Resolution identifier: years.
- *
- * @deprecated Use {@link Resolution#YEAR}
- */
- @Deprecated
- public static final Resolution RESOLUTION_YEAR = Resolution.YEAR;
-
- /**
- * Specified smallest modifiable unit for the date field.
- */
- private Resolution resolution = Resolution.DAY;
-
- /**
- * The internal calendar to be used in java.utl.Date conversions.
- */
- private transient Calendar calendar;
-
- /**
- * Overridden format string
- */
- private String dateFormat;
-
- private boolean lenient = false;
-
- private String dateString = null;
-
- /**
- * Was the last entered string parsable? If this flag is false, datefields
- * internal validator does not pass.
- */
- private boolean uiHasValidDateString = true;
-
- /**
- * Determines if week numbers are shown in the date selector.
- */
- private boolean showISOWeekNumbers = false;
-
- private String currentParseErrorMessage;
-
- private String defaultParseErrorMessage = "Date format not recognized";
-
- private TimeZone timeZone = null;
-
- private static Map<Resolution, String> variableNameForResolution = new HashMap<DateField.Resolution, String>();
- {
- variableNameForResolution.put(Resolution.SECOND, "sec");
- variableNameForResolution.put(Resolution.MINUTE, "min");
- variableNameForResolution.put(Resolution.HOUR, "hour");
- variableNameForResolution.put(Resolution.DAY, "day");
- variableNameForResolution.put(Resolution.MONTH, "month");
- variableNameForResolution.put(Resolution.YEAR, "year");
- }
-
- /* Constructors */
-
- /**
- * Constructs an empty <code>DateField</code> with no caption.
- */
- public DateField() {
- }
-
- /**
- * Constructs an empty <code>DateField</code> with caption.
- *
- * @param caption
- * the caption of the datefield.
- */
- public DateField(String caption) {
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>DateField</code> that's bound to the specified
- * <code>Property</code> and has the given caption <code>String</code>.
- *
- * @param caption
- * the caption <code>String</code> for the editor.
- * @param dataSource
- * the Property to be edited with this editor.
- */
- public DateField(String caption, Property dataSource) {
- this(dataSource);
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>DateField</code> that's bound to the specified
- * <code>Property</code> and has no caption.
- *
- * @param dataSource
- * the Property to be edited with this editor.
- */
- public DateField(Property dataSource) throws IllegalArgumentException {
- if (!Date.class.isAssignableFrom(dataSource.getType())) {
- throw new IllegalArgumentException("Can't use "
- + dataSource.getType().getName()
- + " typed property as datasource");
- }
-
- setPropertyDataSource(dataSource);
- }
-
- /**
- * Constructs a new <code>DateField</code> with the given caption and
- * initial text contents. The editor constructed this way will not be bound
- * to a Property unless
- * {@link com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)}
- * is called to bind it.
- *
- * @param caption
- * the caption <code>String</code> for the editor.
- * @param value
- * the Date value.
- */
- public DateField(String caption, Date value) {
- setValue(value);
- setCaption(caption);
- }
-
- /* Component basic features */
-
- /*
- * Paints this component. Don't add a JavaDoc comment here, we use the
- * default documentation from implemented interface.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- // Adds the locale as attribute
- final Locale l = getLocale();
- if (l != null) {
- target.addAttribute("locale", l.toString());
- }
-
- if (getDateFormat() != null) {
- target.addAttribute("format", dateFormat);
- }
-
- if (!isLenient()) {
- target.addAttribute("strict", true);
- }
-
- target.addAttribute(VDateField.WEEK_NUMBERS, isShowISOWeekNumbers());
- target.addAttribute("parsable", uiHasValidDateString);
- /*
- * TODO communicate back the invalid date string? E.g. returning back to
- * app or refresh.
- */
-
- // Gets the calendar
- final Calendar calendar = getCalendar();
- final Date currentDate = getValue();
-
- // Only paint variables for the resolution and up, e.g. Resolution DAY
- // paints DAY,MONTH,YEAR
- for (Resolution res : Resolution
- .getResolutionsHigherOrEqualTo(resolution)) {
- int value = -1;
- if (currentDate != null) {
- value = calendar.get(res.getCalendarField());
- if (res == Resolution.MONTH) {
- // Calendar month is zero based
- value++;
- }
- }
- target.addVariable(this, variableNameForResolution.get(res), value);
- }
- }
-
- @Override
- protected boolean shouldHideErrors() {
- return super.shouldHideErrors() && uiHasValidDateString;
- }
-
- /*
- * Invoked when a variable of the component changes. Don't add a JavaDoc
- * comment here, we use the default documentation from implemented
- * interface.
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
-
- if (!isReadOnly()
- && (variables.containsKey("year")
- || variables.containsKey("month")
- || variables.containsKey("day")
- || variables.containsKey("hour")
- || variables.containsKey("min")
- || variables.containsKey("sec")
- || variables.containsKey("msec") || variables
- .containsKey("dateString"))) {
-
- // Old and new dates
- final Date oldDate = getValue();
- Date newDate = null;
-
- // this enables analyzing invalid input on the server
- final String newDateString = (String) variables.get("dateString");
- dateString = newDateString;
-
- // Gets the new date in parts
- boolean hasChanges = false;
- Map<Resolution, Integer> calendarFieldChanges = new HashMap<DateField.Resolution, Integer>();
-
- for (Resolution r : Resolution
- .getResolutionsHigherOrEqualTo(resolution)) {
- // Only handle what the client is allowed to send. The same
- // resolutions that are painted
- String variableName = variableNameForResolution.get(r);
-
- if (variables.containsKey(variableName)) {
- Integer value = (Integer) variables.get(variableName);
- if (r == Resolution.MONTH) {
- // Calendar MONTH is zero based
- value--;
- }
- if (value >= 0) {
- hasChanges = true;
- calendarFieldChanges.put(r, value);
- }
- }
- }
-
- // If no new variable values were received, use the previous value
- if (!hasChanges) {
- newDate = null;
- } else {
- // Clone the calendar for date operation
- final Calendar cal = getCalendar();
-
- // Update the value based on the received info
- // Must set in this order to avoid invalid dates (or wrong
- // dates if lenient is true) in calendar
- for (int r = Resolution.YEAR.ordinal(); r >= 0; r--) {
- Resolution res = Resolution.values()[r];
- if (calendarFieldChanges.containsKey(res)) {
-
- // Field resolution should be included. Others are
- // skipped so that client can not make unexpected
- // changes (e.g. day change even though resolution is
- // year).
- Integer newValue = calendarFieldChanges.get(res);
- cal.set(res.getCalendarField(), newValue);
- }
- }
- newDate = cal.getTime();
- }
-
- if (newDate == null && dateString != null && !"".equals(dateString)) {
- try {
- Date parsedDate = handleUnparsableDateString(dateString);
- setValue(parsedDate, true);
-
- /*
- * Ensure the value is sent to the client if the value is
- * set to the same as the previous (#4304). Does not repaint
- * if handleUnparsableDateString throws an exception. In
- * this case the invalid text remains in the DateField.
- */
- requestRepaint();
- } catch (Converter.ConversionException e) {
-
- /*
- * Datefield now contains some text that could't be parsed
- * into date.
- */
- if (oldDate != null) {
- /*
- * Set the logic value to null.
- */
- setValue(null);
- /*
- * Reset the dateString (overridden to null by setValue)
- */
- dateString = newDateString;
- }
-
- /*
- * Saves the localized message of parse error. This can be
- * overridden in handleUnparsableDateString. The message
- * will later be used to show a validation error.
- */
- currentParseErrorMessage = e.getLocalizedMessage();
-
- /*
- * The value of the DateField should be null if an invalid
- * value has been given. Not using setValue() since we do
- * not want to cause the client side value to change.
- */
- uiHasValidDateString = false;
-
- /*
- * Because of our custom implementation of isValid(), that
- * also checks the parsingSucceeded flag, we must also
- * notify the form (if this is used in one) that the
- * validity of this field has changed.
- *
- * Normally fields validity doesn't change without value
- * change and form depends on this implementation detail.
- */
- notifyFormOfValidityChange();
- requestRepaint();
- }
- } else if (newDate != oldDate
- && (newDate == null || !newDate.equals(oldDate))) {
- setValue(newDate, true); // Don't require a repaint, client
- // updates itself
- } else if (!uiHasValidDateString) { // oldDate ==
- // newDate == null
- // Empty value set, previously contained unparsable date string,
- // clear related internal fields
- setValue(null);
- }
- }
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
-
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
- }
-
- /**
- * This method is called to handle a non-empty date string from the client
- * if the client could not parse it as a Date.
- *
- * By default, a Converter.ConversionException is thrown, and the current
- * value is not modified.
- *
- * This can be overridden to handle conversions, to return null (equivalent
- * to empty input), to throw an exception or to fire an event.
- *
- * @param dateString
- * @return parsed Date
- * @throws Converter.ConversionException
- * to keep the old value and indicate an error
- */
- protected Date handleUnparsableDateString(String dateString)
- throws Converter.ConversionException {
- currentParseErrorMessage = null;
- throw new Converter.ConversionException(getParseErrorMessage());
- }
-
- /* Property features */
-
- /*
- * Gets the edited property's type. Don't add a JavaDoc comment here, we use
- * the default documentation from implemented interface.
- */
- @Override
- public Class<Date> getType() {
- return Date.class;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractField#setValue(java.lang.Object, boolean)
- */
- @Override
- protected void setValue(Date newValue, boolean repaintIsNotNeeded)
- throws Property.ReadOnlyException {
-
- /*
- * First handle special case when the client side component have a date
- * string but value is null (e.g. unparsable date string typed in by the
- * user). No value changes should happen, but we need to do some
- * internal housekeeping.
- */
- if (newValue == null && !uiHasValidDateString) {
- /*
- * Side-effects of setInternalValue clears possible previous strings
- * and flags about invalid input.
- */
- setInternalValue(null);
-
- /*
- * Due to DateField's special implementation of isValid(),
- * datefields validity may change although the logical value does
- * not change. This is an issue for Form which expects that validity
- * of Fields cannot change unless actual value changes.
- *
- * So we check if this field is inside a form and the form has
- * registered this as a field. In this case we repaint the form.
- * Without this hacky solution the form might not be able to clean
- * validation errors etc. We could avoid this by firing an extra
- * value change event, but feels like at least as bad solution as
- * this.
- */
- notifyFormOfValidityChange();
- requestRepaint();
- return;
- }
-
- super.setValue(newValue, repaintIsNotNeeded);
- }
-
- /**
- * Detects if this field is used in a Form (logically) and if so, notifies
- * it (by repainting it) that the validity of this field might have changed.
- */
- private void notifyFormOfValidityChange() {
- Component parenOfDateField = getParent();
- boolean formFound = false;
- while (parenOfDateField != null || formFound) {
- if (parenOfDateField instanceof Form) {
- Form f = (Form) parenOfDateField;
- Collection<?> visibleItemProperties = f.getItemPropertyIds();
- for (Object fieldId : visibleItemProperties) {
- Field<?> field = f.getField(fieldId);
- if (field == this) {
- /*
- * this datefield is logically in a form. Do the same
- * thing as form does in its value change listener that
- * it registers to all fields.
- */
- f.requestRepaint();
- formFound = true;
- break;
- }
- }
- }
- if (formFound) {
- break;
- }
- parenOfDateField = parenOfDateField.getParent();
- }
- }
-
- @Override
- protected void setInternalValue(Date newValue) {
- // Also set the internal dateString
- if (newValue != null) {
- dateString = newValue.toString();
- } else {
- dateString = null;
- }
-
- if (!uiHasValidDateString) {
- // clear component error and parsing flag
- setComponentError(null);
- uiHasValidDateString = true;
- currentParseErrorMessage = null;
- }
-
- super.setInternalValue(newValue);
- }
-
- /**
- * Gets the resolution.
- *
- * @return int
- */
- public Resolution getResolution() {
- return resolution;
- }
-
- /**
- * Sets the resolution of the DateField.
- *
- * The default resolution is {@link Resolution#DAY} since Vaadin 7.0.
- *
- * @param resolution
- * the resolution to set.
- */
- public void setResolution(Resolution resolution) {
- this.resolution = resolution;
- requestRepaint();
- }
-
- /**
- * Returns new instance calendar used in Date conversions.
- *
- * Returns new clone of the calendar object initialized using the the
- * current date (if available)
- *
- * If this is no calendar is assigned the <code>Calendar.getInstance</code>
- * is used.
- *
- * @return the Calendar.
- * @see #setCalendar(Calendar)
- */
- private Calendar getCalendar() {
-
- // Makes sure we have an calendar instance
- if (calendar == null) {
- calendar = Calendar.getInstance();
- // Start by a zeroed calendar to avoid having values for lower
- // resolution variables e.g. time when resolution is day
- for (Resolution r : Resolution.getResolutionsLowerThan(resolution)) {
- calendar.set(r.getCalendarField(), 0);
- }
- calendar.set(Calendar.MILLISECOND, 0);
- }
-
- // Clone the instance
- final Calendar newCal = (Calendar) calendar.clone();
-
- // Assigns the current time tom calendar.
- final Date currentDate = getValue();
- if (currentDate != null) {
- newCal.setTime(currentDate);
- }
-
- final TimeZone currentTimeZone = getTimeZone();
- if (currentTimeZone != null) {
- newCal.setTimeZone(currentTimeZone);
- }
-
- return newCal;
- }
-
- /**
- * Sets formatting used by some component implementations. See
- * {@link SimpleDateFormat} for format details.
- *
- * By default it is encouraged to used default formatting defined by Locale,
- * but due some JVM bugs it is sometimes necessary to use this method to
- * override formatting. See Vaadin issue #2200.
- *
- * @param dateFormat
- * the dateFormat to set
- *
- * @see com.vaadin.ui.AbstractComponent#setLocale(Locale))
- */
- public void setDateFormat(String dateFormat) {
- this.dateFormat = dateFormat;
- requestRepaint();
- }
-
- /**
- * Returns a format string used to format date value on client side or null
- * if default formatting from {@link Component#getLocale()} is used.
- *
- * @return the dateFormat
- */
- public String getDateFormat() {
- return dateFormat;
- }
-
- /**
- * Specifies whether or not date/time interpretation in component is to be
- * lenient.
- *
- * @see Calendar#setLenient(boolean)
- * @see #isLenient()
- *
- * @param lenient
- * true if the lenient mode is to be turned on; false if it is to
- * be turned off.
- */
- public void setLenient(boolean lenient) {
- this.lenient = lenient;
- requestRepaint();
- }
-
- /**
- * Returns whether date/time interpretation is to be lenient.
- *
- * @see #setLenient(boolean)
- *
- * @return true if the interpretation mode of this calendar is lenient;
- * false otherwise.
- */
- public boolean isLenient() {
- return lenient;
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- /**
- * Checks whether ISO 8601 week numbers are shown in the date selector.
- *
- * @return true if week numbers are shown, false otherwise.
- */
- public boolean isShowISOWeekNumbers() {
- return showISOWeekNumbers;
- }
-
- /**
- * Sets the visibility of ISO 8601 week numbers in the date selector. ISO
- * 8601 defines that a week always starts with a Monday so the week numbers
- * are only shown if this is the case.
- *
- * @param showWeekNumbers
- * true if week numbers should be shown, false otherwise.
- */
- public void setShowISOWeekNumbers(boolean showWeekNumbers) {
- showISOWeekNumbers = showWeekNumbers;
- requestRepaint();
- }
-
- /**
- * Validates the current value against registered validators if the field is
- * not empty. Note that DateField is considered empty (value == null) and
- * invalid if it contains text typed in by the user that couldn't be parsed
- * into a Date value.
- *
- * @see com.vaadin.ui.AbstractField#validate()
- */
- @Override
- public void validate() throws InvalidValueException {
- /*
- * To work properly in form we must throw exception if there is
- * currently a parsing error in the datefield. Parsing error is kind of
- * an internal validator.
- */
- if (!uiHasValidDateString) {
- throw new UnparsableDateString(currentParseErrorMessage);
- }
- super.validate();
- }
-
- /**
- * Return the error message that is shown if the user inputted value can't
- * be parsed into a Date object. If
- * {@link #handleUnparsableDateString(String)} is overridden and it throws a
- * custom exception, the message returned by
- * {@link Exception#getLocalizedMessage()} will be used instead of the value
- * returned by this method.
- *
- * @see #setParseErrorMessage(String)
- *
- * @return the error message that the DateField uses when it can't parse the
- * textual input from user to a Date object
- */
- public String getParseErrorMessage() {
- return defaultParseErrorMessage;
- }
-
- /**
- * Sets the default error message used if the DateField cannot parse the
- * text input by user to a Date field. Note that if the
- * {@link #handleUnparsableDateString(String)} method is overridden, the
- * localized message from its exception is used.
- *
- * @see #getParseErrorMessage()
- * @see #handleUnparsableDateString(String)
- * @param parsingErrorMessage
- */
- public void setParseErrorMessage(String parsingErrorMessage) {
- defaultParseErrorMessage = parsingErrorMessage;
- }
-
- /**
- * Sets the time zone used by this date field. The time zone is used to
- * convert the absolute time in a Date object to a logical time displayed in
- * the selector and to convert the select time back to a Date object.
- *
- * If no time zone has been set, the current default time zone returned by
- * {@code TimeZone.getDefault()} is used.
- *
- * @see #getTimeZone()
- * @param timeZone
- * the time zone to use for time calculations.
- */
- public void setTimeZone(TimeZone timeZone) {
- this.timeZone = timeZone;
- requestRepaint();
- }
-
- /**
- * Gets the time zone used by this field. The time zone is used to convert
- * the absolute time in a Date object to a logical time displayed in the
- * selector and to convert the select time back to a Date object.
- *
- * If {@code null} is returned, the current default time zone returned by
- * {@code TimeZone.getDefault()} is used.
- *
- * @return the current time zone
- */
- public TimeZone getTimeZone() {
- return timeZone;
- }
-
- public static class UnparsableDateString extends
- Validator.InvalidValueException {
-
- public UnparsableDateString(String message) {
- super(message);
- }
-
- }
-}
diff --git a/src/com/vaadin/ui/DefaultFieldFactory.java b/src/com/vaadin/ui/DefaultFieldFactory.java
deleted file mode 100644
index e17f08c1c6..0000000000
--- a/src/com/vaadin/ui/DefaultFieldFactory.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-
-/**
- * This class contains a basic implementation for both {@link FormFieldFactory}
- * and {@link TableFieldFactory}. The class is singleton, use {@link #get()}
- * method to get reference to the instance.
- *
- * <p>
- * There are also some static helper methods available for custom built field
- * factories.
- *
- */
-public class DefaultFieldFactory implements FormFieldFactory, TableFieldFactory {
-
- private static final DefaultFieldFactory instance = new DefaultFieldFactory();
-
- /**
- * Singleton method to get an instance of DefaultFieldFactory.
- *
- * @return an instance of DefaultFieldFactory
- */
- public static DefaultFieldFactory get() {
- return instance;
- }
-
- protected DefaultFieldFactory() {
- }
-
- @Override
- public Field<?> createField(Item item, Object propertyId,
- Component uiContext) {
- Class<?> type = item.getItemProperty(propertyId).getType();
- Field<?> field = createFieldByPropertyType(type);
- field.setCaption(createCaptionByPropertyId(propertyId));
- return field;
- }
-
- @Override
- public Field<?> createField(Container container, Object itemId,
- Object propertyId, Component uiContext) {
- Property<?> containerProperty = container.getContainerProperty(itemId,
- propertyId);
- Class<?> type = containerProperty.getType();
- Field<?> field = createFieldByPropertyType(type);
- field.setCaption(createCaptionByPropertyId(propertyId));
- return field;
- }
-
- /**
- * If name follows method naming conventions, convert the name to spaced
- * upper case text. For example, convert "firstName" to "First Name"
- *
- * @param propertyId
- * @return the formatted caption string
- */
- public static String createCaptionByPropertyId(Object propertyId) {
- String name = propertyId.toString();
- if (name.length() > 0) {
-
- int dotLocation = name.lastIndexOf('.');
- if (dotLocation > 0 && dotLocation < name.length() - 1) {
- name = name.substring(dotLocation + 1);
- }
- if (name.indexOf(' ') < 0
- && name.charAt(0) == Character.toLowerCase(name.charAt(0))
- && name.charAt(0) != Character.toUpperCase(name.charAt(0))) {
- StringBuffer out = new StringBuffer();
- out.append(Character.toUpperCase(name.charAt(0)));
- int i = 1;
-
- while (i < name.length()) {
- int j = i;
- for (; j < name.length(); j++) {
- char c = name.charAt(j);
- if (Character.toLowerCase(c) != c
- && Character.toUpperCase(c) == c) {
- break;
- }
- }
- if (j == name.length()) {
- out.append(name.substring(i));
- } else {
- out.append(name.substring(i, j));
- out.append(" " + name.charAt(j));
- }
- i = j + 1;
- }
-
- name = out.toString();
- }
- }
- return name;
- }
-
- /**
- * Creates fields based on the property type.
- * <p>
- * The default field type is {@link TextField}. Other field types generated
- * by this method:
- * <p>
- * <b>Boolean</b>: {@link CheckBox}.<br/>
- * <b>Date</b>: {@link DateField}(resolution: day).<br/>
- * <b>Item</b>: {@link Form}. <br/>
- * <b>default field type</b>: {@link TextField}.
- * <p>
- *
- * @param type
- * the type of the property
- * @return the most suitable generic {@link Field} for given type
- */
- public static Field<?> createFieldByPropertyType(Class<?> type) {
- // Null typed properties can not be edited
- if (type == null) {
- return null;
- }
-
- // Item field
- if (Item.class.isAssignableFrom(type)) {
- return new Form();
- }
-
- // Date field
- if (Date.class.isAssignableFrom(type)) {
- final DateField df = new DateField();
- df.setResolution(DateField.RESOLUTION_DAY);
- return df;
- }
-
- // Boolean field
- if (Boolean.class.isAssignableFrom(type)) {
- return new CheckBox();
- }
-
- return new TextField();
- }
-
-}
diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java
deleted file mode 100644
index 67229a45fe..0000000000
--- a/src/com/vaadin/ui/DragAndDropWrapper.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.vaadin.event.Transferable;
-import com.vaadin.event.TransferableImpl;
-import com.vaadin.event.dd.DragSource;
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.event.dd.TargetDetails;
-import com.vaadin.event.dd.TargetDetailsImpl;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.dd.HorizontalDropLocation;
-import com.vaadin.shared.ui.dd.VerticalDropLocation;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.StreamVariable;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.draganddropwrapper.VDragAndDropWrapper;
-
-@SuppressWarnings("serial")
-public class DragAndDropWrapper extends CustomComponent implements DropTarget,
- DragSource, Vaadin6Component {
-
- public class WrapperTransferable extends TransferableImpl {
-
- private Html5File[] files;
-
- public WrapperTransferable(Component sourceComponent,
- Map<String, Object> rawVariables) {
- super(sourceComponent, rawVariables);
- Integer fc = (Integer) rawVariables.get("filecount");
- if (fc != null) {
- files = new Html5File[fc];
- for (int i = 0; i < fc; i++) {
- Html5File file = new Html5File(
- (String) rawVariables.get("fn" + i), // name
- (Integer) rawVariables.get("fs" + i), // size
- (String) rawVariables.get("ft" + i)); // mime
- String id = (String) rawVariables.get("fi" + i);
- files[i] = file;
- receivers.put(id, file);
- requestRepaint(); // paint Receivers
- }
- }
- }
-
- /**
- * The component in wrapper that is being dragged or null if the
- * transferable is not a component (most likely an html5 drag).
- *
- * @return
- */
- public Component getDraggedComponent() {
- Component object = (Component) getData("component");
- return object;
- }
-
- /**
- * @return the mouse down event that started the drag and drop operation
- */
- public MouseEventDetails getMouseDownEvent() {
- return MouseEventDetails.deSerialize((String) getData("mouseDown"));
- }
-
- public Html5File[] getFiles() {
- return files;
- }
-
- public String getText() {
- String data = (String) getData("Text"); // IE, html5
- if (data == null) {
- // check for "text/plain" (webkit)
- data = (String) getData("text/plain");
- }
- return data;
- }
-
- public String getHtml() {
- String data = (String) getData("Html"); // IE, html5
- if (data == null) {
- // check for "text/plain" (webkit)
- data = (String) getData("text/html");
- }
- return data;
- }
-
- }
-
- private Map<String, Html5File> receivers = new HashMap<String, Html5File>();
-
- public class WrapperTargetDetails extends TargetDetailsImpl {
-
- public WrapperTargetDetails(Map<String, Object> rawDropData) {
- super(rawDropData, DragAndDropWrapper.this);
- }
-
- /**
- * @return the absolute position of wrapper on the page
- */
- public Integer getAbsoluteLeft() {
- return (Integer) getData("absoluteLeft");
- }
-
- /**
- *
- * @return the absolute position of wrapper on the page
- */
- public Integer getAbsoluteTop() {
- return (Integer) getData("absoluteTop");
- }
-
- /**
- * @return details about the actual event that caused the event details.
- * Practically mouse move or mouse up.
- */
- public MouseEventDetails getMouseEvent() {
- return MouseEventDetails
- .deSerialize((String) getData("mouseEvent"));
- }
-
- /**
- * @return a detail about the drags vertical position over the wrapper.
- */
- public VerticalDropLocation getVerticalDropLocation() {
- return VerticalDropLocation
- .valueOf((String) getData("verticalLocation"));
- }
-
- /**
- * @return a detail about the drags horizontal position over the
- * wrapper.
- */
- public HorizontalDropLocation getHorizontalDropLocation() {
- return HorizontalDropLocation
- .valueOf((String) getData("horizontalLocation"));
- }
-
- /**
- * @deprecated use {@link #getVerticalDropLocation()} instead
- */
- @Deprecated
- public VerticalDropLocation verticalDropLocation() {
- return getVerticalDropLocation();
- }
-
- /**
- * @deprecated use {@link #getHorizontalDropLocation()} instead
- */
- @Deprecated
- public HorizontalDropLocation horizontalDropLocation() {
- return getHorizontalDropLocation();
- }
-
- }
-
- public enum DragStartMode {
- /**
- * {@link DragAndDropWrapper} does not start drag events at all
- */
- NONE,
- /**
- * The component on which the drag started will be shown as drag image.
- */
- COMPONENT,
- /**
- * The whole wrapper is used as a drag image when dragging.
- */
- WRAPPER,
- /**
- * The whole wrapper is used to start an HTML5 drag.
- *
- * NOTE: In Internet Explorer 6 to 8, this prevents user interactions
- * with the wrapper's contents. For example, clicking a button inside
- * the wrapper will no longer work.
- */
- HTML5,
- }
-
- private final Map<String, Object> html5DataFlavors = new LinkedHashMap<String, Object>();
- private DragStartMode dragStartMode = DragStartMode.NONE;
-
- /**
- * Wraps given component in a {@link DragAndDropWrapper}.
- *
- * @param root
- * the component to be wrapped
- */
- public DragAndDropWrapper(Component root) {
- super(root);
- }
-
- /**
- * Sets data flavors available in the DragAndDropWrapper is used to start an
- * HTML5 style drags. Most commonly the "Text" flavor should be set.
- * Multiple data types can be set.
- *
- * @param type
- * the string identifier of the drag "payload". E.g. "Text" or
- * "text/html"
- * @param value
- * the value
- */
- public void setHTML5DataFlavor(String type, Object value) {
- html5DataFlavors.put(type, value);
- requestRepaint();
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // TODO Remove once Vaadin6Component is no longer implemented
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute(VDragAndDropWrapper.DRAG_START_MODE,
- dragStartMode.ordinal());
- if (getDropHandler() != null) {
- getDropHandler().getAcceptCriterion().paint(target);
- }
- if (receivers != null && receivers.size() > 0) {
- for (Iterator<Entry<String, Html5File>> it = receivers.entrySet()
- .iterator(); it.hasNext();) {
- Entry<String, com.vaadin.ui.Html5File> entry = it.next();
- String id = entry.getKey();
- Html5File html5File = entry.getValue();
- if (html5File.getStreamVariable() != null) {
- target.addVariable(this, "rec-" + id, new ProxyReceiver(
- html5File));
- // these are cleaned from receivers once the upload has
- // started
- } else {
- // instructs the client side not to send the file
- target.addVariable(this, "rec-" + id, (String) null);
- // forget the file from subsequent paints
- it.remove();
- }
- }
- }
- target.addAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS,
- html5DataFlavors);
- }
-
- private DropHandler dropHandler;
-
- @Override
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- requestRepaint();
- }
-
- @Override
- public TargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables) {
- return new WrapperTargetDetails(clientVariables);
- }
-
- @Override
- public Transferable getTransferable(final Map<String, Object> rawVariables) {
- return new WrapperTransferable(this, rawVariables);
- }
-
- public void setDragStartMode(DragStartMode dragStartMode) {
- this.dragStartMode = dragStartMode;
- requestRepaint();
- }
-
- public DragStartMode getDragStartMode() {
- return dragStartMode;
- }
-
- final class ProxyReceiver implements StreamVariable {
-
- private Html5File file;
-
- public ProxyReceiver(Html5File file) {
- this.file = file;
- }
-
- private boolean listenProgressOfUploadedFile;
-
- @Override
- public OutputStream getOutputStream() {
- if (file.getStreamVariable() == null) {
- return null;
- }
- return file.getStreamVariable().getOutputStream();
- }
-
- @Override
- public boolean listenProgress() {
- return file.getStreamVariable().listenProgress();
- }
-
- @Override
- public void onProgress(StreamingProgressEvent event) {
- file.getStreamVariable().onProgress(
- new ReceivingEventWrapper(event));
- }
-
- @Override
- public void streamingStarted(StreamingStartEvent event) {
- listenProgressOfUploadedFile = file.getStreamVariable() != null;
- if (listenProgressOfUploadedFile) {
- file.getStreamVariable().streamingStarted(
- new ReceivingEventWrapper(event));
- }
- // no need tell to the client about this receiver on next paint
- receivers.remove(file);
- // let the terminal GC the streamvariable and not to accept other
- // file uploads to this variable
- event.disposeStreamVariable();
- }
-
- @Override
- public void streamingFinished(StreamingEndEvent event) {
- if (listenProgressOfUploadedFile) {
- file.getStreamVariable().streamingFinished(
- new ReceivingEventWrapper(event));
- }
- }
-
- @Override
- public void streamingFailed(final StreamingErrorEvent event) {
- if (listenProgressOfUploadedFile) {
- file.getStreamVariable().streamingFailed(
- new ReceivingEventWrapper(event));
- }
- }
-
- @Override
- public boolean isInterrupted() {
- return file.getStreamVariable().isInterrupted();
- }
-
- /*
- * With XHR2 file posts we can't provide as much information from the
- * terminal as with multipart request. This helper class wraps the
- * terminal event and provides the lacking information from the
- * Html5File.
- */
- class ReceivingEventWrapper implements StreamingErrorEvent,
- StreamingEndEvent, StreamingStartEvent, StreamingProgressEvent {
-
- private StreamingEvent wrappedEvent;
-
- ReceivingEventWrapper(StreamingEvent e) {
- wrappedEvent = e;
- }
-
- @Override
- public String getMimeType() {
- return file.getType();
- }
-
- @Override
- public String getFileName() {
- return file.getFileName();
- }
-
- @Override
- public long getContentLength() {
- return file.getFileSize();
- }
-
- public StreamVariable getReceiver() {
- return ProxyReceiver.this;
- }
-
- @Override
- public Exception getException() {
- if (wrappedEvent instanceof StreamingErrorEvent) {
- return ((StreamingErrorEvent) wrappedEvent).getException();
- }
- return null;
- }
-
- @Override
- public long getBytesReceived() {
- return wrappedEvent.getBytesReceived();
- }
-
- /**
- * Calling this method has no effect. DD files are receive only once
- * anyway.
- */
- @Override
- public void disposeStreamVariable() {
-
- }
- }
-
- }
-
-}
diff --git a/src/com/vaadin/ui/Embedded.java b/src/com/vaadin/ui/Embedded.java
deleted file mode 100644
index 6088c5aa66..0000000000
--- a/src/com/vaadin/ui/Embedded.java
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.MouseEvents.ClickListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.embedded.EmbeddedServerRpc;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.ClickEventHandler;
-import com.vaadin.terminal.gwt.client.ui.embedded.EmbeddedConnector;
-
-/**
- * Component for embedding external objects.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Embedded extends AbstractComponent implements Vaadin6Component {
-
- /**
- * General object type.
- */
- public static final int TYPE_OBJECT = 0;
-
- /**
- * Image types.
- */
- public static final int TYPE_IMAGE = 1;
-
- /**
- * Browser ("iframe") type.
- */
- public static final int TYPE_BROWSER = 2;
-
- /**
- * Type of the object.
- */
- private int type = TYPE_OBJECT;
-
- /**
- * Source of the embedded object.
- */
- private Resource source = null;
-
- /**
- * Generic object attributes.
- */
- private String mimeType = null;
-
- private String standby = null;
-
- /**
- * Hash of object parameters.
- */
- private final Map<String, String> parameters = new HashMap<String, String>();
-
- /**
- * Applet or other client side runnable properties.
- */
- private String codebase = null;
-
- private String codetype = null;
-
- private String classId = null;
-
- private String archive = null;
-
- private String altText;
-
- private EmbeddedServerRpc rpc = new EmbeddedServerRpc() {
- @Override
- public void click(MouseEventDetails mouseDetails) {
- fireEvent(new ClickEvent(Embedded.this, mouseDetails));
- }
- };
-
- /**
- * Creates a new empty Embedded object.
- */
- public Embedded() {
- registerRpc(rpc);
- }
-
- /**
- * Creates a new empty Embedded object with caption.
- *
- * @param caption
- */
- public Embedded(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Creates a new Embedded object whose contents is loaded from given
- * resource. The dimensions are assumed if possible. The type is guessed
- * from resource.
- *
- * @param caption
- * @param source
- * the Source of the embedded object.
- */
- public Embedded(String caption, Resource source) {
- this(caption);
- setSource(source);
- }
-
- /**
- * Invoked when the component state should be painted.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- switch (type) {
- case TYPE_IMAGE:
- target.addAttribute("type", "image");
- break;
- case TYPE_BROWSER:
- target.addAttribute("type", "browser");
- break;
- default:
- break;
- }
-
- if (getSource() != null) {
- target.addAttribute("src", getSource());
- }
-
- if (mimeType != null && !"".equals(mimeType)) {
- target.addAttribute("mimetype", mimeType);
- }
- if (classId != null && !"".equals(classId)) {
- target.addAttribute("classid", classId);
- }
- if (codebase != null && !"".equals(codebase)) {
- target.addAttribute("codebase", codebase);
- }
- if (codetype != null && !"".equals(codetype)) {
- target.addAttribute("codetype", codetype);
- }
- if (standby != null && !"".equals(standby)) {
- target.addAttribute("standby", standby);
- }
- if (archive != null && !"".equals(archive)) {
- target.addAttribute("archive", archive);
- }
- if (altText != null && !"".equals(altText)) {
- target.addAttribute(EmbeddedConnector.ALTERNATE_TEXT, altText);
- }
-
- // Params
- for (final Iterator<String> i = getParameterNames(); i.hasNext();) {
- target.startTag("embeddedparam");
- final String key = i.next();
- target.addAttribute("name", key);
- target.addAttribute("value", getParameter(key));
- target.endTag("embeddedparam");
- }
- }
-
- /**
- * Sets this component's "alt-text", that is, an alternate text that can be
- * presented instead of this component's normal content, for accessibility
- * purposes. Does not work when {@link #setType(int)} has been called with
- * {@link #TYPE_BROWSER}.
- *
- * @param altText
- * A short, human-readable description of this component's
- * content.
- * @since 6.8
- */
- public void setAlternateText(String altText) {
- if (altText != this.altText
- || (altText != null && !altText.equals(this.altText))) {
- this.altText = altText;
- requestRepaint();
- }
- }
-
- /**
- * Gets this component's "alt-text".
- *
- * @see #setAlternateText(String)
- */
- public String getAlternateText() {
- return altText;
- }
-
- /**
- * Sets an object parameter. Parameters are optional information, and they
- * are passed to the instantiated object. Parameters are are stored as name
- * value pairs. This overrides the previous value assigned to this
- * parameter.
- *
- * @param name
- * the name of the parameter.
- * @param value
- * the value of the parameter.
- */
- public void setParameter(String name, String value) {
- parameters.put(name, value);
- requestRepaint();
- }
-
- /**
- * Gets the value of an object parameter. Parameters are optional
- * information, and they are passed to the instantiated object. Parameters
- * are are stored as name value pairs.
- *
- * @return the Value of parameter or null if not found.
- */
- public String getParameter(String name) {
- return parameters.get(name);
- }
-
- /**
- * Removes an object parameter from the list.
- *
- * @param name
- * the name of the parameter to remove.
- */
- public void removeParameter(String name) {
- parameters.remove(name);
- requestRepaint();
- }
-
- /**
- * Gets the embedded object parameter names.
- *
- * @return the Iterator of parameters names.
- */
- public Iterator<String> getParameterNames() {
- return parameters.keySet().iterator();
- }
-
- /**
- * This attribute specifies the base path used to resolve relative URIs
- * specified by the classid, data, and archive attributes. When absent, its
- * default value is the base URI of the current document.
- *
- * @return the code base.
- */
- public String getCodebase() {
- return codebase;
- }
-
- /**
- * Gets the MIME-Type of the code.
- *
- * @return the MIME-Type of the code.
- */
- public String getCodetype() {
- return codetype;
- }
-
- /**
- * Gets the MIME-Type of the object.
- *
- * @return the MIME-Type of the object.
- */
- public String getMimeType() {
- return mimeType;
- }
-
- /**
- * This attribute specifies a message that a user agent may render while
- * loading the object's implementation and data.
- *
- * @return The text displayed when loading
- */
- public String getStandby() {
- return standby;
- }
-
- /**
- * This attribute specifies the base path used to resolve relative URIs
- * specified by the classid, data, and archive attributes. When absent, its
- * default value is the base URI of the current document.
- *
- * @param codebase
- * The base path
- */
- public void setCodebase(String codebase) {
- if (codebase != this.codebase
- || (codebase != null && !codebase.equals(this.codebase))) {
- this.codebase = codebase;
- requestRepaint();
- }
- }
-
- /**
- * This attribute specifies the content type of data expected when
- * downloading the object specified by classid. This attribute is optional
- * but recommended when classid is specified since it allows the user agent
- * to avoid loading information for unsupported content types. When absent,
- * it defaults to the value of the type attribute.
- *
- * @param codetype
- * the codetype to set.
- */
- public void setCodetype(String codetype) {
- if (codetype != this.codetype
- || (codetype != null && !codetype.equals(this.codetype))) {
- this.codetype = codetype;
- requestRepaint();
- }
- }
-
- /**
- * Sets the mimeType, the MIME-Type of the object.
- *
- * @param mimeType
- * the mimeType to set.
- */
- public void setMimeType(String mimeType) {
- if (mimeType != this.mimeType
- || (mimeType != null && !mimeType.equals(this.mimeType))) {
- this.mimeType = mimeType;
- if ("application/x-shockwave-flash".equals(mimeType)) {
- /*
- * Automatically add wmode transparent as we use lots of
- * floating layers in Vaadin. If developers need better flash
- * performance, they can override this value programmatically
- * back to "window" (the defautl).
- */
- if (getParameter("wmode") == null) {
- setParameter("wmode", "transparent");
- }
- }
- requestRepaint();
- }
- }
-
- /**
- * This attribute specifies a message that a user agent may render while
- * loading the object's implementation and data.
- *
- * @param standby
- * The text to display while loading
- */
- public void setStandby(String standby) {
- if (standby != this.standby
- || (standby != null && !standby.equals(this.standby))) {
- this.standby = standby;
- requestRepaint();
- }
- }
-
- /**
- * This attribute may be used to specify the location of an object's
- * implementation via a URI.
- *
- * @return the classid.
- */
- public String getClassId() {
- return classId;
- }
-
- /**
- * This attribute may be used to specify the location of an object's
- * implementation via a URI.
- *
- * @param classId
- * the classId to set.
- */
- public void setClassId(String classId) {
- if (classId != this.classId
- || (classId != null && !classId.equals(this.classId))) {
- this.classId = classId;
- requestRepaint();
- }
- }
-
- /**
- * Gets the resource contained in the embedded object.
- *
- * @return the Resource
- */
- public Resource getSource() {
- return source;
- }
-
- /**
- * Gets the type of the embedded object.
- * <p>
- * This can be one of the following:
- * <ul>
- * <li>TYPE_OBJECT <i>(This is the default)</i>
- * <li>TYPE_IMAGE
- * </ul>
- * </p>
- *
- * @return the type.
- */
- public int getType() {
- return type;
- }
-
- /**
- * Sets the object source resource. The dimensions are assumed if possible.
- * The type is guessed from resource.
- *
- * @param source
- * the source to set.
- */
- public void setSource(Resource source) {
- if (source != null && !source.equals(this.source)) {
- this.source = source;
- final String mt = source.getMIMEType();
-
- if (mimeType == null) {
- mimeType = mt;
- }
-
- if (mt.equals("image/svg+xml")) {
- type = TYPE_OBJECT;
- } else if ((mt.substring(0, mt.indexOf("/"))
- .equalsIgnoreCase("image"))) {
- type = TYPE_IMAGE;
- } else {
- // Keep previous type
- }
- requestRepaint();
- }
- }
-
- /**
- * Sets the object type.
- * <p>
- * This can be one of the following:
- * <ul>
- * <li>TYPE_OBJECT <i>(This is the default)</i>
- * <li>TYPE_IMAGE
- * <li>TYPE_BROWSER
- * </ul>
- * </p>
- *
- * @param type
- * the type to set.
- */
- public void setType(int type) {
- if (type != TYPE_OBJECT && type != TYPE_IMAGE && type != TYPE_BROWSER) {
- throw new IllegalArgumentException("Unsupported type");
- }
- if (type != this.type) {
- this.type = type;
- requestRepaint();
- }
- }
-
- /**
- * This attribute may be used to specify a space-separated list of URIs for
- * archives containing resources relevant to the object, which may include
- * the resources specified by the classid and data attributes. Preloading
- * archives will generally result in reduced load times for objects.
- * Archives specified as relative URIs should be interpreted relative to the
- * codebase attribute.
- *
- * @return Space-separated list of URIs with resources relevant to the
- * object
- */
- public String getArchive() {
- return archive;
- }
-
- /**
- * This attribute may be used to specify a space-separated list of URIs for
- * archives containing resources relevant to the object, which may include
- * the resources specified by the classid and data attributes. Preloading
- * archives will generally result in reduced load times for objects.
- * Archives specified as relative URIs should be interpreted relative to the
- * codebase attribute.
- *
- * @param archive
- * Space-separated list of URIs with resources relevant to the
- * object
- */
- public void setArchive(String archive) {
- if (archive != this.archive
- || (archive != null && !archive.equals(this.archive))) {
- this.archive = archive;
- requestRepaint();
- }
- }
-
- /**
- * Add a click listener to the component. The listener is called whenever
- * the user clicks inside the component. Depending on the content the event
- * may be blocked and in that case no event is fired.
- *
- * Use {@link #removeListener(ClickListener)} to remove the listener.
- *
- * @param listener
- * The listener to add
- */
- public void addListener(ClickListener listener) {
- addListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, ClickEvent.class,
- listener, ClickListener.clickMethod);
- }
-
- /**
- * Remove a click listener from the component. The listener should earlier
- * have been added using {@link #addListener(ClickListener)}.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(ClickListener listener) {
- removeListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER,
- ClickEvent.class, listener);
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // TODO Remove once Vaadin6Component is no longer implemented
- }
-
-}
diff --git a/src/com/vaadin/ui/Field.java b/src/com/vaadin/ui/Field.java
deleted file mode 100644
index 6dc40d192f..0000000000
--- a/src/com/vaadin/ui/Field.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.data.BufferedValidatable;
-import com.vaadin.data.Property;
-import com.vaadin.ui.Component.Focusable;
-
-/**
- * TODO document
- *
- * @author Vaadin Ltd.
- *
- * @param T
- * the type of values in the field, which might not be the same type
- * as that of the data source if converters are used
- *
- * @author IT Mill Ltd.
- */
-public interface Field<T> extends Component, BufferedValidatable, Property<T>,
- Property.ValueChangeNotifier, Property.ValueChangeListener,
- Property.Editor, Focusable {
-
- /**
- * Is this field required.
- *
- * Required fields must filled by the user.
- *
- * @return <code>true</code> if the field is required,otherwise
- * <code>false</code>.
- * @since 3.1
- */
- public boolean isRequired();
-
- /**
- * Sets the field required. Required fields must filled by the user.
- *
- * @param required
- * Is the field required.
- * @since 3.1
- */
- public void setRequired(boolean required);
-
- /**
- * Sets the error message to be displayed if a required field is empty.
- *
- * @param requiredMessage
- * Error message.
- * @since 5.2.6
- */
- public void setRequiredError(String requiredMessage);
-
- /**
- * Gets the error message that is to be displayed if a required field is
- * empty.
- *
- * @return Error message.
- * @since 5.2.6
- */
- public String getRequiredError();
-
- /**
- * An <code>Event</code> object specifying the Field whose value has been
- * changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public static class ValueChangeEvent extends Component.Event implements
- Property.ValueChangeEvent {
-
- /**
- * Constructs a new event object with the specified source field object.
- *
- * @param source
- * the field that caused the event.
- */
- public ValueChangeEvent(Field source) {
- super(source);
- }
-
- /**
- * Gets the Property which triggered the event.
- *
- * @return the Source Property of the event.
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-}
diff --git a/src/com/vaadin/ui/Form.java b/src/com/vaadin/ui/Form.java
deleted file mode 100644
index fbc4d5a8e6..0000000000
--- a/src/com/vaadin/ui/Form.java
+++ /dev/null
@@ -1,1420 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import com.vaadin.data.Buffered;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.Validatable;
-import com.vaadin.data.Validator;
-import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.data.fieldgroup.FieldGroup;
-import com.vaadin.data.util.BeanItem;
-import com.vaadin.event.Action;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.event.Action.ShortcutNotifier;
-import com.vaadin.event.ActionManager;
-import com.vaadin.shared.ui.form.FormState;
-import com.vaadin.terminal.AbstractErrorMessage;
-import com.vaadin.terminal.CompositeErrorMessage;
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.UserError;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- * Form component provides easy way of creating and managing sets fields.
- *
- * <p>
- * <code>Form</code> is a container for fields implementing {@link Field}
- * interface. It provides support for any layouts and provides buffering
- * interface for easy connection of commit and discard buttons. All the form
- * fields can be customized by adding validators, setting captions and icons,
- * setting immediateness, etc. Also direct mechanism for replacing existing
- * fields with selections is given.
- * </p>
- *
- * <p>
- * <code>Form</code> provides customizable editor for classes implementing
- * {@link com.vaadin.data.Item} interface. Also the form itself implements this
- * interface for easier connectivity to other items. To use the form as editor
- * for an item, just connect the item to form with
- * {@link Form#setItemDataSource(Item)}. If only a part of the item needs to be
- * edited, {@link Form#setItemDataSource(Item,Collection)} can be used instead.
- * After the item has been connected to the form, the automatically created
- * fields can be customized and new fields can be added. If you need to connect
- * a class that does not implement {@link com.vaadin.data.Item} interface, most
- * properties of any class following bean pattern, can be accessed trough
- * {@link com.vaadin.data.util.BeanItem}.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- * @deprecated Use {@link FieldGroup} instead of {@link Form} for more
- * flexibility.
- */
-@Deprecated
-public class Form extends AbstractField<Object> implements Item.Editor,
- Buffered, Item, Validatable, Action.Notifier, HasComponents,
- Vaadin6Component {
-
- private Object propertyValue;
-
- /**
- * Item connected to this form as datasource.
- */
- private Item itemDatasource;
-
- /**
- * Ordered list of property ids in this editor.
- */
- private final LinkedList<Object> propertyIds = new LinkedList<Object>();
-
- /**
- * Current buffered source exception.
- */
- private Buffered.SourceException currentBufferedSourceException = null;
-
- /**
- * Is the form in write trough mode.
- */
- private boolean writeThrough = true;
-
- /**
- * Is the form in read trough mode.
- */
- private boolean readThrough = true;
-
- /**
- * Mapping from propertyName to corresponding field.
- */
- private final HashMap<Object, Field<?>> fields = new HashMap<Object, Field<?>>();
-
- /**
- * Form may act as an Item, its own properties are stored here.
- */
- private final HashMap<Object, Property<?>> ownProperties = new HashMap<Object, Property<?>>();
-
- /**
- * Field factory for this form.
- */
- private FormFieldFactory fieldFactory;
-
- /**
- * Visible item properties.
- */
- private Collection<?> visibleItemProperties;
-
- /**
- * Form needs to repaint itself if child fields value changes due possible
- * change in form validity.
- *
- * TODO introduce ValidityChangeEvent (#6239) and start using it instead.
- * See e.g. DateField#notifyFormOfValidityChange().
- */
- private final ValueChangeListener fieldValueChangeListener = new ValueChangeListener() {
- @Override
- public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
- requestRepaint();
- }
- };
-
- /**
- * If this is true, commit implicitly calls setValidationVisible(true).
- */
- private boolean validationVisibleOnCommit = true;
-
- // special handling for gridlayout; remember initial cursor pos
- private int gridlayoutCursorX = -1;
- private int gridlayoutCursorY = -1;
-
- /**
- * Keeps track of the Actions added to this component, and manages the
- * painting and handling as well. Note that the extended AbstractField is a
- * {@link ShortcutNotifier} and has a actionManager that delegates actions
- * to the containing window. This one does not delegate.
- */
- private ActionManager ownActionManager = new ActionManager(this);
-
- /**
- * Constructs a new form with default layout.
- *
- * <p>
- * By default the form uses {@link FormLayout}.
- * </p>
- */
- public Form() {
- this(null);
- setValidationVisible(false);
- }
-
- /**
- * Constructs a new form with given {@link Layout}.
- *
- * @param formLayout
- * the layout of the form.
- */
- public Form(Layout formLayout) {
- this(formLayout, DefaultFieldFactory.get());
- }
-
- /**
- * Constructs a new form with given {@link Layout} and
- * {@link FormFieldFactory}.
- *
- * @param formLayout
- * the layout of the form.
- * @param fieldFactory
- * the FieldFactory of the form.
- */
- public Form(Layout formLayout, FormFieldFactory fieldFactory) {
- super();
- setLayout(formLayout);
- setFooter(null);
- setFormFieldFactory(fieldFactory);
- setValidationVisible(false);
- setWidth(100, UNITS_PERCENTAGE);
- }
-
- @Override
- public FormState getState() {
- return (FormState) super.getState();
- }
-
- /* Documented in interface */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (ownActionManager != null) {
- ownActionManager.paintActions(null, target);
- }
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // Actions
- if (ownActionManager != null) {
- ownActionManager.handleActions(variables, this);
- }
- }
-
- /**
- * The error message of a Form is the error of the first field with a
- * non-empty error.
- *
- * Empty error messages of the contained fields are skipped, because an
- * empty error indicator would be confusing to the user, especially if there
- * are errors that have something to display. This is also the reason why
- * the calculation of the error message is separate from validation, because
- * validation fails also on empty errors.
- */
- @Override
- public ErrorMessage getErrorMessage() {
-
- // Reimplement the checking of validation error by using
- // getErrorMessage() recursively instead of validate().
- ErrorMessage validationError = null;
- if (isValidationVisible()) {
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- Object f = fields.get(i.next());
- if (f instanceof AbstractComponent) {
- AbstractComponent field = (AbstractComponent) f;
-
- validationError = field.getErrorMessage();
- if (validationError != null) {
- // Show caption as error for fields with empty errors
- if ("".equals(validationError.toString())) {
- validationError = new UserError(field.getCaption());
- }
- break;
- } else if (f instanceof Field && !((Field<?>) f).isValid()) {
- // Something is wrong with the field, but no proper
- // error is given. Generate one.
- validationError = new UserError(field.getCaption());
- break;
- }
- }
- }
- }
-
- // Return if there are no errors at all
- if (getComponentError() == null && validationError == null
- && currentBufferedSourceException == null) {
- return null;
- }
-
- // Throw combination of the error types
- return new CompositeErrorMessage(
- new ErrorMessage[] {
- getComponentError(),
- validationError,
- AbstractErrorMessage
- .getErrorMessageForException(currentBufferedSourceException) });
- }
-
- /**
- * Controls the making validation visible implicitly on commit.
- *
- * Having commit() call setValidationVisible(true) implicitly is the default
- * behaviour. You can disable the implicit setting by setting this property
- * as false.
- *
- * It is useful, because you usually want to start with the form free of
- * errors and only display them after the user clicks Ok. You can disable
- * the implicit setting by setting this property as false.
- *
- * @param makeVisible
- * If true (default), validation is made visible when commit() is
- * called. If false, the visibility is left as it is.
- */
- public void setValidationVisibleOnCommit(boolean makeVisible) {
- validationVisibleOnCommit = makeVisible;
- }
-
- /**
- * Is validation made automatically visible on commit?
- *
- * See setValidationVisibleOnCommit().
- *
- * @return true if validation is made automatically visible on commit.
- */
- public boolean isValidationVisibleOnCommit() {
- return validationVisibleOnCommit;
- }
-
- /*
- * Commit changes to the data source Don't add a JavaDoc comment here, we
- * use the default one from the interface.
- */
- @Override
- public void commit() throws Buffered.SourceException, InvalidValueException {
-
- LinkedList<SourceException> problems = null;
-
- // Only commit on valid state if so requested
- if (!isInvalidCommitted() && !isValid()) {
- /*
- * The values are not ok and we are told not to commit invalid
- * values
- */
- if (validationVisibleOnCommit) {
- setValidationVisible(true);
- }
-
- // Find the first invalid value and throw the exception
- validate();
- }
-
- // Try to commit all
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- try {
- final Field<?> f = (fields.get(i.next()));
- // Commit only non-readonly fields.
- if (!f.isReadOnly()) {
- f.commit();
- }
- } catch (final Buffered.SourceException e) {
- if (problems == null) {
- problems = new LinkedList<SourceException>();
- }
- problems.add(e);
- }
- }
-
- // No problems occurred
- if (problems == null) {
- if (currentBufferedSourceException != null) {
- currentBufferedSourceException = null;
- requestRepaint();
- }
- return;
- }
-
- // Commit problems
- final Throwable[] causes = new Throwable[problems.size()];
- int index = 0;
- for (final Iterator<SourceException> i = problems.iterator(); i
- .hasNext();) {
- causes[index++] = i.next();
- }
- final Buffered.SourceException e = new Buffered.SourceException(this,
- causes);
- currentBufferedSourceException = e;
- requestRepaint();
- throw e;
- }
-
- /*
- * Discards local changes and refresh values from the data source Don't add
- * a JavaDoc comment here, we use the default one from the interface.
- */
- @Override
- public void discard() throws Buffered.SourceException {
-
- LinkedList<SourceException> problems = null;
-
- // Try to discard all changes
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- try {
- (fields.get(i.next())).discard();
- } catch (final Buffered.SourceException e) {
- if (problems == null) {
- problems = new LinkedList<SourceException>();
- }
- problems.add(e);
- }
- }
-
- // No problems occurred
- if (problems == null) {
- if (currentBufferedSourceException != null) {
- currentBufferedSourceException = null;
- requestRepaint();
- }
- return;
- }
-
- // Discards problems occurred
- final Throwable[] causes = new Throwable[problems.size()];
- int index = 0;
- for (final Iterator<SourceException> i = problems.iterator(); i
- .hasNext();) {
- causes[index++] = i.next();
- }
- final Buffered.SourceException e = new Buffered.SourceException(this,
- causes);
- currentBufferedSourceException = e;
- requestRepaint();
- throw e;
- }
-
- /*
- * Is the object modified but not committed? Don't add a JavaDoc comment
- * here, we use the default one from the interface.
- */
- @Override
- public boolean isModified() {
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- final Field<?> f = fields.get(i.next());
- if (f != null && f.isModified()) {
- return true;
- }
-
- }
- return false;
- }
-
- /*
- * Is the editor in a read-through mode? Don't add a JavaDoc comment here,
- * we use the default one from the interface.
- */
- @Override
- @Deprecated
- public boolean isReadThrough() {
- return readThrough;
- }
-
- /*
- * Is the editor in a write-through mode? Don't add a JavaDoc comment here,
- * we use the default one from the interface.
- */
- @Override
- @Deprecated
- public boolean isWriteThrough() {
- return writeThrough;
- }
-
- /*
- * Sets the editor's read-through mode to the specified status. Don't add a
- * JavaDoc comment here, we use the default one from the interface.
- */
- @Override
- public void setReadThrough(boolean readThrough) {
- if (readThrough != this.readThrough) {
- this.readThrough = readThrough;
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- (fields.get(i.next())).setReadThrough(readThrough);
- }
- }
- }
-
- /*
- * Sets the editor's read-through mode to the specified status. Don't add a
- * JavaDoc comment here, we use the default one from the interface.
- */
- @Override
- public void setWriteThrough(boolean writeThrough) throws SourceException,
- InvalidValueException {
- if (writeThrough != this.writeThrough) {
- this.writeThrough = writeThrough;
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- (fields.get(i.next())).setWriteThrough(writeThrough);
- }
- }
- }
-
- /**
- * Adds a new property to form and create corresponding field.
- *
- * @see com.vaadin.data.Item#addItemProperty(Object, Property)
- */
- @Override
- public boolean addItemProperty(Object id, Property property) {
-
- // Checks inputs
- if (id == null || property == null) {
- throw new NullPointerException("Id and property must be non-null");
- }
-
- // Checks that the property id is not reserved
- if (propertyIds.contains(id)) {
- return false;
- }
-
- propertyIds.add(id);
- ownProperties.put(id, property);
-
- // Gets suitable field
- final Field<?> field = fieldFactory.createField(this, id, this);
- if (field == null) {
- return false;
- }
-
- // Configures the field
- bindPropertyToField(id, property, field);
-
- // Register and attach the created field
- addField(id, field);
-
- return true;
- }
-
- /**
- * Registers the field with the form and adds the field to the form layout.
- *
- * <p>
- * The property id must not be already used in the form.
- * </p>
- *
- * <p>
- * This field is added to the layout using the
- * {@link #attachField(Object, Field)} method.
- * </p>
- *
- * @param propertyId
- * the Property id the the field.
- * @param field
- * the field which should be added to the form.
- */
- public void addField(Object propertyId, Field<?> field) {
- registerField(propertyId, field);
- attachField(propertyId, field);
- requestRepaint();
- }
-
- /**
- * Register the field with the form. All registered fields are validated
- * when the form is validated and also committed when the form is committed.
- *
- * <p>
- * The property id must not be already used in the form.
- * </p>
- *
- *
- * @param propertyId
- * the Property id of the field.
- * @param field
- * the Field that should be registered
- */
- private void registerField(Object propertyId, Field<?> field) {
- if (propertyId == null || field == null) {
- return;
- }
-
- fields.put(propertyId, field);
- field.addListener(fieldValueChangeListener);
- if (!propertyIds.contains(propertyId)) {
- // adding a field directly
- propertyIds.addLast(propertyId);
- }
-
- // Update the read and write through status and immediate to match the
- // form.
- // Should this also include invalidCommitted (#3993)?
- field.setReadThrough(readThrough);
- field.setWriteThrough(writeThrough);
- if (isImmediate() && field instanceof AbstractComponent) {
- ((AbstractComponent) field).setImmediate(true);
- }
- }
-
- /**
- * Adds the field to the form layout.
- * <p>
- * The field is added to the form layout in the default position (the
- * position used by {@link Layout#addComponent(Component)}. If the
- * underlying layout is a {@link CustomLayout} the field is added to the
- * CustomLayout location given by the string representation of the property
- * id using {@link CustomLayout#addComponent(Component, String)}.
- * </p>
- *
- * <p>
- * Override this method to control how the fields are added to the layout.
- * </p>
- *
- * @param propertyId
- * @param field
- */
- protected void attachField(Object propertyId, Field field) {
- if (propertyId == null || field == null) {
- return;
- }
-
- Layout layout = getLayout();
- if (layout instanceof CustomLayout) {
- ((CustomLayout) layout).addComponent(field, propertyId.toString());
- } else {
- layout.addComponent(field);
- }
-
- }
-
- /**
- * The property identified by the property id.
- *
- * <p>
- * The property data source of the field specified with property id is
- * returned. If there is a (with specified property id) having no data
- * source, the field is returned instead of the data source.
- * </p>
- *
- * @see com.vaadin.data.Item#getItemProperty(Object)
- */
- @Override
- public Property<?> getItemProperty(Object id) {
- final Field<?> field = fields.get(id);
- if (field == null) {
- // field does not exist or it is not (yet) created for this property
- return ownProperties.get(id);
- }
- final Property<?> property = field.getPropertyDataSource();
-
- if (property != null) {
- return property;
- } else {
- return field;
- }
- }
-
- /**
- * Gets the field identified by the propertyid.
- *
- * @param propertyId
- * the id of the property.
- */
- public Field<?> getField(Object propertyId) {
- return fields.get(propertyId);
- }
-
- /* Documented in interface */
- @Override
- public Collection<?> getItemPropertyIds() {
- return Collections.unmodifiableCollection(propertyIds);
- }
-
- /**
- * Removes the property and corresponding field from the form.
- *
- * @see com.vaadin.data.Item#removeItemProperty(Object)
- */
- @Override
- public boolean removeItemProperty(Object id) {
- ownProperties.remove(id);
-
- final Field<?> field = fields.get(id);
-
- if (field != null) {
- propertyIds.remove(id);
- fields.remove(id);
- detachField(field);
- field.removeListener(fieldValueChangeListener);
- return true;
- }
-
- return false;
- }
-
- /**
- * Called when a form field is detached from a Form. Typically when a new
- * Item is assigned to Form via {@link #setItemDataSource(Item)}.
- * <p>
- * Override this method to control how the fields are removed from the
- * layout.
- * </p>
- *
- * @param field
- * the field to be detached from the forms layout.
- */
- protected void detachField(final Field field) {
- Component p = field.getParent();
- if (p instanceof ComponentContainer) {
- ((ComponentContainer) p).removeComponent(field);
- }
- }
-
- /**
- * Removes all properties and fields from the form.
- *
- * @return the Success of the operation. Removal of all fields succeeded if
- * (and only if) the return value is <code>true</code>.
- */
- public boolean removeAllProperties() {
- final Object[] properties = propertyIds.toArray();
- boolean success = true;
-
- for (int i = 0; i < properties.length; i++) {
- if (!removeItemProperty(properties[i])) {
- success = false;
- }
- }
-
- return success;
- }
-
- /* Documented in the interface */
- @Override
- public Item getItemDataSource() {
- return itemDatasource;
- }
-
- /**
- * Sets the item datasource for the form.
- *
- * <p>
- * Setting item datasource clears any fields, the form might contain and
- * adds all the properties as fields to the form.
- * </p>
- *
- * @see com.vaadin.data.Item.Viewer#setItemDataSource(Item)
- */
- @Override
- public void setItemDataSource(Item newDataSource) {
- setItemDataSource(newDataSource,
- newDataSource != null ? newDataSource.getItemPropertyIds()
- : null);
- }
-
- /**
- * Set the item datasource for the form, but limit the form contents to
- * specified properties of the item.
- *
- * <p>
- * Setting item datasource clears any fields, the form might contain and
- * adds the specified the properties as fields to the form, in the specified
- * order.
- * </p>
- *
- * @see com.vaadin.data.Item.Viewer#setItemDataSource(Item)
- */
- public void setItemDataSource(Item newDataSource, Collection<?> propertyIds) {
-
- if (getLayout() instanceof GridLayout) {
- GridLayout gl = (GridLayout) getLayout();
- if (gridlayoutCursorX == -1) {
- // first setItemDataSource, remember initial cursor
- gridlayoutCursorX = gl.getCursorX();
- gridlayoutCursorY = gl.getCursorY();
- } else {
- // restore initial cursor
- gl.setCursorX(gridlayoutCursorX);
- gl.setCursorY(gridlayoutCursorY);
- }
- }
-
- // Removes all fields first from the form
- removeAllProperties();
-
- // Sets the datasource
- itemDatasource = newDataSource;
-
- // If the new datasource is null, just set null datasource
- if (itemDatasource == null) {
- requestRepaint();
- return;
- }
-
- // Adds all the properties to this form
- for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) {
- final Object id = i.next();
- final Property<?> property = itemDatasource.getItemProperty(id);
- if (id != null && property != null) {
- final Field<?> f = fieldFactory.createField(itemDatasource, id,
- this);
- if (f != null) {
- bindPropertyToField(id, property, f);
- addField(id, f);
- }
- }
- }
- }
-
- /**
- * Binds an item property to a field. The default behavior is to bind
- * property straight to Field. If Property.Viewer type property (e.g.
- * PropertyFormatter) is already set for field, the property is bound to
- * that Property.Viewer.
- *
- * @param propertyId
- * @param property
- * @param field
- * @since 6.7.3
- */
- protected void bindPropertyToField(final Object propertyId,
- final Property property, final Field field) {
- // check if field has a property that is Viewer set. In that case we
- // expect developer has e.g. PropertyFormatter that he wishes to use and
- // assign the property to the Viewer instead.
- boolean hasFilterProperty = field.getPropertyDataSource() != null
- && (field.getPropertyDataSource() instanceof Property.Viewer);
- if (hasFilterProperty) {
- ((Property.Viewer) field.getPropertyDataSource())
- .setPropertyDataSource(property);
- } else {
- field.setPropertyDataSource(property);
- }
- }
-
- /**
- * Gets the layout of the form.
- *
- * <p>
- * By default form uses <code>OrderedLayout</code> with <code>form</code>
- * -style.
- * </p>
- *
- * @return the Layout of the form.
- */
- public Layout getLayout() {
- return (Layout) getState().getLayout();
- }
-
- /**
- * Sets the layout of the form.
- *
- * <p>
- * If set to null then Form uses a FormLayout by default.
- * </p>
- *
- * @param layout
- * the layout of the form.
- */
- public void setLayout(Layout layout) {
-
- // Use orderedlayout by default
- if (layout == null) {
- layout = new FormLayout();
- }
-
- // reset cursor memory
- gridlayoutCursorX = -1;
- gridlayoutCursorY = -1;
-
- // Move fields from previous layout
- if (getLayout() != null) {
- final Object[] properties = propertyIds.toArray();
- for (int i = 0; i < properties.length; i++) {
- Field<?> f = getField(properties[i]);
- detachField(f);
- if (layout instanceof CustomLayout) {
- ((CustomLayout) layout).addComponent(f,
- properties[i].toString());
- } else {
- layout.addComponent(f);
- }
- }
-
- getLayout().setParent(null);
- }
-
- // Replace the previous layout
- layout.setParent(this);
- getState().setLayout(layout);
-
- // Hierarchy has changed so we need to repaint (this could be a
- // hierarchy repaint only)
- requestRepaint();
- }
-
- /**
- * Sets the form field to be selectable from static list of changes.
- *
- * <p>
- * The list values and descriptions are given as array. The value-array must
- * contain the current value of the field and the lengths of the arrays must
- * match. Null values are not supported.
- * </p>
- *
- * Note: since Vaadin 7.0, returns an {@link AbstractSelect} instead of a
- * {@link Select}.
- *
- * @param propertyId
- * the id of the property.
- * @param values
- * @param descriptions
- * @return the select property generated
- */
- public AbstractSelect replaceWithSelect(Object propertyId, Object[] values,
- Object[] descriptions) {
-
- // Checks the parameters
- if (propertyId == null || values == null || descriptions == null) {
- throw new NullPointerException("All parameters must be non-null");
- }
- if (values.length != descriptions.length) {
- throw new IllegalArgumentException(
- "Value and description list are of different size");
- }
-
- // Gets the old field
- final Field<?> oldField = fields.get(propertyId);
- if (oldField == null) {
- throw new IllegalArgumentException("Field with given propertyid '"
- + propertyId.toString() + "' can not be found.");
- }
- final Object value = oldField.getPropertyDataSource() == null ? oldField
- .getValue() : oldField.getPropertyDataSource().getValue();
-
- // Checks that the value exists and check if the select should
- // be forced in multiselect mode
- boolean found = false;
- boolean isMultiselect = false;
- for (int i = 0; i < values.length && !found; i++) {
- if (values[i] == value
- || (value != null && value.equals(values[i]))) {
- found = true;
- }
- }
- if (value != null && !found) {
- if (value instanceof Collection) {
- for (final Iterator<?> it = ((Collection<?>) value).iterator(); it
- .hasNext();) {
- final Object val = it.next();
- found = false;
- for (int i = 0; i < values.length && !found; i++) {
- if (values[i] == val
- || (val != null && val.equals(values[i]))) {
- found = true;
- }
- }
- if (!found) {
- throw new IllegalArgumentException(
- "Currently selected value '" + val
- + "' of property '"
- + propertyId.toString()
- + "' was not found");
- }
- }
- isMultiselect = true;
- } else {
- throw new IllegalArgumentException("Current value '" + value
- + "' of property '" + propertyId.toString()
- + "' was not found");
- }
- }
-
- // Creates the new field matching to old field parameters
- final AbstractSelect newField = isMultiselect ? new ListSelect()
- : new Select();
- newField.setCaption(oldField.getCaption());
- newField.setReadOnly(oldField.isReadOnly());
- newField.setReadThrough(oldField.isReadThrough());
- newField.setWriteThrough(oldField.isWriteThrough());
-
- // Creates the options list
- newField.addContainerProperty("desc", String.class, "");
- newField.setItemCaptionPropertyId("desc");
- for (int i = 0; i < values.length; i++) {
- Object id = values[i];
- final Item item;
- if (id == null) {
- id = newField.addItem();
- item = newField.getItem(id);
- newField.setNullSelectionItemId(id);
- } else {
- item = newField.addItem(id);
- }
-
- if (item != null) {
- item.getItemProperty("desc").setValue(
- descriptions[i].toString());
- }
- }
-
- // Sets the property data source
- final Property<?> property = oldField.getPropertyDataSource();
- oldField.setPropertyDataSource(null);
- newField.setPropertyDataSource(property);
-
- // Replaces the old field with new one
- getLayout().replaceComponent(oldField, newField);
- fields.put(propertyId, newField);
- newField.addListener(fieldValueChangeListener);
- oldField.removeListener(fieldValueChangeListener);
-
- return newField;
- }
-
- /**
- * Checks the validity of the Form and all of its fields.
- *
- * @see com.vaadin.data.Validatable#validate()
- */
- @Override
- public void validate() throws InvalidValueException {
- super.validate();
- for (final Iterator<Object> i = propertyIds.iterator(); i.hasNext();) {
- (fields.get(i.next())).validate();
- }
- }
-
- /**
- * Checks the validabtable object accept invalid values.
- *
- * @see com.vaadin.data.Validatable#isInvalidAllowed()
- */
- @Override
- public boolean isInvalidAllowed() {
- return true;
- }
-
- /**
- * Should the validabtable object accept invalid values.
- *
- * @see com.vaadin.data.Validatable#setInvalidAllowed(boolean)
- */
- @Override
- public void setInvalidAllowed(boolean invalidValueAllowed)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Sets the component's to read-only mode to the specified state.
- *
- * @see com.vaadin.ui.Component#setReadOnly(boolean)
- */
- @Override
- public void setReadOnly(boolean readOnly) {
- super.setReadOnly(readOnly);
- for (final Iterator<?> i = propertyIds.iterator(); i.hasNext();) {
- (fields.get(i.next())).setReadOnly(readOnly);
- }
- }
-
- /**
- * Sets the field factory used by this Form to genarate Fields for
- * properties.
- *
- * {@link FormFieldFactory} is used to create fields for form properties.
- * {@link DefaultFieldFactory} is used by default.
- *
- * @param fieldFactory
- * the new factory used to create the fields.
- * @see Field
- * @see FormFieldFactory
- */
- public void setFormFieldFactory(FormFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
- }
-
- /**
- * Get the field factory of the form.
- *
- * @return the FormFieldFactory Factory used to create the fields.
- */
- public FormFieldFactory getFormFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Gets the field type.
- *
- * @see com.vaadin.ui.AbstractField#getType()
- */
- @Override
- public Class<?> getType() {
- if (getPropertyDataSource() != null) {
- return getPropertyDataSource().getType();
- }
- return Object.class;
- }
-
- /**
- * Sets the internal value.
- *
- * This is relevant when the Form is used as Field.
- *
- * @see com.vaadin.ui.AbstractField#setInternalValue(java.lang.Object)
- */
- @Override
- protected void setInternalValue(Object newValue) {
- // Stores the old value
- final Object oldValue = propertyValue;
-
- // Sets the current Value
- super.setInternalValue(newValue);
- propertyValue = newValue;
-
- // Ignores form updating if data object has not changed.
- if (oldValue != newValue) {
- setFormDataSource(newValue, getVisibleItemProperties());
- }
- }
-
- /**
- * Gets the first focusable field in form. If there are enabled,
- * non-read-only fields, the first one of them is returned. Otherwise, the
- * field for the first property (or null if none) is returned.
- *
- * @return the Field.
- */
- private Field<?> getFirstFocusableField() {
- if (getItemPropertyIds() != null) {
- for (Object id : getItemPropertyIds()) {
- if (id != null) {
- Field<?> field = getField(id);
- if (field.isEnabled() && !field.isReadOnly()) {
- return field;
- }
- }
- }
- // fallback: first field if none of the fields is enabled and
- // writable
- Object id = getItemPropertyIds().iterator().next();
- if (id != null) {
- return getField(id);
- }
- }
- return null;
- }
-
- /**
- * Updates the internal form datasource.
- *
- * Method setFormDataSource.
- *
- * @param data
- * @param properties
- */
- protected void setFormDataSource(Object data, Collection<?> properties) {
-
- // If data is an item use it.
- Item item = null;
- if (data instanceof Item) {
- item = (Item) data;
- } else if (data != null) {
- item = new BeanItem<Object>(data);
- }
-
- // Sets the datasource to form
- if (item != null && properties != null) {
- // Shows only given properties
- this.setItemDataSource(item, properties);
- } else {
- // Shows all properties
- this.setItemDataSource(item);
- }
- }
-
- /**
- * Returns the visibleProperties.
- *
- * @return the Collection of visible Item properites.
- */
- public Collection<?> getVisibleItemProperties() {
- return visibleItemProperties;
- }
-
- /**
- * Sets the visibleProperties.
- *
- * @param visibleProperties
- * the visibleProperties to set.
- */
- public void setVisibleItemProperties(Collection<?> visibleProperties) {
- visibleItemProperties = visibleProperties;
- Object value = getValue();
- if (value == null) {
- value = itemDatasource;
- }
- setFormDataSource(value, getVisibleItemProperties());
- }
-
- /**
- * Sets the visibleProperties.
- *
- * @param visibleProperties
- * the visibleProperties to set.
- */
- public void setVisibleItemProperties(Object[] visibleProperties) {
- LinkedList<Object> v = new LinkedList<Object>();
- for (int i = 0; i < visibleProperties.length; i++) {
- v.add(visibleProperties[i]);
- }
- setVisibleItemProperties(v);
- }
-
- /**
- * Focuses the first field in the form.
- *
- * @see com.vaadin.ui.Component.Focusable#focus()
- */
- @Override
- public void focus() {
- final Field<?> f = getFirstFocusableField();
- if (f != null) {
- f.focus();
- }
- }
-
- /**
- * Sets the Tabulator index of this Focusable component.
- *
- * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
- */
- @Override
- public void setTabIndex(int tabIndex) {
- super.setTabIndex(tabIndex);
- for (final Iterator<?> i = getItemPropertyIds().iterator(); i.hasNext();) {
- (getField(i.next())).setTabIndex(tabIndex);
- }
- }
-
- /**
- * Setting the form to be immediate also sets all the fields of the form to
- * the same state.
- */
- @Override
- public void setImmediate(boolean immediate) {
- super.setImmediate(immediate);
- for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
- Field<?> f = i.next();
- if (f instanceof AbstractComponent) {
- ((AbstractComponent) f).setImmediate(immediate);
- }
- }
- }
-
- /** Form is empty if all of its fields are empty. */
- @Override
- protected boolean isEmpty() {
-
- for (Iterator<Field<?>> i = fields.values().iterator(); i.hasNext();) {
- Field<?> f = i.next();
- if (f instanceof AbstractField) {
- if (!((AbstractField<?>) f).isEmpty()) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- /**
- * Adding validators directly to form is not supported.
- *
- * Add the validators to form fields instead.
- */
- @Override
- public void addValidator(Validator validator) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns a layout that is rendered below normal form contents. This area
- * can be used for example to include buttons related to form contents.
- *
- * @return layout rendered below normal form contents.
- */
- public Layout getFooter() {
- return (Layout) getState().getFooter();
- }
-
- /**
- * Sets the layout that is rendered below normal form contents. Setting this
- * to null will cause an empty HorizontalLayout to be rendered in the
- * footer.
- *
- * @param footer
- * the new footer layout
- */
- public void setFooter(Layout footer) {
- if (getFooter() != null) {
- getFooter().setParent(null);
- }
- if (footer == null) {
- footer = new HorizontalLayout();
- }
-
- getState().setFooter(footer);
- footer.setParent(this);
-
- // Hierarchy has changed so we need to repaint (this could be a
- // hierarchy repaint only)
- requestRepaint();
-
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- if (getParent() != null && !getParent().isEnabled()) {
- // some ancestor still disabled, don't update children
- return;
- } else {
- getLayout().requestRepaintAll();
- }
- }
-
- /*
- * ACTIONS
- */
-
- /**
- * Gets the {@link ActionManager} responsible for handling {@link Action}s
- * added to this Form.<br/>
- * Note that Form has another ActionManager inherited from
- * {@link AbstractField}. The ownActionManager handles Actions attached to
- * this Form specifically, while the ActionManager in AbstractField
- * delegates to the containing Window (i.e global Actions).
- *
- * @return
- */
- protected ActionManager getOwnActionManager() {
- if (ownActionManager == null) {
- ownActionManager = new ActionManager(this);
- }
- return ownActionManager;
- }
-
- @Override
- public void addActionHandler(Handler actionHandler) {
- getOwnActionManager().addActionHandler(actionHandler);
- }
-
- @Override
- public void removeActionHandler(Handler actionHandler) {
- if (ownActionManager != null) {
- ownActionManager.removeActionHandler(actionHandler);
- }
- }
-
- /**
- * Removes all action handlers
- */
- public void removeAllActionHandlers() {
- if (ownActionManager != null) {
- ownActionManager.removeAllActionHandlers();
- }
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void addAction(
- T action) {
- getOwnActionManager().addAction(action);
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void removeAction(
- T action) {
- if (ownActionManager != null) {
- ownActionManager.removeAction(action);
- }
- }
-
- @Override
- public Iterator<Component> iterator() {
- return getComponentIterator();
- }
-
- /**
- * Modifiable and Serializable Iterator for the components, used by
- * {@link Form#getComponentIterator()}.
- */
- private class ComponentIterator implements Iterator<Component>,
- Serializable {
-
- int i = 0;
-
- @Override
- public boolean hasNext() {
- if (i < getComponentCount()) {
- return true;
- }
- return false;
- }
-
- @Override
- public Component next() {
- if (!hasNext()) {
- return null;
- }
- i++;
- if (i == 1) {
- return getLayout() != null ? getLayout() : getFooter();
- } else if (i == 2) {
- return getFooter();
- }
- return null;
- }
-
- @Override
- public void remove() {
- if (i == 1) {
- if (getLayout() != null) {
- setLayout(null);
- i = 0;
- } else {
- setFooter(null);
- }
- } else if (i == 2) {
- setFooter(null);
- }
- }
- }
-
- @Override
- public Iterator<Component> getComponentIterator() {
- return new ComponentIterator();
- }
-
- public int getComponentCount() {
- int count = 0;
- if (getLayout() != null) {
- count++;
- }
- if (getFooter() != null) {
- count++;
- }
-
- return count;
- }
-
- @Override
- public boolean isComponentVisible(Component childComponent) {
- return true;
- };
-}
diff --git a/src/com/vaadin/ui/FormFieldFactory.java b/src/com/vaadin/ui/FormFieldFactory.java
deleted file mode 100644
index 1efa05c5f5..0000000000
--- a/src/com/vaadin/ui/FormFieldFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.data.Item;
-
-/**
- * Factory interface for creating new Field-instances based on {@link Item},
- * property id and uiContext (the component responsible for displaying fields).
- * Currently this interface is used by {@link Form}, but might later be used by
- * some other components for {@link Field} generation.
- *
- * <p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.0
- * @see TableFieldFactory
- */
-public interface FormFieldFactory extends Serializable {
- /**
- * Creates a field based on the item, property id and the component (most
- * commonly {@link Form}) where the Field will be presented.
- *
- * @param item
- * the item where the property belongs to.
- * @param propertyId
- * the Id of the property.
- * @param uiContext
- * the component where the field is presented, most commonly this
- * is {@link Form}. uiContext will not necessary be the parent
- * component of the field, but the one that is responsible for
- * creating it.
- * @return Field the field suitable for editing the specified data.
- */
- Field<?> createField(Item item, Object propertyId, Component uiContext);
-}
diff --git a/src/com/vaadin/ui/FormLayout.java b/src/com/vaadin/ui/FormLayout.java
deleted file mode 100644
index c0be784a7b..0000000000
--- a/src/com/vaadin/ui/FormLayout.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-/**
- * FormLayout is used by {@link Form} to layout fields. It may also be used
- * separately without {@link Form}.
- *
- * FormLayout is a close relative to vertical {@link OrderedLayout}, but in
- * FormLayout caption is rendered on left side of component. Required and
- * validation indicators are between captions and fields.
- *
- * FormLayout does not currently support some advanced methods from
- * OrderedLayout like setExpandRatio and setComponentAlignment.
- *
- * FormLayout by default has component spacing on. Also margin top and margin
- * bottom are by default on.
- *
- */
-public class FormLayout extends AbstractOrderedLayout {
-
- public FormLayout() {
- super();
- setSpacing(true);
- setMargin(true, false, true, false);
- setWidth(100, UNITS_PERCENTAGE);
- }
-
-}
diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java
deleted file mode 100644
index 2391a9cd3a..0000000000
--- a/src/com/vaadin/ui/GridLayout.java
+++ /dev/null
@@ -1,1415 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import com.vaadin.event.LayoutEvents.LayoutClickEvent;
-import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
-import com.vaadin.shared.Connector;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.gridlayout.GridLayoutServerRpc;
-import com.vaadin.shared.ui.gridlayout.GridLayoutState;
-import com.vaadin.terminal.LegacyPaint;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
-
-/**
- * A layout where the components are laid out on a grid using cell coordinates.
- *
- * <p>
- * The GridLayout also maintains a cursor for adding components in
- * left-to-right, top-to-bottom order.
- * </p>
- *
- * <p>
- * Each component in a <code>GridLayout</code> uses a defined
- * {@link GridLayout.Area area} (column1,row1,column2,row2) from the grid. The
- * components may not overlap with the existing components - if you try to do so
- * you will get an {@link OverlapsException}. Adding a component with cursor
- * automatically extends the grid by increasing the grid height.
- * </p>
- *
- * <p>
- * The grid coordinates, which are specified by a row and column index, always
- * start from 0 for the topmost row and the leftmost column.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class GridLayout extends AbstractLayout implements
- Layout.AlignmentHandler, Layout.SpacingHandler, LayoutClickNotifier,
- Vaadin6Component {
-
- private GridLayoutServerRpc rpc = new GridLayoutServerRpc() {
-
- @Override
- public void layoutClick(MouseEventDetails mouseDetails,
- Connector clickedConnector) {
- fireEvent(LayoutClickEvent.createEvent(GridLayout.this,
- mouseDetails, clickedConnector));
-
- }
- };
- /**
- * Cursor X position: this is where the next component with unspecified x,y
- * is inserted
- */
- private int cursorX = 0;
-
- /**
- * Cursor Y position: this is where the next component with unspecified x,y
- * is inserted
- */
- private int cursorY = 0;
-
- /**
- * Contains all items that are placed on the grid. These are components with
- * grid area definition.
- */
- private final LinkedList<Area> areas = new LinkedList<Area>();
-
- /**
- * Mapping from components to their respective areas.
- */
- private final LinkedList<Component> components = new LinkedList<Component>();
-
- /**
- * Mapping from components to alignments (horizontal + vertical).
- */
- private Map<Component, Alignment> componentToAlignment = new HashMap<Component, Alignment>();
-
- private static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT;
-
- /**
- * Has there been rows inserted or deleted in the middle of the layout since
- * the last paint operation.
- */
- private boolean structuralChange = false;
-
- private Map<Integer, Float> columnExpandRatio = new HashMap<Integer, Float>();
- private Map<Integer, Float> rowExpandRatio = new HashMap<Integer, Float>();
-
- /**
- * Constructor for a grid of given size (number of columns and rows).
- *
- * The grid may grow or shrink later. Grid grows automatically if you add
- * components outside its area.
- *
- * @param columns
- * Number of columns in the grid.
- * @param rows
- * Number of rows in the grid.
- */
- public GridLayout(int columns, int rows) {
- setColumns(columns);
- setRows(rows);
- registerRpc(rpc);
- }
-
- /**
- * Constructs an empty (1x1) grid layout that is extended as needed.
- */
- public GridLayout() {
- this(1, 1);
- }
-
- @Override
- public GridLayoutState getState() {
- return (GridLayoutState) super.getState();
- }
-
- /**
- * <p>
- * Adds a component to the grid in the specified area. The area is defined
- * by specifying the upper left corner (column1, row1) and the lower right
- * corner (column2, row2) of the area. The coordinates are zero-based.
- * </p>
- *
- * <p>
- * If the area overlaps with any of the existing components already present
- * in the grid, the operation will fail and an {@link OverlapsException} is
- * thrown.
- * </p>
- *
- * @param component
- * the component to be added.
- * @param column1
- * the column of the upper left corner of the area <code>c</code>
- * is supposed to occupy. The leftmost column has index 0.
- * @param row1
- * the row of the upper left corner of the area <code>c</code> is
- * supposed to occupy. The topmost row has index 0.
- * @param column2
- * the column of the lower right corner of the area
- * <code>c</code> is supposed to occupy.
- * @param row2
- * the row of the lower right corner of the area <code>c</code>
- * is supposed to occupy.
- * @throws OverlapsException
- * if the new component overlaps with any of the components
- * already in the grid.
- * @throws OutOfBoundsException
- * if the cells are outside the grid area.
- */
- public void addComponent(Component component, int column1, int row1,
- int column2, int row2) throws OverlapsException,
- OutOfBoundsException {
-
- if (component == null) {
- throw new NullPointerException("Component must not be null");
- }
-
- // Checks that the component does not already exist in the container
- if (components.contains(component)) {
- throw new IllegalArgumentException(
- "Component is already in the container");
- }
-
- // Creates the area
- final Area area = new Area(component, column1, row1, column2, row2);
-
- // Checks the validity of the coordinates
- if (column2 < column1 || row2 < row1) {
- throw new IllegalArgumentException(
- "Illegal coordinates for the component");
- }
- if (column1 < 0 || row1 < 0 || column2 >= getColumns()
- || row2 >= getRows()) {
- throw new OutOfBoundsException(area);
- }
-
- // Checks that newItem does not overlap with existing items
- checkExistingOverlaps(area);
-
- // Inserts the component to right place at the list
- // Respect top-down, left-right ordering
- // component.setParent(this);
- final Iterator<Area> i = areas.iterator();
- int index = 0;
- boolean done = false;
- while (!done && i.hasNext()) {
- final Area existingArea = i.next();
- if ((existingArea.row1 >= row1 && existingArea.column1 > column1)
- || existingArea.row1 > row1) {
- areas.add(index, area);
- components.add(index, component);
- done = true;
- }
- index++;
- }
- if (!done) {
- areas.addLast(area);
- components.addLast(component);
- }
-
- // Attempt to add to super
- try {
- super.addComponent(component);
- } catch (IllegalArgumentException e) {
- areas.remove(area);
- components.remove(component);
- throw e;
- }
-
- // update cursor position, if it's within this area; use first position
- // outside this area, even if it's occupied
- if (cursorX >= column1 && cursorX <= column2 && cursorY >= row1
- && cursorY <= row2) {
- // cursor within area
- cursorX = column2 + 1; // one right of area
- if (cursorX >= getColumns()) {
- // overflowed columns
- cursorX = 0; // first col
- // move one row down, or one row under the area
- cursorY = (column1 == 0 ? row2 : row1) + 1;
- } else {
- cursorY = row1;
- }
- }
-
- requestRepaint();
- }
-
- /**
- * Tests if the given area overlaps with any of the items already on the
- * grid.
- *
- * @param area
- * the Area to be checked for overlapping.
- * @throws OverlapsException
- * if <code>area</code> overlaps with any existing area.
- */
- private void checkExistingOverlaps(Area area) throws OverlapsException {
- for (final Iterator<Area> i = areas.iterator(); i.hasNext();) {
- final Area existingArea = i.next();
- if (existingArea.overlaps(area)) {
- // Component not added, overlaps with existing component
- throw new OverlapsException(existingArea);
- }
- }
- }
-
- /**
- * Adds the component to the grid in cells column1,row1 (NortWest corner of
- * the area.) End coordinates (SouthEast corner of the area) are the same as
- * column1,row1. The coordinates are zero-based. Component width and height
- * is 1.
- *
- * @param component
- * the component to be added.
- * @param column
- * the column index, starting from 0.
- * @param row
- * the row index, starting from 0.
- * @throws OverlapsException
- * if the new component overlaps with any of the components
- * already in the grid.
- * @throws OutOfBoundsException
- * if the cell is outside the grid area.
- */
- public void addComponent(Component component, int column, int row)
- throws OverlapsException, OutOfBoundsException {
- this.addComponent(component, column, row, column, row);
- }
-
- /**
- * Forces the next component to be added at the beginning of the next line.
- *
- * <p>
- * Sets the cursor column to 0 and increments the cursor row by one.
- * </p>
- *
- * <p>
- * By calling this function you can ensure that no more components are added
- * right of the previous component.
- * </p>
- *
- * @see #space()
- */
- public void newLine() {
- cursorX = 0;
- cursorY++;
- }
-
- /**
- * Moves the cursor forward by one. If the cursor goes out of the right grid
- * border, it is moved to the first column of the next row.
- *
- * @see #newLine()
- */
- public void space() {
- cursorX++;
- if (cursorX >= getColumns()) {
- cursorX = 0;
- cursorY++;
- }
- }
-
- /**
- * Adds the component into this container to the cursor position. If the
- * cursor position is already occupied, the cursor is moved forwards to find
- * free position. If the cursor goes out from the bottom of the grid, the
- * grid is automatically extended.
- *
- * @param component
- * the component to be added.
- */
- @Override
- public void addComponent(Component component) {
-
- // Finds first available place from the grid
- Area area;
- boolean done = false;
- while (!done) {
- try {
- area = new Area(component, cursorX, cursorY, cursorX, cursorY);
- checkExistingOverlaps(area);
- done = true;
- } catch (final OverlapsException e) {
- space();
- }
- }
-
- // Extends the grid if needed
- if (cursorX >= getColumns()) {
- setColumns(cursorX + 1);
- }
- if (cursorY >= getRows()) {
- setRows(cursorY + 1);
- }
-
- addComponent(component, cursorX, cursorY);
- }
-
- /**
- * Removes the specified component from the layout.
- *
- * @param component
- * the component to be removed.
- */
- @Override
- public void removeComponent(Component component) {
-
- // Check that the component is contained in the container
- if (component == null || !components.contains(component)) {
- return;
- }
-
- Area area = null;
- for (final Iterator<Area> i = areas.iterator(); area == null
- && i.hasNext();) {
- final Area a = i.next();
- if (a.getComponent() == component) {
- area = a;
- }
- }
-
- components.remove(component);
- if (area != null) {
- areas.remove(area);
- }
-
- componentToAlignment.remove(component);
-
- super.removeComponent(component);
-
- requestRepaint();
- }
-
- /**
- * Removes the component specified by its cell coordinates.
- *
- * @param column
- * the component's column, starting from 0.
- * @param row
- * the component's row, starting from 0.
- */
- public void removeComponent(int column, int row) {
-
- // Finds the area
- for (final Iterator<Area> i = areas.iterator(); i.hasNext();) {
- final Area area = i.next();
- if (area.getColumn1() == column && area.getRow1() == row) {
- removeComponent(area.getComponent());
- return;
- }
- }
- }
-
- /**
- * Gets an Iterator for the components contained in the layout. By using the
- * Iterator it is possible to step through the contents of the layout.
- *
- * @return the Iterator of the components inside the layout.
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return Collections.unmodifiableCollection(components).iterator();
- }
-
- /**
- * Gets the number of components contained in the layout. Consistent with
- * the iterator returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
- @Override
- public int getComponentCount() {
- return components.size();
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // TODO Remove once Vaadin6Component is no longer implemented
- }
-
- /**
- * Paints the contents of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- // TODO refactor attribute names in future release.
- target.addAttribute("structuralChange", structuralChange);
- structuralChange = false;
-
- // Area iterator
- final Iterator<Area> areaiterator = areas.iterator();
-
- // Current item to be processed (fetch first item)
- Area area = areaiterator.hasNext() ? (Area) areaiterator.next() : null;
-
- // Collects rowspan related information here
- final HashMap<Integer, Integer> cellUsed = new HashMap<Integer, Integer>();
-
- // Empty cell collector
- int emptyCells = 0;
-
- final String[] alignmentsArray = new String[components.size()];
- final Integer[] columnExpandRatioArray = new Integer[getColumns()];
- final Integer[] rowExpandRatioArray = new Integer[getRows()];
-
- int realColExpandRatioSum = 0;
- float colSum = getExpandRatioSum(columnExpandRatio);
- if (colSum == 0) {
- // no columns has been expanded, all cols have same expand
- // rate
- float equalSize = 1 / (float) getColumns();
- int myRatio = Math.round(equalSize * 1000);
- for (int i = 0; i < getColumns(); i++) {
- columnExpandRatioArray[i] = myRatio;
- }
- realColExpandRatioSum = myRatio * getColumns();
- } else {
- for (int i = 0; i < getColumns(); i++) {
- int myRatio = Math
- .round((getColumnExpandRatio(i) / colSum) * 1000);
- columnExpandRatioArray[i] = myRatio;
- realColExpandRatioSum += myRatio;
- }
- }
-
- boolean equallyDividedRows = false;
- int realRowExpandRatioSum = 0;
- float rowSum = getExpandRatioSum(rowExpandRatio);
- if (rowSum == 0) {
- // no rows have been expanded
- equallyDividedRows = true;
- float equalSize = 1 / (float) getRows();
- int myRatio = Math.round(equalSize * 1000);
- for (int i = 0; i < getRows(); i++) {
- rowExpandRatioArray[i] = myRatio;
- }
- realRowExpandRatioSum = myRatio * getRows();
- }
-
- int index = 0;
-
- // Iterates every applicable row
- for (int cury = 0; cury < getRows(); cury++) {
- target.startTag("gr");
-
- if (!equallyDividedRows) {
- int myRatio = Math
- .round((getRowExpandRatio(cury) / rowSum) * 1000);
- rowExpandRatioArray[cury] = myRatio;
- realRowExpandRatioSum += myRatio;
-
- }
- // Iterates every applicable column
- for (int curx = 0; curx < getColumns(); curx++) {
-
- // Checks if current item is located at curx,cury
- if (area != null && (area.row1 == cury)
- && (area.column1 == curx)) {
-
- // First check if empty cell needs to be rendered
- if (emptyCells > 0) {
- target.startTag("gc");
- target.addAttribute("x", curx - emptyCells);
- target.addAttribute("y", cury);
- if (emptyCells > 1) {
- target.addAttribute("w", emptyCells);
- }
- target.endTag("gc");
- emptyCells = 0;
- }
-
- // Now proceed rendering current item
- final int cols = (area.column2 - area.column1) + 1;
- final int rows = (area.row2 - area.row1) + 1;
- target.startTag("gc");
-
- target.addAttribute("x", curx);
- target.addAttribute("y", cury);
-
- if (cols > 1) {
- target.addAttribute("w", cols);
- }
- if (rows > 1) {
- target.addAttribute("h", rows);
- }
- LegacyPaint.paint(area.getComponent(), target);
-
- alignmentsArray[index++] = String
- .valueOf(getComponentAlignment(area.getComponent())
- .getBitMask());
-
- target.endTag("gc");
-
- // Fetch next item
- if (areaiterator.hasNext()) {
- area = areaiterator.next();
- } else {
- area = null;
- }
-
- // Updates the cellUsed if rowspan needed
- if (rows > 1) {
- int spannedx = curx;
- for (int j = 1; j <= cols; j++) {
- cellUsed.put(new Integer(spannedx), new Integer(
- cury + rows - 1));
- spannedx++;
- }
- }
-
- // Skips the current item's spanned columns
- if (cols > 1) {
- curx += cols - 1;
- }
-
- } else {
-
- // Checks against cellUsed, render space or ignore cell
- if (cellUsed.containsKey(new Integer(curx))) {
-
- // Current column contains already an item,
- // check if rowspan affects at current x,y position
- final int rowspanDepth = cellUsed
- .get(new Integer(curx)).intValue();
-
- if (rowspanDepth >= cury) {
-
- // ignore cell
- // Check if empty cell needs to be rendered
- if (emptyCells > 0) {
- target.startTag("gc");
- target.addAttribute("x", curx - emptyCells);
- target.addAttribute("y", cury);
- if (emptyCells > 1) {
- target.addAttribute("w", emptyCells);
- }
- target.endTag("gc");
-
- emptyCells = 0;
- }
- } else {
-
- // empty cell is needed
- emptyCells++;
-
- // Removes the cellUsed key as it has become
- // obsolete
- cellUsed.remove(Integer.valueOf(curx));
- }
- } else {
-
- // empty cell is needed
- emptyCells++;
- }
- }
-
- } // iterates every column
-
- // Last column handled of current row
-
- // Checks if empty cell needs to be rendered
- if (emptyCells > 0) {
- target.startTag("gc");
- target.addAttribute("x", getColumns() - emptyCells);
- target.addAttribute("y", cury);
- if (emptyCells > 1) {
- target.addAttribute("w", emptyCells);
- }
- target.endTag("gc");
-
- emptyCells = 0;
- }
-
- target.endTag("gr");
- } // iterates every row
-
- // Last row handled
-
- // correct possible rounding error
- if (rowExpandRatioArray.length > 0) {
- rowExpandRatioArray[0] -= realRowExpandRatioSum - 1000;
- }
- if (columnExpandRatioArray.length > 0) {
- columnExpandRatioArray[0] -= realColExpandRatioSum - 1000;
- }
-
- target.addAttribute("colExpand", columnExpandRatioArray);
- target.addAttribute("rowExpand", rowExpandRatioArray);
-
- // Add child component alignment info to layout tag
- target.addAttribute("alignments", alignmentsArray);
-
- }
-
- private float getExpandRatioSum(Map<Integer, Float> ratioMap) {
- float sum = 0;
- for (Iterator<Entry<Integer, Float>> iterator = ratioMap.entrySet()
- .iterator(); iterator.hasNext();) {
- sum += iterator.next().getValue();
- }
- return sum;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.AlignmentHandler#getComponentAlignment(com
- * .vaadin.ui.Component)
- */
- @Override
- public Alignment getComponentAlignment(Component childComponent) {
- Alignment alignment = componentToAlignment.get(childComponent);
- if (alignment == null) {
- return ALIGNMENT_DEFAULT;
- } else {
- return alignment;
- }
- }
-
- /**
- * Defines a rectangular area of cells in a GridLayout.
- *
- * <p>
- * Also maintains a reference to the component contained in the area.
- * </p>
- *
- * <p>
- * The area is specified by the cell coordinates of its upper left corner
- * (column1,row1) and lower right corner (column2,row2). As otherwise with
- * GridLayout, the column and row coordinates start from zero.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class Area implements Serializable {
-
- /**
- * The column of the upper left corner cell of the area.
- */
- private final int column1;
-
- /**
- * The row of the upper left corner cell of the area.
- */
- private int row1;
-
- /**
- * The column of the lower right corner cell of the area.
- */
- private final int column2;
-
- /**
- * The row of the lower right corner cell of the area.
- */
- private int row2;
-
- /**
- * Component painted in the area.
- */
- private Component component;
-
- /**
- * <p>
- * Construct a new area on a grid.
- * </p>
- *
- * @param component
- * the component connected to the area.
- * @param column1
- * The column of the upper left corner cell of the area. The
- * leftmost column has index 0.
- * @param row1
- * The row of the upper left corner cell of the area. The
- * topmost row has index 0.
- * @param column2
- * The column of the lower right corner cell of the area. The
- * leftmost column has index 0.
- * @param row2
- * The row of the lower right corner cell of the area. The
- * topmost row has index 0.
- */
- public Area(Component component, int column1, int row1, int column2,
- int row2) {
- this.column1 = column1;
- this.row1 = row1;
- this.column2 = column2;
- this.row2 = row2;
- this.component = component;
- }
-
- /**
- * Tests if this Area overlaps with another Area.
- *
- * @param other
- * the other Area that is to be tested for overlap with this
- * area
- * @return <code>true</code> if <code>other</code> area overlaps with
- * this on, <code>false</code> if it does not.
- */
- public boolean overlaps(Area other) {
- return column1 <= other.getColumn2() && row1 <= other.getRow2()
- && column2 >= other.getColumn1() && row2 >= other.getRow1();
-
- }
-
- /**
- * Gets the component connected to the area.
- *
- * @return the Component.
- */
- public Component getComponent() {
- return component;
- }
-
- /**
- * Sets the component connected to the area.
- *
- * <p>
- * This function only sets the value in the data structure and does not
- * send any events or set parents.
- * </p>
- *
- * @param newComponent
- * the new connected overriding the existing one.
- */
- protected void setComponent(Component newComponent) {
- component = newComponent;
- }
-
- /**
- * @deprecated Use {@link #getColumn1()} instead.
- */
- @Deprecated
- public int getX1() {
- return getColumn1();
- }
-
- /**
- * Gets the column of the top-left corner cell.
- *
- * @return the column of the top-left corner cell.
- */
- public int getColumn1() {
- return column1;
- }
-
- /**
- * @deprecated Use {@link #getColumn2()} instead.
- */
- @Deprecated
- public int getX2() {
- return getColumn2();
- }
-
- /**
- * Gets the column of the bottom-right corner cell.
- *
- * @return the column of the bottom-right corner cell.
- */
- public int getColumn2() {
- return column2;
- }
-
- /**
- * @deprecated Use {@link #getRow1()} instead.
- */
- @Deprecated
- public int getY1() {
- return getRow1();
- }
-
- /**
- * Gets the row of the top-left corner cell.
- *
- * @return the row of the top-left corner cell.
- */
- public int getRow1() {
- return row1;
- }
-
- /**
- * @deprecated Use {@link #getRow2()} instead.
- */
- @Deprecated
- public int getY2() {
- return getRow2();
- }
-
- /**
- * Gets the row of the bottom-right corner cell.
- *
- * @return the row of the bottom-right corner cell.
- */
- public int getRow2() {
- return row2;
- }
-
- }
-
- /**
- * Gridlayout does not support laying components on top of each other. An
- * <code>OverlapsException</code> is thrown when a component already exists
- * (even partly) at the same space on a grid with the new component.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class OverlapsException extends java.lang.RuntimeException {
-
- private final Area existingArea;
-
- /**
- * Constructs an <code>OverlapsException</code>.
- *
- * @param existingArea
- */
- public OverlapsException(Area existingArea) {
- this.existingArea = existingArea;
- }
-
- @Override
- public String getMessage() {
- StringBuilder sb = new StringBuilder();
- Component component = existingArea.getComponent();
- sb.append(component);
- sb.append("( type = ");
- sb.append(component.getClass().getName());
- if (component.getCaption() != null) {
- sb.append(", caption = \"");
- sb.append(component.getCaption());
- sb.append("\"");
- }
- sb.append(")");
- sb.append(" is already added to ");
- sb.append(existingArea.column1);
- sb.append(",");
- sb.append(existingArea.column1);
- sb.append(",");
- sb.append(existingArea.row1);
- sb.append(",");
- sb.append(existingArea.row2);
- sb.append("(column1, column2, row1, row2).");
-
- return sb.toString();
- }
-
- /**
- * Gets the area .
- *
- * @return the existing area.
- */
- public Area getArea() {
- return existingArea;
- }
- }
-
- /**
- * An <code>Exception</code> object which is thrown when an area exceeds the
- * bounds of the grid.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class OutOfBoundsException extends java.lang.RuntimeException {
-
- private final Area areaOutOfBounds;
-
- /**
- * Constructs an <code>OoutOfBoundsException</code> with the specified
- * detail message.
- *
- * @param areaOutOfBounds
- */
- public OutOfBoundsException(Area areaOutOfBounds) {
- this.areaOutOfBounds = areaOutOfBounds;
- }
-
- /**
- * Gets the area that is out of bounds.
- *
- * @return the area out of Bound.
- */
- public Area getArea() {
- return areaOutOfBounds;
- }
- }
-
- /**
- * Sets the number of columns in the grid. The column count can not be
- * reduced if there are any areas that would be outside of the shrunk grid.
- *
- * @param columns
- * the new number of columns in the grid.
- */
- public void setColumns(int columns) {
-
- // The the param
- if (columns < 1) {
- throw new IllegalArgumentException(
- "The number of columns and rows in the grid must be at least 1");
- }
-
- // In case of no change
- if (getColumns() == columns) {
- return;
- }
-
- // Checks for overlaps
- if (getColumns() > columns) {
- for (final Iterator<Area> i = areas.iterator(); i.hasNext();) {
- final Area area = i.next();
- if (area.column2 >= columns) {
- throw new OutOfBoundsException(area);
- }
- }
- }
-
- getState().setColumns(columns);
-
- requestRepaint();
- }
-
- /**
- * Get the number of columns in the grid.
- *
- * @return the number of columns in the grid.
- */
- public int getColumns() {
- return getState().getColumns();
- }
-
- /**
- * Sets the number of rows in the grid. The number of rows can not be
- * reduced if there are any areas that would be outside of the shrunk grid.
- *
- * @param rows
- * the new number of rows in the grid.
- */
- public void setRows(int rows) {
-
- // The the param
- if (rows < 1) {
- throw new IllegalArgumentException(
- "The number of columns and rows in the grid must be at least 1");
- }
-
- // In case of no change
- if (getRows() == rows) {
- return;
- }
-
- // Checks for overlaps
- if (getRows() > rows) {
- for (final Iterator<Area> i = areas.iterator(); i.hasNext();) {
- final Area area = i.next();
- if (area.row2 >= rows) {
- throw new OutOfBoundsException(area);
- }
- }
- }
-
- getState().setRows(rows);
-
- requestRepaint();
- }
-
- /**
- * Get the number of rows in the grid.
- *
- * @return the number of rows in the grid.
- */
- public int getRows() {
- return getState().getRows();
- }
-
- /**
- * Gets the current x-position (column) of the cursor.
- *
- * <p>
- * The cursor position points the position for the next component that is
- * added without specifying its coordinates (grid cell). When the cursor
- * position is occupied, the next component will be added to first free
- * position after the cursor.
- * </p>
- *
- * @return the grid column the cursor is on, starting from 0.
- */
- public int getCursorX() {
- return cursorX;
- }
-
- /**
- * Sets the current cursor x-position. This is usually handled automatically
- * by GridLayout.
- *
- * @param cursorX
- */
- public void setCursorX(int cursorX) {
- this.cursorX = cursorX;
- }
-
- /**
- * Gets the current y-position (row) of the cursor.
- *
- * <p>
- * The cursor position points the position for the next component that is
- * added without specifying its coordinates (grid cell). When the cursor
- * position is occupied, the next component will be added to the first free
- * position after the cursor.
- * </p>
- *
- * @return the grid row the Cursor is on.
- */
- public int getCursorY() {
- return cursorY;
- }
-
- /**
- * Sets the current y-coordinate (row) of the cursor. This is usually
- * handled automatically by GridLayout.
- *
- * @param cursorY
- * the row number, starting from 0 for the topmost row.
- */
- public void setCursorY(int cursorY) {
- this.cursorY = cursorY;
- }
-
- /* Documented in superclass */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- // Gets the locations
- Area oldLocation = null;
- Area newLocation = null;
- for (final Iterator<Area> i = areas.iterator(); i.hasNext();) {
- final Area location = i.next();
- final Component component = location.getComponent();
- if (component == oldComponent) {
- oldLocation = location;
- }
- if (component == newComponent) {
- newLocation = location;
- }
- }
-
- if (oldLocation == null) {
- addComponent(newComponent);
- } else if (newLocation == null) {
- removeComponent(oldComponent);
- addComponent(newComponent, oldLocation.getColumn1(),
- oldLocation.getRow1(), oldLocation.getColumn2(),
- oldLocation.getRow2());
- } else {
- oldLocation.setComponent(newComponent);
- newLocation.setComponent(oldComponent);
- requestRepaint();
- }
- }
-
- /*
- * Removes all components from this container.
- *
- * @see com.vaadin.ui.ComponentContainer#removeAllComponents()
- */
- @Override
- public void removeAllComponents() {
- super.removeAllComponents();
- componentToAlignment = new HashMap<Component, Alignment>();
- cursorX = 0;
- cursorY = 0;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.AlignmentHandler#setComponentAlignment(com
- * .vaadin.ui.Component, int, int)
- */
- @Override
- public void setComponentAlignment(Component childComponent,
- int horizontalAlignment, int verticalAlignment) {
- componentToAlignment.put(childComponent, new Alignment(
- horizontalAlignment + verticalAlignment));
- requestRepaint();
- }
-
- @Override
- public void setComponentAlignment(Component childComponent,
- Alignment alignment) {
- componentToAlignment.put(childComponent, alignment);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.SpacingHandler#setSpacing(boolean)
- */
- @Override
- public void setSpacing(boolean spacing) {
- getState().setSpacing(spacing);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Layout.SpacingHandler#isSpacing()
- */
- @Override
- public boolean isSpacing() {
- return getState().isSpacing();
- }
-
- /**
- * Inserts an empty row at the specified position in the grid.
- *
- * @param row
- * Index of the row before which the new row will be inserted.
- * The leftmost row has index 0.
- */
- public void insertRow(int row) {
- if (row > getRows()) {
- throw new IllegalArgumentException("Cannot insert row at " + row
- + " in a gridlayout with height " + getRows());
- }
-
- for (Iterator<Area> i = areas.iterator(); i.hasNext();) {
- Area existingArea = i.next();
- // Areas ending below the row needs to be moved down or stretched
- if (existingArea.row2 >= row) {
- existingArea.row2++;
-
- // Stretch areas that span over the selected row
- if (existingArea.row1 >= row) {
- existingArea.row1++;
- }
-
- }
- }
-
- if (cursorY >= row) {
- cursorY++;
- }
-
- setRows(getRows() + 1);
- structuralChange = true;
- requestRepaint();
- }
-
- /**
- * Removes a row and all the components in the row.
- *
- * <p>
- * Components which span over several rows are removed if the selected row
- * is on the first row of such a component.
- * </p>
- *
- * <p>
- * If the last row is removed then all remaining components will be removed
- * and the grid will be reduced to one row. The cursor will be moved to the
- * upper left cell of the grid.
- * </p>
- *
- * @param row
- * Index of the row to remove. The leftmost row has index 0.
- */
- public void removeRow(int row) {
- if (row >= getRows()) {
- throw new IllegalArgumentException("Cannot delete row " + row
- + " from a gridlayout with height " + getRows());
- }
-
- // Remove all components in row
- for (int col = 0; col < getColumns(); col++) {
- removeComponent(col, row);
- }
-
- // Shrink or remove areas in the selected row
- for (Iterator<Area> i = areas.iterator(); i.hasNext();) {
- Area existingArea = i.next();
- if (existingArea.row2 >= row) {
- existingArea.row2--;
-
- if (existingArea.row1 > row) {
- existingArea.row1--;
- }
- }
- }
-
- if (getRows() == 1) {
- /*
- * Removing the last row means that the dimensions of the Grid
- * layout will be truncated to 1 empty row and the cursor is moved
- * to the first cell
- */
- cursorX = 0;
- cursorY = 0;
- } else {
- setRows(getRows() - 1);
- if (cursorY > row) {
- cursorY--;
- }
- }
-
- structuralChange = true;
- requestRepaint();
-
- }
-
- /**
- * Sets the expand ratio of given column.
- *
- * <p>
- * The expand ratio defines how excess space is distributed among columns.
- * Excess space means space that is left over from components that are not
- * sized relatively. By default, the excess space is distributed evenly.
- * </p>
- *
- * <p>
- * Note that the component width of the GridLayout must be defined (fixed or
- * relative, as opposed to undefined) for this method to have any effect.
- * </p>
- *
- * @see #setWidth(float, int)
- *
- * @param columnIndex
- * @param ratio
- */
- public void setColumnExpandRatio(int columnIndex, float ratio) {
- columnExpandRatio.put(columnIndex, ratio);
- requestRepaint();
- }
-
- /**
- * Returns the expand ratio of given column
- *
- * @see #setColumnExpandRatio(int, float)
- *
- * @param columnIndex
- * @return the expand ratio, 0.0f by default
- */
- public float getColumnExpandRatio(int columnIndex) {
- Float r = columnExpandRatio.get(columnIndex);
- return r == null ? 0 : r.floatValue();
- }
-
- /**
- * Sets the expand ratio of given row.
- *
- * <p>
- * Expand ratio defines how excess space is distributed among rows. Excess
- * space means the space left over from components that are not sized
- * relatively. By default, the excess space is distributed evenly.
- * </p>
- *
- * <p>
- * Note, that height needs to be defined (fixed or relative, as opposed to
- * undefined height) for this method to have any effect.
- * </p>
- *
- * @see #setHeight(float, int)
- *
- * @param rowIndex
- * The row index, starting from 0 for the topmost row.
- * @param ratio
- */
- public void setRowExpandRatio(int rowIndex, float ratio) {
- rowExpandRatio.put(rowIndex, ratio);
- requestRepaint();
- }
-
- /**
- * Returns the expand ratio of given row.
- *
- * @see #setRowExpandRatio(int, float)
- *
- * @param rowIndex
- * The row index, starting from 0 for the topmost row.
- * @return the expand ratio, 0.0f by default
- */
- public float getRowExpandRatio(int rowIndex) {
- Float r = rowExpandRatio.get(rowIndex);
- return r == null ? 0 : r.floatValue();
- }
-
- /**
- * Gets the Component at given index.
- *
- * @param x
- * The column index, starting from 0 for the leftmost column.
- * @param y
- * The row index, starting from 0 for the topmost row.
- * @return Component in given cell or null if empty
- */
- public Component getComponent(int x, int y) {
- for (final Iterator<Area> iterator = areas.iterator(); iterator
- .hasNext();) {
- final Area area = iterator.next();
- if (area.getColumn1() <= x && x <= area.getColumn2()
- && area.getRow1() <= y && y <= area.getRow2()) {
- return area.getComponent();
- }
- }
- return null;
- }
-
- /**
- * Returns information about the area where given component is laid in the
- * GridLayout.
- *
- * @param component
- * the component whose area information is requested.
- * @return an Area object that contains information how component is laid in
- * the grid
- */
- public Area getComponentArea(Component component) {
- for (final Iterator<Area> iterator = areas.iterator(); iterator
- .hasNext();) {
- final Area area = iterator.next();
- if (area.getComponent() == component) {
- return area;
- }
- }
- return null;
- }
-
- @Override
- public void addListener(LayoutClickListener listener) {
- addListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener,
- LayoutClickListener.clickMethod);
- }
-
- @Override
- public void removeListener(LayoutClickListener listener) {
- removeListener(LayoutClickEventHandler.LAYOUT_CLICK_EVENT_IDENTIFIER,
- LayoutClickEvent.class, listener);
- }
-
-}
diff --git a/src/com/vaadin/ui/HasComponents.java b/src/com/vaadin/ui/HasComponents.java
deleted file mode 100644
index 3ebd63bff2..0000000000
--- a/src/com/vaadin/ui/HasComponents.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.util.Iterator;
-
-/**
- * Interface that must be implemented by all {@link Component}s that contain
- * other {@link Component}s.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- *
- */
-public interface HasComponents extends Component, Iterable<Component> {
- /**
- * Gets an iterator to the collection of contained components. Using this
- * iterator it is possible to step through all components contained in this
- * container.
- *
- * @return the component iterator.
- *
- * @deprecated Use {@link #iterator()} instead.
- */
- @Deprecated
- public Iterator<Component> getComponentIterator();
-
- /**
- * Checks if the child component is visible. This method allows hiding a
- * child component from updates and communication to and from the client.
- * This is useful for components that show only a limited number of its
- * children at any given time and want to allow updates only for the
- * children that are visible (e.g. TabSheet has one tab open at a time).
- * <p>
- * Note that this will prevent updates from reaching the child even though
- * the child itself is set to visible. Also if a child is set to invisible
- * this will not force it to be visible.
- * </p>
- *
- * @param childComponent
- * The child component to check
- * @return true if the child component is visible to the user, false
- * otherwise
- */
- public boolean isComponentVisible(Component childComponent);
-
-}
diff --git a/src/com/vaadin/ui/HorizontalLayout.java b/src/com/vaadin/ui/HorizontalLayout.java
deleted file mode 100644
index b9dc1c13ca..0000000000
--- a/src/com/vaadin/ui/HorizontalLayout.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-/**
- * Horizontal layout
- *
- * <code>HorizontalLayout</code> is a component container, which shows the
- * subcomponents in the order of their addition (horizontally).
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.3
- */
-@SuppressWarnings("serial")
-public class HorizontalLayout extends AbstractOrderedLayout {
-
- public HorizontalLayout() {
-
- }
-
-}
diff --git a/src/com/vaadin/ui/HorizontalSplitPanel.java b/src/com/vaadin/ui/HorizontalSplitPanel.java
deleted file mode 100644
index 5bd6c8a075..0000000000
--- a/src/com/vaadin/ui/HorizontalSplitPanel.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-/**
- * A horizontal split panel contains two components and lays them horizontally.
- * The first component is on the left side.
- *
- * <pre>
- *
- * +---------------------++----------------------+
- * | || |
- * | The first component || The second component |
- * | || |
- * +---------------------++----------------------+
- *
- * ^
- * |
- * the splitter
- *
- * </pre>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.5
- */
-public class HorizontalSplitPanel extends AbstractSplitPanel {
- public HorizontalSplitPanel() {
- super();
- setSizeFull();
- }
-}
diff --git a/src/com/vaadin/ui/Html5File.java b/src/com/vaadin/ui/Html5File.java
deleted file mode 100644
index aa3fb558fa..0000000000
--- a/src/com/vaadin/ui/Html5File.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.terminal.StreamVariable;
-
-/**
- * {@link DragAndDropWrapper} can receive also files from client computer if
- * appropriate HTML 5 features are supported on client side. This class wraps
- * information about dragged file on server side.
- */
-public class Html5File implements Serializable {
-
- private String name;
- private long size;
- private StreamVariable streamVariable;
- private String type;
-
- Html5File(String name, long size, String mimeType) {
- this.name = name;
- this.size = size;
- type = mimeType;
- }
-
- public String getFileName() {
- return name;
- }
-
- public long getFileSize() {
- return size;
- }
-
- public String getType() {
- return type;
- }
-
- /**
- * Sets the {@link StreamVariable} that into which the file contents will be
- * written. Usage of StreamVariable is similar to {@link Upload} component.
- * <p>
- * If the {@link StreamVariable} is not set in the {@link DropHandler} the
- * file contents will not be sent to server.
- * <p>
- * <em>Note!</em> receiving file contents is experimental feature depending
- * on HTML 5 API's. It is supported only by modern web browsers like Firefox
- * 3.6 and above and recent webkit based browsers (Safari 5, Chrome 6) at
- * this time.
- *
- * @param streamVariable
- * the callback that returns stream where the implementation
- * writes the file contents as it arrives.
- */
- public void setStreamVariable(StreamVariable streamVariable) {
- this.streamVariable = streamVariable;
- }
-
- public StreamVariable getStreamVariable() {
- return streamVariable;
- }
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/ui/InlineDateField.java b/src/com/vaadin/ui/InlineDateField.java
deleted file mode 100644
index cf61703318..0000000000
--- a/src/com/vaadin/ui/InlineDateField.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector inline.
- *
- * </p>
- *
- * @see DateField
- * @see PopupDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-public class InlineDateField extends DateField {
-
- public InlineDateField() {
- super();
- }
-
- public InlineDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public InlineDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public InlineDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public InlineDateField(String caption) {
- super(caption);
- }
-
-}
diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java
deleted file mode 100644
index 0b4669728a..0000000000
--- a/src/com/vaadin/ui/JavaScript.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.shared.communication.ServerRpc;
-import com.vaadin.shared.extension.javascriptmanager.ExecuteJavaScriptRpc;
-import com.vaadin.shared.extension.javascriptmanager.JavaScriptManagerState;
-import com.vaadin.terminal.AbstractExtension;
-import com.vaadin.terminal.Page;
-
-/**
- * Provides access to JavaScript functionality in the web browser. To get an
- * instance of JavaScript, either use Page.getJavaScript() or
- * JavaScript.getCurrent() as a shorthand for getting the JavaScript object
- * corresponding to the current Page.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public class JavaScript extends AbstractExtension {
- private Map<String, JavaScriptFunction> functions = new HashMap<String, JavaScriptFunction>();
-
- // Can not be defined in client package as this JSONArray is not available
- // in GWT
- public interface JavaScriptCallbackRpc extends ServerRpc {
- public void call(String name, JSONArray arguments);
- }
-
- /**
- * Creates a new JavaScript object. You should typically not this, but
- * instead use the JavaScript object already associated with your Page
- * object.
- */
- public JavaScript() {
- registerRpc(new JavaScriptCallbackRpc() {
- @Override
- public void call(String name, JSONArray arguments) {
- JavaScriptFunction function = functions.get(name);
- // TODO handle situation if name is not registered
- try {
- function.call(arguments);
- } catch (JSONException e) {
- throw new IllegalArgumentException(e);
- }
- }
- });
- }
-
- @Override
- public JavaScriptManagerState getState() {
- return (JavaScriptManagerState) super.getState();
- }
-
- /**
- * Add a new function to the global JavaScript namespace (i.e. the window
- * object). The <code>call</code> method in the passed
- * {@link JavaScriptFunction} object will be invoked with the same
- * parameters whenever the JavaScript function is called in the browser.
- *
- * A function added with the name <code>"myFunction"</code> can thus be
- * invoked with the following JavaScript code:
- * <code>window.myFunction(argument1, argument2)</code>.
- *
- * If the name parameter contains dots, simple objects are created on demand
- * to allow calling the function using the same name (e.g.
- * <code>window.myObject.myFunction</code>).
- *
- * @param name
- * the name that the function should get in the global JavaScript
- * namespace.
- * @param function
- * the JavaScriptFunction that will be invoked if the JavaScript
- * function is called.
- */
- public void addFunction(String name, JavaScriptFunction function) {
- functions.put(name, function);
- if (getState().getNames().add(name)) {
- requestRepaint();
- }
- }
-
- /**
- * Removes a JavaScripFunction from the browser's global JavaScript
- * namespace.
- *
- * If the name contains dots and intermediate objects were created by
- * {@link #addFunction(String, JavaScriptFunction)}, these objects will not
- * be removed by this method.
- *
- * @param name
- * the name of the callback to remove
- */
- public void removeFunction(String name) {
- functions.remove(name);
- if (getState().getNames().remove(name)) {
- requestRepaint();
- }
- }
-
- /**
- * Executes the given JavaScript code in the browser.
- *
- * @param script
- * The JavaScript code to run.
- */
- public void execute(String script) {
- getRpcProxy(ExecuteJavaScriptRpc.class).executeJavaScript(script);
- }
-
- /**
- * Executes the given JavaScript code in the browser.
- *
- * @param script
- * The JavaScript code to run.
- */
- public static void eval(String script) {
- getCurrent().execute(script);
- }
-
- /**
- * Get the JavaScript object for the current Page, or null if there is no
- * current page.
- *
- * @see Page#getCurrent()
- *
- * @return the JavaScript object corresponding to the current Page, or
- * <code>null</code> if there is no current page.
- */
- public static JavaScript getCurrent() {
- Page page = Page.getCurrent();
- if (page == null) {
- return null;
- }
- return page.getJavaScript();
- }
-
- /**
- * JavaScript is not designed to be removed.
- *
- * @throws UnsupportedOperationException
- * when invoked
- */
- @Override
- public void removeFromTarget() {
- throw new UnsupportedOperationException(
- "JavaScript is not designed to be removed.");
- }
-
-}
diff --git a/src/com/vaadin/ui/JavaScriptFunction.java b/src/com/vaadin/ui/JavaScriptFunction.java
deleted file mode 100644
index e39ae9b87b..0000000000
--- a/src/com/vaadin/ui/JavaScriptFunction.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.external.json.JSONArray;
-import com.vaadin.external.json.JSONException;
-import com.vaadin.terminal.AbstractJavaScriptExtension;
-
-/**
- * Defines a method that is called by a client-side JavaScript function. When
- * the corresponding JavaScript function is called, the {@link #call(JSONArray)}
- * method is invoked.
- *
- * @see JavaScript#addFunction(String, JavaScriptCallback)
- * @see AbstractJavaScriptComponent#addFunction(String, JavaScriptCallback)
- * @see AbstractJavaScriptExtension#addFunction(String, JavaScriptCallback)
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0.0
- */
-public interface JavaScriptFunction extends Serializable {
- /**
- * Invoked whenever the corresponding JavaScript function is called in the
- * browser.
- * <p>
- * Because of the asynchronous nature of the communication between client
- * and server, no return value can be sent back to the browser.
- *
- * @param arguments
- * an array with JSON representations of the arguments with which
- * the JavaScript function was called.
- * @throws JSONException
- * if the arguments can not be interpreted
- */
- public void call(JSONArray arguments) throws JSONException;
-}
diff --git a/src/com/vaadin/ui/Label.java b/src/com/vaadin/ui/Label.java
deleted file mode 100644
index 7e50a37805..0000000000
--- a/src/com/vaadin/ui/Label.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.lang.reflect.Method;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.data.util.converter.ConverterUtil;
-import com.vaadin.shared.ui.label.ContentMode;
-import com.vaadin.shared.ui.label.LabelState;
-
-/**
- * Label component for showing non-editable short texts.
- *
- * The label content can be set to the modes specified by {@link ContentMode}
- *
- * <p>
- * The contents of the label may contain simple formatting:
- * <ul>
- * <li><b>&lt;b></b> Bold
- * <li><b>&lt;i></b> Italic
- * <li><b>&lt;u></b> Underlined
- * <li><b>&lt;br/></b> Linebreak
- * <li><b>&lt;ul>&lt;li>item 1&lt;/li>&lt;li>item 2&lt;/li>&lt;/ul></b> List of
- * items
- * </ul>
- * The <b>b</b>,<b>i</b>,<b>u</b> and <b>li</b> tags can contain all the tags in
- * the list recursively.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Label extends AbstractComponent implements Property<String>,
- Property.Viewer, Property.ValueChangeListener,
- Property.ValueChangeNotifier, Comparable<Label> {
-
- private static final Logger logger = Logger
- .getLogger(Label.class.getName());
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#TEXT} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_TEXT = ContentMode.TEXT;
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#PREFORMATTED} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_PREFORMATTED = ContentMode.PREFORMATTED;
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#XHTML} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_XHTML = ContentMode.XHTML;
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#XML} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_XML = ContentMode.XML;
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#RAW} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_RAW = ContentMode.RAW;
-
- /**
- * @deprecated From 7.0, use {@link ContentMode#TEXT} instead
- */
- @Deprecated
- public static final ContentMode CONTENT_DEFAULT = ContentMode.TEXT;
-
- /**
- * A converter used to convert from the data model type to the field type
- * and vice versa. Label type is always String.
- */
- private Converter<String, Object> converter = null;
-
- private Property<String> dataSource = null;
-
- /**
- * Creates an empty Label.
- */
- public Label() {
- this("");
- }
-
- /**
- * Creates a new instance of Label with text-contents.
- *
- * @param content
- */
- public Label(String content) {
- this(content, ContentMode.TEXT);
- }
-
- /**
- * Creates a new instance of Label with text-contents read from given
- * datasource.
- *
- * @param contentSource
- */
- public Label(Property contentSource) {
- this(contentSource, ContentMode.TEXT);
- }
-
- /**
- * Creates a new instance of Label with text-contents.
- *
- * @param content
- * @param contentMode
- */
- public Label(String content, ContentMode contentMode) {
- setValue(content);
- setContentMode(contentMode);
- setWidth(100, Unit.PERCENTAGE);
- }
-
- /**
- * Creates a new instance of Label with text-contents read from given
- * datasource.
- *
- * @param contentSource
- * @param contentMode
- */
- public Label(Property contentSource, ContentMode contentMode) {
- setPropertyDataSource(contentSource);
- setContentMode(contentMode);
- setWidth(100, Unit.PERCENTAGE);
- }
-
- @Override
- public LabelState getState() {
- return (LabelState) super.getState();
- }
-
- /**
- * Gets the value of the label.
- * <p>
- * The value of the label is the text that is shown to the end user.
- * Depending on the {@link ContentMode} it is plain text or markup.
- * </p>
- *
- * @return the value of the label.
- */
- @Override
- public String getValue() {
- if (getPropertyDataSource() == null) {
- // Use internal value if we are running without a data source
- return getState().getText();
- }
- return ConverterUtil.convertFromModel(getPropertyDataSource()
- .getValue(), String.class, getConverter(), getLocale());
- }
-
- /**
- * Set the value of the label. Value of the label is the XML contents of the
- * label.
- *
- * @param newStringValue
- * the New value of the label.
- */
- @Override
- public void setValue(Object newStringValue) {
- if (newStringValue != null && newStringValue.getClass() != String.class) {
- throw new Converter.ConversionException("Value of type "
- + newStringValue.getClass() + " cannot be assigned to "
- + String.class.getName());
- }
- if (getPropertyDataSource() == null) {
- getState().setText((String) newStringValue);
- requestRepaint();
- } else {
- throw new IllegalStateException(
- "Label is only a Property.Viewer and cannot update its data source");
- }
- }
-
- /**
- * Returns the value displayed by this label.
- *
- * @see java.lang.Object#toString()
- * @deprecated As of 7.0.0, use {@link #getValue()} to get the value of the
- * label or {@link #getPropertyDataSource()} .getValue() to get
- * the value of the data source.
- */
- @Deprecated
- @Override
- public String toString() {
- logger.warning("You are using Label.toString() to get the value for a "
- + getClass().getSimpleName()
- + ". This is not recommended and will not be supported in future versions.");
- return getValue();
- }
-
- /**
- * Gets the type of the Property.
- *
- * @see com.vaadin.data.Property#getType()
- */
- @Override
- public Class<String> getType() {
- return String.class;
- }
-
- /**
- * Gets the viewing data-source property.
- *
- * @return the data source property.
- * @see com.vaadin.data.Property.Viewer#getPropertyDataSource()
- */
- @Override
- public Property getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- * Sets the property as data-source for viewing.
- *
- * @param newDataSource
- * the new data source Property
- * @see com.vaadin.data.Property.Viewer#setPropertyDataSource(com.vaadin.data.Property)
- */
- @Override
- public void setPropertyDataSource(Property newDataSource) {
- // Stops listening the old data source changes
- if (dataSource != null
- && Property.ValueChangeNotifier.class
- .isAssignableFrom(dataSource.getClass())) {
- ((Property.ValueChangeNotifier) dataSource).removeListener(this);
- }
-
- if (!ConverterUtil.canConverterHandle(getConverter(), String.class,
- newDataSource.getType())) {
- // Try to find a converter
- Converter<String, ?> c = ConverterUtil.getConverter(String.class,
- newDataSource.getType(), getApplication());
- setConverter(c);
- }
- dataSource = newDataSource;
-
- // Listens the new data source if possible
- if (dataSource != null
- && Property.ValueChangeNotifier.class
- .isAssignableFrom(dataSource.getClass())) {
- ((Property.ValueChangeNotifier) dataSource).addListener(this);
- }
- requestRepaint();
- }
-
- /**
- * Gets the content mode of the Label.
- *
- * @return the Content mode of the label.
- *
- * @see ContentMode
- */
- public ContentMode getContentMode() {
- return getState().getContentMode();
- }
-
- /**
- * Sets the content mode of the Label.
- *
- * @param contentMode
- * the New content mode of the label.
- *
- * @see ContentMode
- */
- public void setContentMode(ContentMode contentMode) {
- if (contentMode == null) {
- throw new IllegalArgumentException("Content mode can not be null");
- }
-
- getState().setContentMode(contentMode);
- requestRepaint();
- }
-
- /* Value change events */
-
- private static final Method VALUE_CHANGE_METHOD;
-
- static {
- try {
- VALUE_CHANGE_METHOD = Property.ValueChangeListener.class
- .getDeclaredMethod("valueChange",
- new Class[] { Property.ValueChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in Label");
- }
- }
-
- /**
- * Value change event
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class ValueChangeEvent extends Component.Event implements
- Property.ValueChangeEvent {
-
- /**
- * New instance of text change event
- *
- * @param source
- * the Source of the event.
- */
- public ValueChangeEvent(Label source) {
- super(source);
- }
-
- /**
- * Gets the Property that has been modified.
- *
- * @see com.vaadin.data.Property.ValueChangeEvent#getProperty()
- */
- @Override
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /**
- * Adds the value change listener.
- *
- * @param listener
- * the Listener to be added.
- * @see com.vaadin.data.Property.ValueChangeNotifier#addListener(com.vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void addListener(Property.ValueChangeListener listener) {
- addListener(Label.ValueChangeEvent.class, listener, VALUE_CHANGE_METHOD);
- }
-
- /**
- * Removes the value change listener.
- *
- * @param listener
- * the Listener to be removed.
- * @see com.vaadin.data.Property.ValueChangeNotifier#removeListener(com.vaadin.data.Property.ValueChangeListener)
- */
- @Override
- public void removeListener(Property.ValueChangeListener listener) {
- removeListener(Label.ValueChangeEvent.class, listener,
- VALUE_CHANGE_METHOD);
- }
-
- /**
- * Emits the options change event.
- */
- protected void fireValueChange() {
- // Set the error message
- fireEvent(new Label.ValueChangeEvent(this));
- }
-
- /**
- * Listens the value change events from data source.
- *
- * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent)
- */
- @Override
- public void valueChange(Property.ValueChangeEvent event) {
- // Update the internal value from the data source
- getState().setText(getValue());
- requestRepaint();
-
- fireValueChange();
- }
-
- private String getComparableValue() {
- String stringValue = getValue();
- if (stringValue == null) {
- stringValue = "";
- }
-
- if (getContentMode() == ContentMode.XHTML
- || getContentMode() == ContentMode.XML) {
- return stripTags(stringValue);
- } else {
- return stringValue;
- }
-
- }
-
- /**
- * Compares the Label to other objects.
- *
- * <p>
- * Labels can be compared to other labels for sorting label contents. This
- * is especially handy for sorting table columns.
- * </p>
- *
- * <p>
- * In RAW, PREFORMATTED and TEXT modes, the label contents are compared as
- * is. In XML, UIDL and XHTML modes, only CDATA is compared and tags
- * ignored. If the other object is not a Label, its toString() return value
- * is used in comparison.
- * </p>
- *
- * @param other
- * the Other object to compare to.
- * @return a negative integer, zero, or a positive integer as this object is
- * less than, equal to, or greater than the specified object.
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
- @Override
- public int compareTo(Label other) {
-
- String thisValue = getComparableValue();
- String otherValue = other.getComparableValue();
-
- return thisValue.compareTo(otherValue);
- }
-
- /**
- * Strips the tags from the XML.
- *
- * @param xml
- * the String containing a XML snippet.
- * @return the original XML without tags.
- */
- private String stripTags(String xml) {
-
- final StringBuffer res = new StringBuffer();
-
- int processed = 0;
- final int xmlLen = xml.length();
- while (processed < xmlLen) {
- int next = xml.indexOf('<', processed);
- if (next < 0) {
- next = xmlLen;
- }
- res.append(xml.substring(processed, next));
- if (processed < xmlLen) {
- next = xml.indexOf('>', processed);
- if (next < 0) {
- next = xmlLen;
- }
- processed = next + 1;
- }
- }
-
- return res.toString();
- }
-
- /**
- * Gets the converter used to convert the property data source value to the
- * label value.
- *
- * @return The converter or null if none is set.
- */
- public Converter<String, Object> getConverter() {
- return converter;
- }
-
- /**
- * Sets the converter used to convert the label value to the property data
- * source type. The converter must have a presentation type of String.
- *
- * @param converter
- * The new converter to use.
- */
- public void setConverter(Converter<String, ?> converter) {
- this.converter = (Converter<String, Object>) converter;
- requestRepaint();
- }
-
-}
diff --git a/src/com/vaadin/ui/Layout.java b/src/com/vaadin/ui/Layout.java
deleted file mode 100644
index d083f9afdc..0000000000
--- a/src/com/vaadin/ui/Layout.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.shared.ui.VMarginInfo;
-import com.vaadin.shared.ui.AlignmentInfo.Bits;
-
-/**
- * Extension to the {@link ComponentContainer} interface which adds the
- * layouting control to the elements in the container. This is required by the
- * various layout components to enable them to place other components in
- * specific locations in the UI.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public interface Layout extends ComponentContainer, Serializable {
-
- /**
- * Enable layout margins. Affects all four sides of the layout. This will
- * tell the client-side implementation to leave extra space around the
- * layout. The client-side implementation decides the actual amount, and it
- * can vary between themes.
- *
- * @param enabled
- */
- public void setMargin(boolean enabled);
-
- /**
- * Enable specific layout margins. This will tell the client-side
- * implementation to leave extra space around the layout in specified edges,
- * clockwise from top (top, right, bottom, left). The client-side
- * implementation decides the actual amount, and it can vary between themes.
- *
- * @param top
- * @param right
- * @param bottom
- * @param left
- */
- public void setMargin(boolean top, boolean right, boolean bottom,
- boolean left);
-
- /**
- * AlignmentHandler is most commonly an advanced {@link Layout} that can
- * align its components.
- */
- public interface AlignmentHandler extends Serializable {
-
- /**
- * Contained component should be aligned horizontally to the left.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_LEFT = Bits.ALIGNMENT_LEFT;
-
- /**
- * Contained component should be aligned horizontally to the right.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_RIGHT = Bits.ALIGNMENT_RIGHT;
-
- /**
- * Contained component should be aligned vertically to the top.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_TOP = Bits.ALIGNMENT_TOP;
-
- /**
- * Contained component should be aligned vertically to the bottom.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_BOTTOM = Bits.ALIGNMENT_BOTTOM;
-
- /**
- * Contained component should be horizontally aligned to center.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_HORIZONTAL_CENTER = Bits.ALIGNMENT_HORIZONTAL_CENTER;
-
- /**
- * Contained component should be vertically aligned to center.
- *
- * @deprecated Use of {@link Alignment} class and its constants
- */
- @Deprecated
- public static final int ALIGNMENT_VERTICAL_CENTER = Bits.ALIGNMENT_VERTICAL_CENTER;
-
- /**
- * Set alignment for one contained component in this layout. Alignment
- * is calculated as a bit mask of the two passed values.
- *
- * @deprecated Use {@link #setComponentAlignment(Component, Alignment)}
- * instead
- *
- * @param childComponent
- * the component to align within it's layout cell.
- * @param horizontalAlignment
- * the horizontal alignment for the child component (left,
- * center, right). Use ALIGNMENT constants.
- * @param verticalAlignment
- * the vertical alignment for the child component (top,
- * center, bottom). Use ALIGNMENT constants.
- */
- @Deprecated
- public void setComponentAlignment(Component childComponent,
- int horizontalAlignment, int verticalAlignment);
-
- /**
- * Set alignment for one contained component in this layout. Use
- * predefined alignments from Alignment class.
- *
- * Example: <code>
- * layout.setComponentAlignment(myComponent, Alignment.TOP_RIGHT);
- * </code>
- *
- * @param childComponent
- * the component to align within it's layout cell.
- * @param alignment
- * the Alignment value to be set
- */
- public void setComponentAlignment(Component childComponent,
- Alignment alignment);
-
- /**
- * Returns the current Alignment of given component.
- *
- * @param childComponent
- * @return the {@link Alignment}
- */
- public Alignment getComponentAlignment(Component childComponent);
-
- }
-
- /**
- * This type of layout supports automatic addition of space between its
- * components.
- *
- */
- public interface SpacingHandler extends Serializable {
- /**
- * Enable spacing between child components within this layout.
- *
- * <p>
- * <strong>NOTE:</strong> This will only affect the space between
- * components, not the space around all the components in the layout
- * (i.e. do not confuse this with the cellspacing attribute of a HTML
- * Table). Use {@link #setMargin(boolean)} to add space around the
- * layout.
- * </p>
- *
- * <p>
- * See the reference manual for more information about CSS rules for
- * defining the amount of spacing to use.
- * </p>
- *
- * @param enabled
- * true if spacing should be turned on, false if it should be
- * turned off
- */
- public void setSpacing(boolean enabled);
-
- /**
- *
- * @return true if spacing between child components within this layout
- * is enabled, false otherwise
- */
- public boolean isSpacing();
- }
-
- /**
- * This type of layout supports automatic addition of margins (space around
- * its components).
- */
- public interface MarginHandler extends Serializable {
- /**
- * Enable margins for this layout.
- *
- * <p>
- * <strong>NOTE:</strong> This will only affect the space around the
- * components in the layout, not space between the components in the
- * layout. Use {@link #setSpacing(boolean)} to add space between the
- * components in the layout.
- * </p>
- *
- * <p>
- * See the reference manual for more information about CSS rules for
- * defining the size of the margin.
- * </p>
- *
- * @param marginInfo
- * MarginInfo object containing the new margins.
- */
- public void setMargin(MarginInfo marginInfo);
-
- /**
- *
- * @return MarginInfo containing the currently enabled margins.
- */
- public MarginInfo getMargin();
- }
-
- @SuppressWarnings("serial")
- public static class MarginInfo extends VMarginInfo implements Serializable {
-
- public MarginInfo(boolean enabled) {
- super(enabled, enabled, enabled, enabled);
- }
-
- public MarginInfo(boolean top, boolean right, boolean bottom,
- boolean left) {
- super(top, right, bottom, left);
- }
- }
-}
diff --git a/src/com/vaadin/ui/Link.java b/src/com/vaadin/ui/Link.java
deleted file mode 100644
index fd105f3255..0000000000
--- a/src/com/vaadin/ui/Link.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Map;
-
-import com.vaadin.terminal.Page;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- * Link is used to create external or internal URL links.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Link extends AbstractComponent implements Vaadin6Component {
-
- /* Target window border type constant: No window border */
- public static final int TARGET_BORDER_NONE = Page.BORDER_NONE;
-
- /* Target window border type constant: Minimal window border */
- public static final int TARGET_BORDER_MINIMAL = Page.BORDER_MINIMAL;
-
- /* Target window border type constant: Default window border */
- public static final int TARGET_BORDER_DEFAULT = Page.BORDER_DEFAULT;
-
- private Resource resource = null;
-
- private String targetName;
-
- private int targetBorder = TARGET_BORDER_DEFAULT;
-
- private int targetWidth = -1;
-
- private int targetHeight = -1;
-
- /**
- * Creates a new link.
- */
- public Link() {
-
- }
-
- /**
- * Creates a new instance of Link.
- *
- * @param caption
- * @param resource
- */
- public Link(String caption, Resource resource) {
- setCaption(caption);
- this.resource = resource;
- }
-
- /**
- * Creates a new instance of Link that opens a new window.
- *
- *
- * @param caption
- * the Link text.
- * @param targetName
- * the name of the target window where the link opens to. Empty
- * name of null implies that the target is opened to the window
- * containing the link.
- * @param width
- * the Width of the target window.
- * @param height
- * the Height of the target window.
- * @param border
- * the Border style of the target window.
- *
- */
- public Link(String caption, Resource resource, String targetName,
- int width, int height, int border) {
- setCaption(caption);
- this.resource = resource;
- setTargetName(targetName);
- setTargetWidth(width);
- setTargetHeight(height);
- setTargetBorder(border);
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- if (resource != null) {
- target.addAttribute("src", resource);
- } else {
- return;
- }
-
- // Target window name
- final String name = getTargetName();
- if (name != null && name.length() > 0) {
- target.addAttribute("name", name);
- }
-
- // Target window size
- if (getTargetWidth() >= 0) {
- target.addAttribute("targetWidth", getTargetWidth());
- }
- if (getTargetHeight() >= 0) {
- target.addAttribute("targetHeight", getTargetHeight());
- }
-
- // Target window border
- switch (getTargetBorder()) {
- case TARGET_BORDER_MINIMAL:
- target.addAttribute("border", "minimal");
- break;
- case TARGET_BORDER_NONE:
- target.addAttribute("border", "none");
- break;
- }
- }
-
- /**
- * Returns the target window border.
- *
- * @return the target window border.
- */
- public int getTargetBorder() {
- return targetBorder;
- }
-
- /**
- * Returns the target window height or -1 if not set.
- *
- * @return the target window height.
- */
- public int getTargetHeight() {
- return targetHeight < 0 ? -1 : targetHeight;
- }
-
- /**
- * Returns the target window name. Empty name of null implies that the
- * target is opened to the window containing the link.
- *
- * @return the target window name.
- */
- public String getTargetName() {
- return targetName;
- }
-
- /**
- * Returns the target window width or -1 if not set.
- *
- * @return the target window width.
- */
- public int getTargetWidth() {
- return targetWidth < 0 ? -1 : targetWidth;
- }
-
- /**
- * Sets the border of the target window.
- *
- * @param targetBorder
- * the targetBorder to set.
- */
- public void setTargetBorder(int targetBorder) {
- if (targetBorder == TARGET_BORDER_DEFAULT
- || targetBorder == TARGET_BORDER_MINIMAL
- || targetBorder == TARGET_BORDER_NONE) {
- this.targetBorder = targetBorder;
- requestRepaint();
- }
- }
-
- /**
- * Sets the target window height.
- *
- * @param targetHeight
- * the targetHeight to set.
- */
- public void setTargetHeight(int targetHeight) {
- this.targetHeight = targetHeight;
- requestRepaint();
- }
-
- /**
- * Sets the target window name.
- *
- * @param targetName
- * the targetName to set.
- */
- public void setTargetName(String targetName) {
- this.targetName = targetName;
- requestRepaint();
- }
-
- /**
- * Sets the target window width.
- *
- * @param targetWidth
- * the targetWidth to set.
- */
- public void setTargetWidth(int targetWidth) {
- this.targetWidth = targetWidth;
- requestRepaint();
- }
-
- /**
- * Returns the resource this link opens.
- *
- * @return the Resource.
- */
- public Resource getResource() {
- return resource;
- }
-
- /**
- * Sets the resource this link opens.
- *
- * @param resource
- * the resource to set.
- */
- public void setResource(Resource resource) {
- this.resource = resource;
- requestRepaint();
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // TODO Remove once Vaadin6Component is no longer implemented
- }
-}
diff --git a/src/com/vaadin/ui/ListSelect.java b/src/com/vaadin/ui/ListSelect.java
deleted file mode 100644
index 35ccb34b3c..0000000000
--- a/src/com/vaadin/ui/ListSelect.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * This is a simple list select without, for instance, support for new items,
- * lazyloading, and other advanced features.
- */
-@SuppressWarnings("serial")
-public class ListSelect extends AbstractSelect {
-
- private int columns = 0;
- private int rows = 0;
-
- public ListSelect() {
- super();
- }
-
- public ListSelect(String caption, Collection<?> options) {
- super(caption, options);
- }
-
- public ListSelect(String caption, Container dataSource) {
- super(caption, dataSource);
- }
-
- public ListSelect(String caption) {
- super(caption);
- }
-
- /**
- * Sets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- *
- * @param columns
- * the number of columns to set.
- */
- public void setColumns(int columns) {
- if (columns < 0) {
- columns = 0;
- }
- if (this.columns != columns) {
- this.columns = columns;
- requestRepaint();
- }
- }
-
- public int getColumns() {
- return columns;
- }
-
- public int getRows() {
- return rows;
- }
-
- /**
- * Sets the number of rows in the editor. If the number of rows is set 0,
- * the actual number of displayed rows is determined implicitly by the
- * adapter.
- *
- * @param rows
- * the number of rows to set.
- */
- public void setRows(int rows) {
- if (rows < 0) {
- rows = 0;
- }
- if (this.rows != rows) {
- this.rows = rows;
- requestRepaint();
- }
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute("type", "list");
- // Adds the number of columns
- if (columns != 0) {
- target.addAttribute("cols", columns);
- }
- // Adds the number of rows
- if (rows != 0) {
- target.addAttribute("rows", rows);
- }
- super.paintContent(target);
- }
-}
diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java
deleted file mode 100644
index db7e5f9dd9..0000000000
--- a/src/com/vaadin/ui/LoginForm.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.vaadin.Application;
-import com.vaadin.terminal.ApplicationResource;
-import com.vaadin.terminal.DownloadStream;
-import com.vaadin.terminal.RequestHandler;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedResponse;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-
-/**
- * LoginForm is a Vaadin component to handle common problem among Ajax
- * applications: browsers password managers don't fill dynamically created forms
- * like all those UI elements created by Vaadin.
- * <p>
- * For developer it is easy to use: add component to a desired place in you UI
- * and add LoginListener to validate form input. Behind the curtain LoginForm
- * creates an iframe with static html that browsers detect.
- * <p>
- * Login form is by default 100% width and height, so consider using it inside a
- * sized {@link Panel} or {@link Window}.
- * <p>
- * Login page html can be overridden by replacing protected getLoginHTML method.
- * As the login page is actually an iframe, styles must be handled manually. By
- * default component tries to guess the right place for theme css.
- *
- * @since 5.3
- */
-public class LoginForm extends CustomComponent {
-
- private String usernameCaption = "Username";
- private String passwordCaption = "Password";
- private String loginButtonCaption = "Login";
-
- private Embedded iframe = new Embedded();
-
- private ApplicationResource loginPage = new ApplicationResource() {
-
- @Override
- public Application getApplication() {
- return LoginForm.this.getApplication();
- }
-
- @Override
- public int getBufferSize() {
- return getLoginHTML().length;
- }
-
- @Override
- public long getCacheTime() {
- return -1;
- }
-
- @Override
- public String getFilename() {
- return "login";
- }
-
- @Override
- public DownloadStream getStream() {
- return new DownloadStream(new ByteArrayInputStream(getLoginHTML()),
- getMIMEType(), getFilename());
- }
-
- @Override
- public String getMIMEType() {
- return "text/html; charset=utf-8";
- }
- };
-
- private final RequestHandler requestHandler = new RequestHandler() {
- @Override
- public boolean handleRequest(Application application,
- WrappedRequest request, WrappedResponse response)
- throws IOException {
- String requestPathInfo = request.getRequestPathInfo();
- if ("/loginHandler".equals(requestPathInfo)) {
- response.setCacheTime(-1);
- response.setContentType("text/html; charset=utf-8");
- response.getWriter()
- .write("<html><body>Login form handled."
- + "<script type='text/javascript'>parent.parent.vaadin.forceSync();"
- + "</script></body></html>");
-
- Map<String, String[]> parameters = request.getParameterMap();
-
- HashMap<String, String> params = new HashMap<String, String>();
- // expecting single params
- for (Iterator<String> it = parameters.keySet().iterator(); it
- .hasNext();) {
- String key = it.next();
- String value = (parameters.get(key))[0];
- params.put(key, value);
- }
- LoginEvent event = new LoginEvent(params);
- fireEvent(event);
- return true;
- }
- return false;
- }
- };
-
- public LoginForm() {
- iframe.setType(Embedded.TYPE_BROWSER);
- iframe.setSizeFull();
- setSizeFull();
- setCompositionRoot(iframe);
- addStyleName("v-loginform");
- }
-
- /**
- * Returns byte array containing login page html. If you need to override
- * the login html, use the default html as basis. Login page sets its target
- * with javascript.
- *
- * @return byte array containing login page html
- */
- protected byte[] getLoginHTML() {
- String appUri = getApplication().getURL().toString();
-
- try {
- return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD "
- + "XHTML 1.0 Transitional//EN\" "
- + "\"http://www.w3.org/TR/xhtml1/"
- + "DTD/xhtml1-transitional.dtd\">\n" + "<html>"
- + "<head><script type='text/javascript'>"
- + "var setTarget = function() {" + "var uri = '"
- + appUri
- + "loginHandler"
- + "'; var f = document.getElementById('loginf');"
- + "document.forms[0].action = uri;document.forms[0].username.focus();};"
- + ""
- + "var styles = window.parent.document.styleSheets;"
- + "for(var j = 0; j < styles.length; j++) {\n"
- + "if(styles[j].href) {"
- + "var stylesheet = document.createElement('link');\n"
- + "stylesheet.setAttribute('rel', 'stylesheet');\n"
- + "stylesheet.setAttribute('type', 'text/css');\n"
- + "stylesheet.setAttribute('href', styles[j].href);\n"
- + "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n"
- + "}"
- + "}\n"
- + "function submitOnEnter(e) { var keycode = e.keyCode || e.which;"
- + " if (keycode == 13) {document.forms[0].submit();} } \n"
- + "</script>"
- + "</head><body onload='setTarget();' style='margin:0;padding:0; background:transparent;' class=\""
- + ApplicationConnection.GENERATED_BODY_CLASSNAME
- + "\">"
- + "<div class='v-app v-app-loginpage' style=\"background:transparent;\">"
- + "<iframe name='logintarget' style='width:0;height:0;"
- + "border:0;margin:0;padding:0;'></iframe>"
- + "<form id='loginf' target='logintarget' onkeypress=\"submitOnEnter(event)\" method=\"post\">"
- + "<div>"
- + usernameCaption
- + "</div><div >"
- + "<input class='v-textfield v-connector' style='display:block;' type='text' name='username'></div>"
- + "<div>"
- + passwordCaption
- + "</div>"
- + "<div><input class='v-textfield v-connector' style='display:block;' type='password' name='password'></div>"
- + "<div><div onclick=\"document.forms[0].submit();\" tabindex=\"0\" class=\"v-button\" role=\"button\" ><span class=\"v-button-wrap\"><span class=\"v-button-caption\">"
- + loginButtonCaption
- + "</span></span></div></div></form></div>" + "</body></html>")
- .getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("UTF-8 encoding not avalable", e);
- }
- }
-
- @Override
- public void attach() {
- super.attach();
- getApplication().addResource(loginPage);
- getApplication().addRequestHandler(requestHandler);
- iframe.setSource(loginPage);
- }
-
- @Override
- public void detach() {
- getApplication().removeResource(loginPage);
- getApplication().removeRequestHandler(requestHandler);
-
- super.detach();
- }
-
- /**
- * This event is sent when login form is submitted.
- */
- public class LoginEvent extends Event {
-
- private Map<String, String> params;
-
- private LoginEvent(Map<String, String> params) {
- super(LoginForm.this);
- this.params = params;
- }
-
- /**
- * Access method to form values by field names.
- *
- * @param name
- * @return value in given field
- */
- public String getLoginParameter(String name) {
- if (params.containsKey(name)) {
- return params.get(name);
- } else {
- return null;
- }
- }
- }
-
- /**
- * Login listener is a class capable to listen LoginEvents sent from
- * LoginBox
- */
- public interface LoginListener extends Serializable {
- /**
- * This method is fired on each login form post.
- *
- * @param event
- */
- public void onLogin(LoginForm.LoginEvent event);
- }
-
- private static final Method ON_LOGIN_METHOD;
-
- private static final String UNDEFINED_HEIGHT = "140px";
- private static final String UNDEFINED_WIDTH = "200px";
-
- static {
- try {
- ON_LOGIN_METHOD = LoginListener.class.getDeclaredMethod("onLogin",
- new Class[] { LoginEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in LoginForm");
- }
- }
-
- /**
- * Adds LoginListener to handle login logic
- *
- * @param listener
- */
- public void addListener(LoginListener listener) {
- addListener(LoginEvent.class, listener, ON_LOGIN_METHOD);
- }
-
- /**
- * Removes LoginListener
- *
- * @param listener
- */
- public void removeListener(LoginListener listener) {
- removeListener(LoginEvent.class, listener, ON_LOGIN_METHOD);
- }
-
- @Override
- public void setWidth(float width, Unit unit) {
- super.setWidth(width, unit);
- if (iframe != null) {
- if (width < 0) {
- iframe.setWidth(UNDEFINED_WIDTH);
- } else {
- iframe.setWidth("100%");
- }
- }
- }
-
- @Override
- public void setHeight(float height, Unit unit) {
- super.setHeight(height, unit);
- if (iframe != null) {
- if (height < 0) {
- iframe.setHeight(UNDEFINED_HEIGHT);
- } else {
- iframe.setHeight("100%");
- }
- }
- }
-
- /**
- * Returns the caption for the user name field.
- *
- * @return String
- */
- public String getUsernameCaption() {
- return usernameCaption;
- }
-
- /**
- * Sets the caption to show for the user name field. The caption cannot be
- * changed after the form has been shown to the user.
- *
- * @param usernameCaption
- */
- public void setUsernameCaption(String usernameCaption) {
- this.usernameCaption = usernameCaption;
- }
-
- /**
- * Returns the caption for the password field.
- *
- * @return String
- */
- public String getPasswordCaption() {
- return passwordCaption;
- }
-
- /**
- * Sets the caption to show for the password field. The caption cannot be
- * changed after the form has been shown to the user.
- *
- * @param passwordCaption
- */
- public void setPasswordCaption(String passwordCaption) {
- this.passwordCaption = passwordCaption;
- }
-
- /**
- * Returns the caption for the login button.
- *
- * @return String
- */
- public String getLoginButtonCaption() {
- return loginButtonCaption;
- }
-
- /**
- * Sets the caption (button text) to show for the login button. The caption
- * cannot be changed after the form has been shown to the user.
- *
- * @param loginButtonCaption
- */
- public void setLoginButtonCaption(String loginButtonCaption) {
- this.loginButtonCaption = loginButtonCaption;
- }
-
-}
diff --git a/src/com/vaadin/ui/MenuBar.java b/src/com/vaadin/ui/MenuBar.java
deleted file mode 100644
index 5b5dc13e20..0000000000
--- a/src/com/vaadin/ui/MenuBar.java
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.menubar.VMenuBar;
-
-/**
- * <p>
- * A class representing a horizontal menu bar. The menu can contain MenuItem
- * objects, which in turn can contain more MenuBars. These sub-level MenuBars
- * are represented as vertical menu.
- * </p>
- */
-@SuppressWarnings("serial")
-public class MenuBar extends AbstractComponent implements Vaadin6Component {
-
- // Items of the top-level menu
- private final List<MenuItem> menuItems;
-
- // Number of items in this menu
- private int numberOfItems = 0;
-
- private MenuItem moreItem;
-
- private boolean openRootOnHover;
-
- private boolean htmlContentAllowed;
-
- /** Paint (serialise) the component for the client. */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER, openRootOnHover);
-
- if (isHtmlContentAllowed()) {
- target.addAttribute(VMenuBar.HTML_CONTENT_ALLOWED, true);
- }
-
- target.startTag("options");
-
- if (getWidth() > -1) {
- target.startTag("moreItem");
- target.addAttribute("text", moreItem.getText());
- if (moreItem.getIcon() != null) {
- target.addAttribute("icon", moreItem.getIcon());
- }
- target.endTag("moreItem");
- }
-
- target.endTag("options");
- target.startTag("items");
-
- // This generates the tree from the contents of the menu
- for (MenuItem item : menuItems) {
- paintItem(target, item);
- }
-
- target.endTag("items");
- }
-
- private void paintItem(PaintTarget target, MenuItem item)
- throws PaintException {
- if (!item.isVisible()) {
- return;
- }
-
- target.startTag("item");
-
- target.addAttribute("id", item.getId());
-
- if (item.getStyleName() != null) {
- target.addAttribute(VMenuBar.ATTRIBUTE_ITEM_STYLE,
- item.getStyleName());
- }
-
- if (item.isSeparator()) {
- target.addAttribute("separator", true);
- } else {
- target.addAttribute("text", item.getText());
-
- Command command = item.getCommand();
- if (command != null) {
- target.addAttribute("command", true);
- }
-
- Resource icon = item.getIcon();
- if (icon != null) {
- target.addAttribute(VMenuBar.ATTRIBUTE_ITEM_ICON, icon);
- }
-
- if (!item.isEnabled()) {
- target.addAttribute(VMenuBar.ATTRIBUTE_ITEM_DISABLED, true);
- }
-
- String description = item.getDescription();
- if (description != null && description.length() > 0) {
- target.addAttribute(VMenuBar.ATTRIBUTE_ITEM_DESCRIPTION,
- description);
- }
- if (item.isCheckable()) {
- // if the "checked" attribute is present (either true or false),
- // the item is checkable
- target.addAttribute(VMenuBar.ATTRIBUTE_CHECKED,
- item.isChecked());
- }
- if (item.hasChildren()) {
- for (MenuItem child : item.getChildren()) {
- paintItem(target, child);
- }
- }
-
- }
-
- target.endTag("item");
- }
-
- /** Deserialize changes received from client. */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- Stack<MenuItem> items = new Stack<MenuItem>();
- boolean found = false;
-
- if (variables.containsKey("clickedId")) {
-
- Integer clickedId = (Integer) variables.get("clickedId");
- Iterator<MenuItem> itr = getItems().iterator();
- while (itr.hasNext()) {
- items.push(itr.next());
- }
-
- MenuItem tmpItem = null;
-
- // Go through all the items in the menu
- while (!found && !items.empty()) {
- tmpItem = items.pop();
- found = (clickedId.intValue() == tmpItem.getId());
-
- if (tmpItem.hasChildren()) {
- itr = tmpItem.getChildren().iterator();
- while (itr.hasNext()) {
- items.push(itr.next());
- }
- }
-
- }// while
-
- // If we got the clicked item, launch the command.
- if (found && tmpItem.isEnabled()) {
- if (tmpItem.isCheckable()) {
- tmpItem.setChecked(!tmpItem.isChecked());
- }
- if (null != tmpItem.getCommand()) {
- tmpItem.getCommand().menuSelected(tmpItem);
- }
- }
- }// if
- }// changeVariables
-
- /**
- * Constructs an empty, horizontal menu
- */
- public MenuBar() {
- menuItems = new ArrayList<MenuItem>();
- setMoreMenuItem(null);
- }
-
- /**
- * Add a new item to the menu bar. Command can be null, but a caption must
- * be given.
- *
- * @param caption
- * the text for the menu item
- * @param command
- * the command for the menu item
- * @throws IllegalArgumentException
- */
- public MenuBar.MenuItem addItem(String caption, MenuBar.Command command) {
- return addItem(caption, null, command);
- }
-
- /**
- * Add a new item to the menu bar. Icon and command can be null, but a
- * caption must be given.
- *
- * @param caption
- * the text for the menu item
- * @param icon
- * the icon for the menu item
- * @param command
- * the command for the menu item
- * @throws IllegalArgumentException
- */
- public MenuBar.MenuItem addItem(String caption, Resource icon,
- MenuBar.Command command) {
- if (caption == null) {
- throw new IllegalArgumentException("caption cannot be null");
- }
- MenuItem newItem = new MenuItem(caption, icon, command);
- menuItems.add(newItem);
- requestRepaint();
-
- return newItem;
-
- }
-
- /**
- * Add an item before some item. If the given item does not exist the item
- * is added at the end of the menu. Icon and command can be null, but a
- * caption must be given.
- *
- * @param caption
- * the text for the menu item
- * @param icon
- * the icon for the menu item
- * @param command
- * the command for the menu item
- * @param itemToAddBefore
- * the item that will be after the new item
- * @throws IllegalArgumentException
- */
- public MenuBar.MenuItem addItemBefore(String caption, Resource icon,
- MenuBar.Command command, MenuBar.MenuItem itemToAddBefore) {
- if (caption == null) {
- throw new IllegalArgumentException("caption cannot be null");
- }
-
- MenuItem newItem = new MenuItem(caption, icon, command);
- if (menuItems.contains(itemToAddBefore)) {
- int index = menuItems.indexOf(itemToAddBefore);
- menuItems.add(index, newItem);
-
- } else {
- menuItems.add(newItem);
- }
-
- requestRepaint();
-
- return newItem;
- }
-
- /**
- * Returns a list with all the MenuItem objects in the menu bar
- *
- * @return a list containing the MenuItem objects in the menu bar
- */
- public List<MenuItem> getItems() {
- return menuItems;
- }
-
- /**
- * Remove first occurrence the specified item from the main menu
- *
- * @param item
- * The item to be removed
- */
- public void removeItem(MenuBar.MenuItem item) {
- if (item != null) {
- menuItems.remove(item);
- }
- requestRepaint();
- }
-
- /**
- * Empty the menu bar
- */
- public void removeItems() {
- menuItems.clear();
- requestRepaint();
- }
-
- /**
- * Returns the size of the menu.
- *
- * @return The size of the menu
- */
- public int getSize() {
- return menuItems.size();
- }
-
- /**
- * Set the item that is used when collapsing the top level menu. All
- * "overflowing" items will be added below this. The item command will be
- * ignored. If set to null, the default item with a downwards arrow is used.
- *
- * The item command (if specified) is ignored.
- *
- * @param item
- */
- public void setMoreMenuItem(MenuItem item) {
- if (item != null) {
- moreItem = item;
- } else {
- moreItem = new MenuItem("", null, null);
- }
- requestRepaint();
- }
-
- /**
- * Get the MenuItem used as the collapse menu item.
- *
- * @return
- */
- public MenuItem getMoreMenuItem() {
- return moreItem;
- }
-
- /**
- * Using this method menubar can be put into a special mode where top level
- * menus opens without clicking on the menu, but automatically when mouse
- * cursor is moved over the menu. In this mode the menu also closes itself
- * if the mouse is moved out of the opened menu.
- * <p>
- * Note, that on touch devices the menu still opens on a click event.
- *
- * @param autoOpenTopLevelMenu
- * true if menus should be opened without click, the default is
- * false
- */
- public void setAutoOpen(boolean autoOpenTopLevelMenu) {
- if (autoOpenTopLevelMenu != openRootOnHover) {
- openRootOnHover = autoOpenTopLevelMenu;
- requestRepaint();
- }
- }
-
- /**
- * Detects whether the menubar is in a mode where top level menus are
- * automatically opened when the mouse cursor is moved over the menu.
- * Normally root menu opens only by clicking on the menu. Submenus always
- * open automatically.
- *
- * @return true if the root menus open without click, the default is false
- */
- public boolean isAutoOpen() {
- return openRootOnHover;
- }
-
- /**
- * Sets whether html is allowed in the item captions. If set to true, the
- * captions are passed to the browser as html and the developer is
- * responsible for ensuring no harmful html is used. If set to false, the
- * content is passed to the browser as plain text.
- *
- * @param htmlContentAllowed
- * true if the captions are used as html, false if used as plain
- * text
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- this.htmlContentAllowed = htmlContentAllowed;
- requestRepaint();
- }
-
- /**
- * Checks whether item captions are interpreted as html or plain text.
- *
- * @return true if the captions are used as html, false if used as plain
- * text
- * @see #setHtmlContentAllowed(boolean)
- */
- public boolean isHtmlContentAllowed() {
- return htmlContentAllowed;
- }
-
- /**
- * This interface contains the layer for menu commands of the
- * {@link com.vaadin.ui.MenuBar} class. It's method will fire when the user
- * clicks on the containing {@link com.vaadin.ui.MenuBar.MenuItem}. The
- * selected item is given as an argument.
- */
- public interface Command extends Serializable {
- public void menuSelected(MenuBar.MenuItem selectedItem);
- }
-
- /**
- * A composite class for menu items and sub-menus. You can set commands to
- * be fired on user click by implementing the
- * {@link com.vaadin.ui.MenuBar.Command} interface. You can also add
- * multiple MenuItems to a MenuItem and create a sub-menu.
- *
- */
- public class MenuItem implements Serializable {
-
- /** Private members * */
- private final int itsId;
- private Command itsCommand;
- private String itsText;
- private List<MenuItem> itsChildren;
- private Resource itsIcon;
- private MenuItem itsParent;
- private boolean enabled = true;
- private boolean visible = true;
- private boolean isSeparator = false;
- private String styleName;
- private String description;
- private boolean checkable = false;
- private boolean checked = false;
-
- /**
- * Constructs a new menu item that can optionally have an icon and a
- * command associated with it. Icon and command can be null, but a
- * caption must be given.
- *
- * @param text
- * The text associated with the command
- * @param command
- * The command to be fired
- * @throws IllegalArgumentException
- */
- public MenuItem(String caption, Resource icon, MenuBar.Command command) {
- if (caption == null) {
- throw new IllegalArgumentException("caption cannot be null");
- }
- itsId = ++numberOfItems;
- itsText = caption;
- itsIcon = icon;
- itsCommand = command;
- }
-
- /**
- * Checks if the item has children (if it is a sub-menu).
- *
- * @return True if this item has children
- */
- public boolean hasChildren() {
- return !isSeparator() && itsChildren != null;
- }
-
- /**
- * Adds a separator to this menu. A separator is a way to visually group
- * items in a menu, to make it easier for users to find what they are
- * looking for in the menu.
- *
- * @author Jouni Koivuviita / Vaadin Ltd.
- * @since 6.2.0
- */
- public MenuBar.MenuItem addSeparator() {
- MenuItem item = addItem("", null, null);
- item.setSeparator(true);
- return item;
- }
-
- public MenuBar.MenuItem addSeparatorBefore(MenuItem itemToAddBefore) {
- MenuItem item = addItemBefore("", null, null, itemToAddBefore);
- item.setSeparator(true);
- return item;
- }
-
- /**
- * Add a new item inside this item, thus creating a sub-menu. Command
- * can be null, but a caption must be given.
- *
- * @param caption
- * the text for the menu item
- * @param command
- * the command for the menu item
- */
- public MenuBar.MenuItem addItem(String caption, MenuBar.Command command) {
- return addItem(caption, null, command);
- }
-
- /**
- * Add a new item inside this item, thus creating a sub-menu. Icon and
- * command can be null, but a caption must be given.
- *
- * @param caption
- * the text for the menu item
- * @param icon
- * the icon for the menu item
- * @param command
- * the command for the menu item
- * @throws IllegalStateException
- * If the item is checkable and thus cannot have children.
- */
- public MenuBar.MenuItem addItem(String caption, Resource icon,
- MenuBar.Command command) throws IllegalStateException {
- if (isSeparator()) {
- throw new UnsupportedOperationException(
- "Cannot add items to a separator");
- }
- if (isCheckable()) {
- throw new IllegalStateException(
- "A checkable item cannot have children");
- }
- if (caption == null) {
- throw new IllegalArgumentException("Caption cannot be null");
- }
-
- if (itsChildren == null) {
- itsChildren = new ArrayList<MenuItem>();
- }
-
- MenuItem newItem = new MenuItem(caption, icon, command);
-
- // The only place where the parent is set
- newItem.setParent(this);
- itsChildren.add(newItem);
-
- requestRepaint();
-
- return newItem;
- }
-
- /**
- * Add an item before some item. If the given item does not exist the
- * item is added at the end of the menu. Icon and command can be null,
- * but a caption must be given.
- *
- * @param caption
- * the text for the menu item
- * @param icon
- * the icon for the menu item
- * @param command
- * the command for the menu item
- * @param itemToAddBefore
- * the item that will be after the new item
- * @throws IllegalStateException
- * If the item is checkable and thus cannot have children.
- */
- public MenuBar.MenuItem addItemBefore(String caption, Resource icon,
- MenuBar.Command command, MenuBar.MenuItem itemToAddBefore)
- throws IllegalStateException {
- if (isCheckable()) {
- throw new IllegalStateException(
- "A checkable item cannot have children");
- }
- MenuItem newItem = null;
-
- if (hasChildren() && itsChildren.contains(itemToAddBefore)) {
- int index = itsChildren.indexOf(itemToAddBefore);
- newItem = new MenuItem(caption, icon, command);
- newItem.setParent(this);
- itsChildren.add(index, newItem);
- } else {
- newItem = addItem(caption, icon, command);
- }
-
- requestRepaint();
-
- return newItem;
- }
-
- /**
- * For the associated command.
- *
- * @return The associated command, or null if there is none
- */
- public Command getCommand() {
- return itsCommand;
- }
-
- /**
- * Gets the objects icon.
- *
- * @return The icon of the item, null if the item doesn't have an icon
- */
- public Resource getIcon() {
- return itsIcon;
- }
-
- /**
- * For the containing item. This will return null if the item is in the
- * top-level menu bar.
- *
- * @return The containing {@link com.vaadin.ui.MenuBar.MenuItem} , or
- * null if there is none
- */
- public MenuBar.MenuItem getParent() {
- return itsParent;
- }
-
- /**
- * This will return the children of this item or null if there are none.
- *
- * @return List of children items, or null if there are none
- */
- public List<MenuItem> getChildren() {
- return itsChildren;
- }
-
- /**
- * Gets the objects text
- *
- * @return The text
- */
- public java.lang.String getText() {
- return itsText;
- }
-
- /**
- * Returns the number of children.
- *
- * @return The number of child items
- */
- public int getSize() {
- if (itsChildren != null) {
- return itsChildren.size();
- }
- return -1;
- }
-
- /**
- * Get the unique identifier for this item.
- *
- * @return The id of this item
- */
- public int getId() {
- return itsId;
- }
-
- /**
- * Set the command for this item. Set null to remove.
- *
- * @param command
- * The MenuCommand of this item
- */
- public void setCommand(MenuBar.Command command) {
- itsCommand = command;
- }
-
- /**
- * Sets the icon. Set null to remove.
- *
- * @param icon
- * The icon for this item
- */
- public void setIcon(Resource icon) {
- itsIcon = icon;
- requestRepaint();
- }
-
- /**
- * Set the text of this object.
- *
- * @param text
- * Text for this object
- */
- public void setText(java.lang.String text) {
- if (text != null) {
- itsText = text;
- }
- requestRepaint();
- }
-
- /**
- * Remove the first occurrence of the item.
- *
- * @param item
- * The item to be removed
- */
- public void removeChild(MenuBar.MenuItem item) {
- if (item != null && itsChildren != null) {
- itsChildren.remove(item);
- if (itsChildren.isEmpty()) {
- itsChildren = null;
- }
- requestRepaint();
- }
- }
-
- /**
- * Empty the list of children items.
- */
- public void removeChildren() {
- if (itsChildren != null) {
- itsChildren.clear();
- itsChildren = null;
- requestRepaint();
- }
- }
-
- /**
- * Set the parent of this item. This is called by the addItem method.
- *
- * @param parent
- * The parent item
- */
- protected void setParent(MenuBar.MenuItem parent) {
- itsParent = parent;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- requestRepaint();
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setVisible(boolean visible) {
- this.visible = visible;
- requestRepaint();
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- private void setSeparator(boolean isSeparator) {
- this.isSeparator = isSeparator;
- requestRepaint();
- }
-
- public boolean isSeparator() {
- return isSeparator;
- }
-
- public void setStyleName(String styleName) {
- this.styleName = styleName;
- requestRepaint();
- }
-
- public String getStyleName() {
- return styleName;
- }
-
- /**
- * Sets the items's description. See {@link #getDescription()} for more
- * information on what the description is. This method will trigger a
- * {@link RepaintRequestEvent}.
- *
- * @param description
- * the new description string for the component.
- */
- public void setDescription(String description) {
- this.description = description;
- requestRepaint();
- }
-
- /**
- * <p>
- * Gets the items's description. The description can be used to briefly
- * describe the state of the item to the user. The description string
- * may contain certain XML tags:
- * </p>
- *
- * <p>
- * <table border=1>
- * <tr>
- * <td width=120><b>Tag</b></td>
- * <td width=120><b>Description</b></td>
- * <td width=120><b>Example</b></td>
- * </tr>
- * <tr>
- * <td>&lt;b></td>
- * <td>bold</td>
- * <td><b>bold text</b></td>
- * </tr>
- * <tr>
- * <td>&lt;i></td>
- * <td>italic</td>
- * <td><i>italic text</i></td>
- * </tr>
- * <tr>
- * <td>&lt;u></td>
- * <td>underlined</td>
- * <td><u>underlined text</u></td>
- * </tr>
- * <tr>
- * <td>&lt;br></td>
- * <td>linebreak</td>
- * <td>N/A</td>
- * </tr>
- * <tr>
- * <td>&lt;ul><br>
- * &lt;li>item1<br>
- * &lt;li>item1<br>
- * &lt;/ul></td>
- * <td>item list</td>
- * <td>
- * <ul>
- * <li>item1
- * <li>item2
- * </ul>
- * </td>
- * </tr>
- * </table>
- * </p>
- *
- * <p>
- * These tags may be nested.
- * </p>
- *
- * @return item's description <code>String</code>
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Gets the checkable state of the item - whether the item has checked
- * and unchecked states. If an item is checkable its checked state (as
- * returned by {@link #isChecked()}) is indicated in the UI.
- *
- * <p>
- * An item is not checkable by default.
- * </p>
- *
- * @return true if the item is checkable, false otherwise
- * @since 6.6.2
- */
- public boolean isCheckable() {
- return checkable;
- }
-
- /**
- * Sets the checkable state of the item. If an item is checkable its
- * checked state (as returned by {@link #isChecked()}) is indicated in
- * the UI.
- *
- * <p>
- * An item is not checkable by default.
- * </p>
- *
- * <p>
- * Items with sub items cannot be checkable.
- * </p>
- *
- * @param checkable
- * true if the item should be checkable, false otherwise
- * @throws IllegalStateException
- * If the item has children
- * @since 6.6.2
- */
- public void setCheckable(boolean checkable)
- throws IllegalStateException {
- if (hasChildren()) {
- throw new IllegalStateException(
- "A menu item with children cannot be checkable");
- }
- this.checkable = checkable;
- requestRepaint();
- }
-
- /**
- * Gets the checked state of the item (checked or unchecked). Only used
- * if the item is checkable (as indicated by {@link #isCheckable()}).
- * The checked state is indicated in the UI with the item, if the item
- * is checkable.
- *
- * <p>
- * An item is not checked by default.
- * </p>
- *
- * <p>
- * The CSS style corresponding to the checked state is "-checked".
- * </p>
- *
- * @return true if the item is checked, false otherwise
- * @since 6.6.2
- */
- public boolean isChecked() {
- return checked;
- }
-
- /**
- * Sets the checked state of the item. Only used if the item is
- * checkable (indicated by {@link #isCheckable()}). The checked state is
- * indicated in the UI with the item, if the item is checkable.
- *
- * <p>
- * An item is not checked by default.
- * </p>
- *
- * <p>
- * The CSS style corresponding to the checked state is "-checked".
- * </p>
- *
- * @return true if the item is checked, false otherwise
- * @since 6.6.2
- */
- public void setChecked(boolean checked) {
- this.checked = checked;
- requestRepaint();
- }
-
- }// class MenuItem
-
-}// class MenuBar
diff --git a/src/com/vaadin/ui/NativeButton.java b/src/com/vaadin/ui/NativeButton.java
deleted file mode 100644
index 6eb4379261..0000000000
--- a/src/com/vaadin/ui/NativeButton.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-@SuppressWarnings("serial")
-public class NativeButton extends Button {
-
- public NativeButton() {
- super();
- }
-
- public NativeButton(String caption) {
- super(caption);
- }
-
- public NativeButton(String caption, ClickListener listener) {
- super(caption, listener);
- }
-
-}
diff --git a/src/com/vaadin/ui/NativeSelect.java b/src/com/vaadin/ui/NativeSelect.java
deleted file mode 100644
index 1f85f57c97..0000000000
--- a/src/com/vaadin/ui/NativeSelect.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * This is a simple drop-down select without, for instance, support for
- * multiselect, new items, lazyloading, and other advanced features. Sometimes
- * "native" select without all the bells-and-whistles of the ComboBox is a
- * better choice.
- */
-@SuppressWarnings("serial")
-public class NativeSelect extends AbstractSelect {
-
- // width in characters, mimics TextField
- private int columns = 0;
-
- public NativeSelect() {
- super();
- }
-
- public NativeSelect(String caption, Collection<?> options) {
- super(caption, options);
- }
-
- public NativeSelect(String caption, Container dataSource) {
- super(caption, dataSource);
- }
-
- public NativeSelect(String caption) {
- super(caption);
- }
-
- /**
- * Sets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- *
- * @param columns
- * the number of columns to set.
- */
- public void setColumns(int columns) {
- if (columns < 0) {
- columns = 0;
- }
- if (this.columns != columns) {
- this.columns = columns;
- requestRepaint();
- }
- }
-
- public int getColumns() {
- return columns;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute("type", "native");
- // Adds the number of columns
- if (columns != 0) {
- target.addAttribute("cols", columns);
- }
-
- super.paintContent(target);
- }
-
- @Override
- public void setMultiSelect(boolean multiSelect)
- throws UnsupportedOperationException {
- if (multiSelect == true) {
- throw new UnsupportedOperationException("Multiselect not supported");
- }
- }
-
- @Override
- public void setNewItemsAllowed(boolean allowNewOptions)
- throws UnsupportedOperationException {
- if (allowNewOptions == true) {
- throw new UnsupportedOperationException(
- "newItemsAllowed not supported");
- }
- }
-
-}
diff --git a/src/com/vaadin/ui/Notification.java b/src/com/vaadin/ui/Notification.java
deleted file mode 100644
index 502e5ff788..0000000000
--- a/src/com/vaadin/ui/Notification.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.terminal.Page;
-import com.vaadin.terminal.Resource;
-
-/**
- * A notification message, used to display temporary messages to the user - for
- * example "Document saved", or "Save failed".
- * <p>
- * The notification message can consist of several parts: caption, description
- * and icon. It is usually used with only caption - one should be wary of
- * filling the notification with too much information.
- * </p>
- * <p>
- * The notification message tries to be as unobtrusive as possible, while still
- * drawing needed attention. There are several basic types of messages that can
- * be used in different situations:
- * <ul>
- * <li>TYPE_HUMANIZED_MESSAGE fades away quickly as soon as the user uses the
- * mouse or types something. It can be used to show fairly unimportant messages,
- * such as feedback that an operation succeeded ("Document Saved") - the kind of
- * messages the user ignores once the application is familiar.</li>
- * <li>TYPE_WARNING_MESSAGE is shown for a short while after the user uses the
- * mouse or types something. It's default style is also more noticeable than the
- * humanized message. It can be used for messages that do not contain a lot of
- * important information, but should be noticed by the user. Despite the name,
- * it does not have to be a warning, but can be used instead of the humanized
- * message whenever you want to make the message a little more noticeable.</li>
- * <li>TYPE_ERROR_MESSAGE requires to user to click it before disappearing, and
- * can be used for critical messages.</li>
- * <li>TYPE_TRAY_NOTIFICATION is shown for a while in the lower left corner of
- * the window, and can be used for "convenience notifications" that do not have
- * to be noticed immediately, and should not interfere with the current task -
- * for instance to show "You have a new message in your inbox" while the user is
- * working in some other area of the application.</li>
- * </ul>
- * </p>
- * <p>
- * In addition to the basic pre-configured types, a Notification can also be
- * configured to show up in a custom position, for a specified time (or until
- * clicked), and with a custom stylename. An icon can also be added.
- * </p>
- *
- */
-public class Notification implements Serializable {
- public static final int TYPE_HUMANIZED_MESSAGE = 1;
- public static final int TYPE_WARNING_MESSAGE = 2;
- public static final int TYPE_ERROR_MESSAGE = 3;
- public static final int TYPE_TRAY_NOTIFICATION = 4;
-
- public static final int POSITION_CENTERED = 1;
- public static final int POSITION_CENTERED_TOP = 2;
- public static final int POSITION_CENTERED_BOTTOM = 3;
- public static final int POSITION_TOP_LEFT = 4;
- public static final int POSITION_TOP_RIGHT = 5;
- public static final int POSITION_BOTTOM_LEFT = 6;
- public static final int POSITION_BOTTOM_RIGHT = 7;
-
- public static final int DELAY_FOREVER = -1;
- public static final int DELAY_NONE = 0;
-
- private String caption;
- private String description;
- private Resource icon;
- private int position = POSITION_CENTERED;
- private int delayMsec = 0;
- private String styleName;
- private boolean htmlContentAllowed;
-
- /**
- * Creates a "humanized" notification message.
- *
- * The caption is rendered as plain text with HTML automatically escaped.
- *
- * @param caption
- * The message to show
- */
- public Notification(String caption) {
- this(caption, null, TYPE_HUMANIZED_MESSAGE);
- }
-
- /**
- * Creates a notification message of the specified type.
- *
- * The caption is rendered as plain text with HTML automatically escaped.
- *
- * @param caption
- * The message to show
- * @param type
- * The type of message
- */
- public Notification(String caption, int type) {
- this(caption, null, type);
- }
-
- /**
- * Creates a "humanized" notification message with a bigger caption and
- * smaller description.
- *
- * The caption and description are rendered as plain text with HTML
- * automatically escaped.
- *
- * @param caption
- * The message caption
- * @param description
- * The message description
- */
- public Notification(String caption, String description) {
- this(caption, description, TYPE_HUMANIZED_MESSAGE);
- }
-
- /**
- * Creates a notification message of the specified type, with a bigger
- * caption and smaller description.
- *
- * The caption and description are rendered as plain text with HTML
- * automatically escaped.
- *
- * @param caption
- * The message caption
- * @param description
- * The message description
- * @param type
- * The type of message
- */
- public Notification(String caption, String description, int type) {
- this(caption, description, type, false);
- }
-
- /**
- * Creates a notification message of the specified type, with a bigger
- * caption and smaller description.
- *
- * Care should be taken to to avoid XSS vulnerabilities if html is allowed.
- *
- * @param caption
- * The message caption
- * @param description
- * The message description
- * @param type
- * The type of message
- * @param htmlContentAllowed
- * Whether html in the caption and description should be
- * displayed as html or as plain text
- */
- public Notification(String caption, String description, int type,
- boolean htmlContentAllowed) {
- this.caption = caption;
- this.description = description;
- this.htmlContentAllowed = htmlContentAllowed;
- setType(type);
- }
-
- private void setType(int type) {
- switch (type) {
- case TYPE_WARNING_MESSAGE:
- delayMsec = 1500;
- styleName = "warning";
- break;
- case TYPE_ERROR_MESSAGE:
- delayMsec = -1;
- styleName = "error";
- break;
- case TYPE_TRAY_NOTIFICATION:
- delayMsec = 3000;
- position = POSITION_BOTTOM_RIGHT;
- styleName = "tray";
-
- case TYPE_HUMANIZED_MESSAGE:
- default:
- break;
- }
-
- }
-
- /**
- * Gets the caption part of the notification message.
- *
- * @return The message caption
- */
- public String getCaption() {
- return caption;
- }
-
- /**
- * Sets the caption part of the notification message
- *
- * @param caption
- * The message caption
- */
- public void setCaption(String caption) {
- this.caption = caption;
- }
-
- /**
- * Gets the description part of the notification message.
- *
- * @return The message description.
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Sets the description part of the notification message.
- *
- * @param description
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * Gets the position of the notification message.
- *
- * @return The position
- */
- public int getPosition() {
- return position;
- }
-
- /**
- * Sets the position of the notification message.
- *
- * @param position
- * The desired notification position
- */
- public void setPosition(int position) {
- this.position = position;
- }
-
- /**
- * Gets the icon part of the notification message.
- *
- * @return The message icon
- */
- public Resource getIcon() {
- return icon;
- }
-
- /**
- * Sets the icon part of the notification message.
- *
- * @param icon
- * The desired message icon
- */
- public void setIcon(Resource icon) {
- this.icon = icon;
- }
-
- /**
- * Gets the delay before the notification disappears.
- *
- * @return the delay in msec, -1 indicates the message has to be clicked.
- */
- public int getDelayMsec() {
- return delayMsec;
- }
-
- /**
- * Sets the delay before the notification disappears.
- *
- * @param delayMsec
- * the desired delay in msec, -1 to require the user to click the
- * message
- */
- public void setDelayMsec(int delayMsec) {
- this.delayMsec = delayMsec;
- }
-
- /**
- * Sets the style name for the notification message.
- *
- * @param styleName
- * The desired style name.
- */
- public void setStyleName(String styleName) {
- this.styleName = styleName;
- }
-
- /**
- * Gets the style name for the notification message.
- *
- * @return
- */
- public String getStyleName() {
- return styleName;
- }
-
- /**
- * Sets whether html is allowed in the caption and description. If set to
- * true, the texts are passed to the browser as html and the developer is
- * responsible for ensuring no harmful html is used. If set to false, the
- * texts are passed to the browser as plain text.
- *
- * @param htmlContentAllowed
- * true if the texts are used as html, false if used as plain
- * text
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- this.htmlContentAllowed = htmlContentAllowed;
- }
-
- /**
- * Checks whether caption and description are interpreted as html or plain
- * text.
- *
- * @return true if the texts are used as html, false if used as plain text
- * @see #setHtmlContentAllowed(boolean)
- */
- public boolean isHtmlContentAllowed() {
- return htmlContentAllowed;
- }
-
- /**
- * Shows this notification on a Page.
- *
- * @param page
- * The page on which the notification should be shown
- */
- public void show(Page page) {
- // TODO Can avoid deprecated API when Notification extends Extension
- page.showNotification(this);
- }
-
- /**
- * Shows a notification message on the middle of the current page. The
- * message automatically disappears ("humanized message").
- *
- * The caption is rendered as plain text with HTML automatically escaped.
- *
- * @see #Notification(String)
- * @see #show(Page)
- *
- * @param caption
- * The message
- */
- public static void show(String caption) {
- new Notification(caption).show(Page.getCurrent());
- }
-
- /**
- * Shows a notification message the current page. The position and behavior
- * of the message depends on the type, which is one of the basic types
- * defined in {@link Notification}, for instance
- * Notification.TYPE_WARNING_MESSAGE.
- *
- * The caption is rendered as plain text with HTML automatically escaped.
- *
- * @see #Notification(String, int)
- * @see #show(Page)
- *
- * @param caption
- * The message
- * @param type
- * The message type
- */
- public static void show(String caption, int type) {
- new Notification(caption, type).show(Page.getCurrent());
- }
-} \ No newline at end of file
diff --git a/src/com/vaadin/ui/OptionGroup.java b/src/com/vaadin/ui/OptionGroup.java
deleted file mode 100644
index e3bcdd61b7..0000000000
--- a/src/com/vaadin/ui/OptionGroup.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import com.vaadin.data.Container;
-import com.vaadin.event.FieldEvents;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.optiongroup.VOptionGroup;
-
-/**
- * Configures select to be used as an option group.
- */
-@SuppressWarnings("serial")
-public class OptionGroup extends AbstractSelect implements
- FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
-
- private Set<Object> disabledItemIds = new HashSet<Object>();
- private boolean htmlContentAllowed = false;
-
- public OptionGroup() {
- super();
- }
-
- public OptionGroup(String caption, Collection<?> options) {
- super(caption, options);
- }
-
- public OptionGroup(String caption, Container dataSource) {
- super(caption, dataSource);
- }
-
- public OptionGroup(String caption) {
- super(caption);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute("type", "optiongroup");
- if (isHtmlContentAllowed()) {
- target.addAttribute(VOptionGroup.HTML_CONTENT_ALLOWED, true);
- }
- super.paintContent(target);
- }
-
- @Override
- protected void paintItem(PaintTarget target, Object itemId)
- throws PaintException {
- super.paintItem(target, itemId);
- if (!isItemEnabled(itemId)) {
- target.addAttribute(VOptionGroup.ATTRIBUTE_OPTION_DISABLED, true);
- }
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- super.changeVariables(source, variables);
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
-
- }
-
- @Override
- protected void setValue(Object newValue, boolean repaintIsNotNeeded) {
- if (repaintIsNotNeeded) {
- /*
- * Check that value from changeVariables() doesn't contain unallowed
- * selections: In the multi select mode, the user has selected or
- * deselected a disabled item. In the single select mode, the user
- * has selected a disabled item.
- */
- if (isMultiSelect()) {
- Set<?> currentValueSet = (Set<?>) getValue();
- Set<?> newValueSet = (Set<?>) newValue;
- for (Object itemId : currentValueSet) {
- if (!isItemEnabled(itemId) && !newValueSet.contains(itemId)) {
- requestRepaint();
- return;
- }
- }
- for (Object itemId : newValueSet) {
- if (!isItemEnabled(itemId)
- && !currentValueSet.contains(itemId)) {
- requestRepaint();
- return;
- }
- }
- } else {
- if (newValue == null) {
- newValue = getNullSelectionItemId();
- }
- if (!isItemEnabled(newValue)) {
- requestRepaint();
- return;
- }
- }
- }
- super.setValue(newValue, repaintIsNotNeeded);
- }
-
- /**
- * Sets an item disabled or enabled. In the multiselect mode, a disabled
- * item cannot be selected or deselected by the user. In the single
- * selection mode, a disable item cannot be selected.
- *
- * However, programmatical selection or deselection of an disable item is
- * possible. By default, items are enabled.
- *
- * @param itemId
- * the id of the item to be disabled or enabled
- * @param enabled
- * if true the item is enabled, otherwise the item is disabled
- */
- public void setItemEnabled(Object itemId, boolean enabled) {
- if (itemId != null) {
- if (enabled) {
- disabledItemIds.remove(itemId);
- } else {
- disabledItemIds.add(itemId);
- }
- requestRepaint();
- }
- }
-
- /**
- * Returns true if the item is enabled.
- *
- * @param itemId
- * the id of the item to be checked
- * @return true if the item is enabled, false otherwise
- * @see #setItemEnabled(Object, boolean)
- */
- public boolean isItemEnabled(Object itemId) {
- if (itemId != null) {
- return !disabledItemIds.contains(itemId);
- }
- return true;
- }
-
- /**
- * Sets whether html is allowed in the item captions. If set to true, the
- * captions are passed to the browser as html and the developer is
- * responsible for ensuring no harmful html is used. If set to false, the
- * content is passed to the browser as plain text.
- *
- * @param htmlContentAllowed
- * true if the captions are used as html, false if used as plain
- * text
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- this.htmlContentAllowed = htmlContentAllowed;
- requestRepaint();
- }
-
- /**
- * Checks whether captions are interpreted as html or plain text.
- *
- * @return true if the captions are used as html, false if used as plain
- * text
- * @see #setHtmlContentAllowed(boolean)
- */
- public boolean isHtmlContentAllowed() {
- return htmlContentAllowed;
- }
-}
diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java
deleted file mode 100644
index 3c26b73f09..0000000000
--- a/src/com/vaadin/ui/Panel.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.vaadin.event.Action;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.event.ActionManager;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.MouseEvents.ClickListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.panel.PanelServerRpc;
-import com.vaadin.shared.ui.panel.PanelState;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Scrollable;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.ClickEventHandler;
-import com.vaadin.ui.Component.Focusable;
-
-/**
- * Panel - a simple single component container.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Panel extends AbstractComponentContainer implements Scrollable,
- ComponentContainer.ComponentAttachListener,
- ComponentContainer.ComponentDetachListener, Action.Notifier, Focusable,
- Vaadin6Component {
-
- /**
- * Content of the panel.
- */
- private ComponentContainer content;
-
- /**
- * Keeps track of the Actions added to this component, and manages the
- * painting and handling as well.
- */
- protected ActionManager actionManager;
-
- private PanelServerRpc rpc = new PanelServerRpc() {
- @Override
- public void click(MouseEventDetails mouseDetails) {
- fireEvent(new ClickEvent(Panel.this, mouseDetails));
- }
- };
-
- /**
- * Creates a new empty panel. A VerticalLayout is used as content.
- */
- public Panel() {
- this((ComponentContainer) null);
- }
-
- /**
- * Creates a new empty panel which contains the given content. The content
- * cannot be null.
- *
- * @param content
- * the content for the panel.
- */
- public Panel(ComponentContainer content) {
- registerRpc(rpc);
- setContent(content);
- setWidth(100, Unit.PERCENTAGE);
- getState().setTabIndex(-1);
- }
-
- /**
- * Creates a new empty panel with caption. Default layout is used.
- *
- * @param caption
- * the caption used in the panel (HTML/XHTML).
- */
- public Panel(String caption) {
- this(caption, null);
- }
-
- /**
- * Creates a new empty panel with the given caption and content.
- *
- * @param caption
- * the caption of the panel (HTML/XHTML).
- * @param content
- * the content used in the panel.
- */
- public Panel(String caption, ComponentContainer content) {
- this(content);
- setCaption(caption);
- }
-
- /**
- * Sets the caption of the panel.
- *
- * Note that the caption is interpreted as HTML/XHTML and therefore care
- * should be taken not to enable HTML injection and XSS attacks using panel
- * captions. This behavior may change in future versions.
- *
- * @see AbstractComponent#setCaption(String)
- */
- @Override
- public void setCaption(String caption) {
- super.setCaption(caption);
- }
-
- /**
- * Returns the content of the Panel.
- *
- * @return
- */
- public ComponentContainer getContent() {
- return content;
- }
-
- /**
- *
- * Set the content of the Panel. If null is given as the new content then a
- * layout is automatically created and set as the content.
- *
- * @param content
- * The new content
- */
- public void setContent(ComponentContainer newContent) {
-
- // If the content is null we create the default content
- if (newContent == null) {
- newContent = createDefaultContent();
- }
-
- // if (newContent == null) {
- // throw new IllegalArgumentException("Content cannot be null");
- // }
-
- if (newContent == content) {
- // don't set the same content twice
- return;
- }
-
- // detach old content if present
- if (content != null) {
- content.setParent(null);
- content.removeListener((ComponentContainer.ComponentAttachListener) this);
- content.removeListener((ComponentContainer.ComponentDetachListener) this);
- }
-
- // Sets the panel to be parent for the content
- newContent.setParent(this);
-
- // Sets the new content
- content = newContent;
-
- // Adds the event listeners for new content
- newContent
- .addListener((ComponentContainer.ComponentAttachListener) this);
- newContent
- .addListener((ComponentContainer.ComponentDetachListener) this);
-
- content = newContent;
- requestRepaint();
- }
-
- /**
- * Create a ComponentContainer which is added by default to the Panel if
- * user does not specify any content.
- *
- * @return
- */
- private ComponentContainer createDefaultContent() {
- VerticalLayout layout = new VerticalLayout();
- // Force margins by default
- layout.setMargin(true);
- return layout;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.Vaadin6Component#paintContent(com.vaadin.terminal
- * .PaintTarget)
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (actionManager != null) {
- actionManager.paintActions(null, target);
- }
- }
-
- /**
- * Adds the component into this container.
- *
- * @param c
- * the component to be added.
- * @see com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component)
- */
- @Override
- public void addComponent(Component c) {
- content.addComponent(c);
- // No repaint request is made as we except the underlying container to
- // request repaints
- }
-
- /**
- * Removes the component from this container.
- *
- * @param c
- * The component to be removed.
- * @see com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui.Component)
- */
- @Override
- public void removeComponent(Component c) {
- content.removeComponent(c);
- // No repaint request is made as we except the underlying container to
- // request repaints
- }
-
- /**
- * Gets the component container iterator for going through all the
- * components in the container.
- *
- * @return the Iterator of the components inside the container.
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return Collections.singleton((Component) content).iterator();
- }
-
- /**
- * Called when one or more variables handled by the implementing class are
- * changed.
- *
- * @see com.vaadin.terminal.VariableOwner#changeVariables(Object, Map)
- */
- @Override
- @SuppressWarnings("unchecked")
- public void changeVariables(Object source, Map<String, Object> variables) {
- // Get new size
- final Integer newWidth = (Integer) variables.get("width");
- final Integer newHeight = (Integer) variables.get("height");
- if (newWidth != null && newWidth.intValue() != getWidth()) {
- setWidth(newWidth.intValue(), UNITS_PIXELS);
- }
- if (newHeight != null && newHeight.intValue() != getHeight()) {
- setHeight(newHeight.intValue(), UNITS_PIXELS);
- }
-
- // Scrolling
- final Integer newScrollX = (Integer) variables.get("scrollLeft");
- final Integer newScrollY = (Integer) variables.get("scrollTop");
- if (newScrollX != null && newScrollX.intValue() != getScrollLeft()) {
- // set internally, not to fire request repaint
- getState().setScrollLeft(newScrollX.intValue());
- }
- if (newScrollY != null && newScrollY.intValue() != getScrollTop()) {
- // set internally, not to fire request repaint
- getState().setScrollTop(newScrollY.intValue());
- }
-
- // Actions
- if (actionManager != null) {
- actionManager.handleActions(variables, this);
- }
-
- }
-
- /* Scrolling functionality */
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Scrollable#setScrollable(boolean)
- */
- @Override
- public int getScrollLeft() {
- return getState().getScrollLeft();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Scrollable#setScrollable(boolean)
- */
- @Override
- public int getScrollTop() {
- return getState().getScrollTop();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Scrollable#setScrollLeft(int)
- */
- @Override
- public void setScrollLeft(int scrollLeft) {
- if (scrollLeft < 0) {
- throw new IllegalArgumentException(
- "Scroll offset must be at least 0");
- }
- getState().setScrollLeft(scrollLeft);
- requestRepaint();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.terminal.Scrollable#setScrollTop(int)
- */
- @Override
- public void setScrollTop(int scrollTop) {
- if (scrollTop < 0) {
- throw new IllegalArgumentException(
- "Scroll offset must be at least 0");
- }
- getState().setScrollTop(scrollTop);
- requestRepaint();
- }
-
- /* Documented in superclass */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- content.replaceComponent(oldComponent, newComponent);
- }
-
- /**
- * A new component is attached to container.
- *
- * @see com.vaadin.ui.ComponentContainer.ComponentAttachListener#componentAttachedToContainer(com.vaadin.ui.ComponentContainer.ComponentAttachEvent)
- */
- @Override
- public void componentAttachedToContainer(ComponentAttachEvent event) {
- if (event.getContainer() == content) {
- fireComponentAttachEvent(event.getAttachedComponent());
- }
- }
-
- /**
- * A component has been detached from container.
- *
- * @see com.vaadin.ui.ComponentContainer.ComponentDetachListener#componentDetachedFromContainer(com.vaadin.ui.ComponentContainer.ComponentDetachEvent)
- */
- @Override
- public void componentDetachedFromContainer(ComponentDetachEvent event) {
- if (event.getContainer() == content) {
- fireComponentDetachEvent(event.getDetachedComponent());
- }
- }
-
- /**
- * Removes all components from this container.
- *
- * @see com.vaadin.ui.ComponentContainer#removeAllComponents()
- */
- @Override
- public void removeAllComponents() {
- content.removeAllComponents();
- }
-
- /*
- * ACTIONS
- */
- @Override
- protected ActionManager getActionManager() {
- if (actionManager == null) {
- actionManager = new ActionManager(this);
- }
- return actionManager;
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void addAction(
- T action) {
- getActionManager().addAction(action);
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void removeAction(
- T action) {
- if (actionManager != null) {
- actionManager.removeAction(action);
- }
- }
-
- @Override
- public void addActionHandler(Handler actionHandler) {
- getActionManager().addActionHandler(actionHandler);
- }
-
- @Override
- public void removeActionHandler(Handler actionHandler) {
- if (actionManager != null) {
- actionManager.removeActionHandler(actionHandler);
- }
- }
-
- /**
- * Removes all action handlers
- */
- public void removeAllActionHandlers() {
- if (actionManager != null) {
- actionManager.removeAllActionHandlers();
- }
- }
-
- /**
- * Add a click listener to the Panel. The listener is called whenever the
- * user clicks inside the Panel. Also when the click targets a component
- * inside the Panel, provided the targeted component does not prevent the
- * click event from propagating.
- *
- * Use {@link #removeListener(ClickListener)} to remove the listener.
- *
- * @param listener
- * The listener to add
- */
- public void addListener(ClickListener listener) {
- addListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, ClickEvent.class,
- listener, ClickListener.clickMethod);
- }
-
- /**
- * Remove a click listener from the Panel. The listener should earlier have
- * been added using {@link #addListener(ClickListener)}.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(ClickListener listener) {
- removeListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER,
- ClickEvent.class, listener);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getTabIndex() {
- return getState().getTabIndex();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setTabIndex(int tabIndex) {
- getState().setTabIndex(tabIndex);
- requestRepaint();
- }
-
- /**
- * Moves keyboard focus to the component. {@see Focusable#focus()}
- *
- */
- @Override
- public void focus() {
- super.focus();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentCount()
- */
- @Override
- public int getComponentCount() {
- // This is so wrong... (#2924)
- return content.getComponentCount();
- }
-
- @Override
- public PanelState getState() {
- return (PanelState) super.getState();
- }
-
-}
diff --git a/src/com/vaadin/ui/PasswordField.java b/src/com/vaadin/ui/PasswordField.java
deleted file mode 100644
index c1fccebbfe..0000000000
--- a/src/com/vaadin/ui/PasswordField.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import com.vaadin.data.Property;
-
-/**
- * A field that is used to enter secret text information like passwords. The
- * entered text is not displayed on the screen.
- */
-public class PasswordField extends AbstractTextField {
-
- /**
- * Constructs an empty PasswordField.
- */
- public PasswordField() {
- setValue("");
- }
-
- /**
- * Constructs a PasswordField with given property data source.
- *
- * @param dataSource
- * the property data source for the field
- */
- public PasswordField(Property dataSource) {
- setPropertyDataSource(dataSource);
- }
-
- /**
- * Constructs a PasswordField with given caption and property data source.
- *
- * @param caption
- * the caption for the field
- * @param dataSource
- * the property data source for the field
- */
- public PasswordField(String caption, Property dataSource) {
- this(dataSource);
- setCaption(caption);
- }
-
- /**
- * Constructs a PasswordField with given value and caption.
- *
- * @param caption
- * the caption for the field
- * @param value
- * the value for the field
- */
- public PasswordField(String caption, String value) {
- setValue(value);
- setCaption(caption);
- }
-
- /**
- * Constructs a PasswordField with given caption.
- *
- * @param caption
- * the caption for the field
- */
- public PasswordField(String caption) {
- this();
- setCaption(caption);
- }
-}
diff --git a/src/com/vaadin/ui/PopupDateField.java b/src/com/vaadin/ui/PopupDateField.java
deleted file mode 100644
index 3688d4035f..0000000000
--- a/src/com/vaadin/ui/PopupDateField.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Date;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-
-/**
- * <p>
- * A date entry component, which displays the actual date selector as a popup.
- *
- * </p>
- *
- * @see DateField
- * @see InlineDateField
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
-public class PopupDateField extends DateField {
-
- private String inputPrompt = null;
-
- public PopupDateField() {
- super();
- }
-
- public PopupDateField(Property dataSource) throws IllegalArgumentException {
- super(dataSource);
- }
-
- public PopupDateField(String caption, Date value) {
- super(caption, value);
- }
-
- public PopupDateField(String caption, Property dataSource) {
- super(caption, dataSource);
- }
-
- public PopupDateField(String caption) {
- super(caption);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
-
- if (inputPrompt != null) {
- target.addAttribute("prompt", inputPrompt);
- }
- }
-
- /**
- * Gets the current input prompt.
- *
- * @see #setInputPrompt(String)
- * @return the current input prompt, or null if not enabled
- */
- public String getInputPrompt() {
- return inputPrompt;
- }
-
- /**
- * Sets the input prompt - a textual prompt that is displayed when the field
- * would otherwise be empty, to prompt the user for input.
- *
- * @param inputPrompt
- */
- public void setInputPrompt(String inputPrompt) {
- this.inputPrompt = inputPrompt;
- requestRepaint();
- }
-
-}
diff --git a/src/com/vaadin/ui/PopupView.java b/src/com/vaadin/ui/PopupView.java
deleted file mode 100644
index 766181b50f..0000000000
--- a/src/com/vaadin/ui/PopupView.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.vaadin.terminal.LegacyPaint;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- *
- * A component for displaying a two different views to data. The minimized view
- * is normally used to render the component, and when it is clicked the full
- * view is displayed on a popup. The inner class {@link PopupView.Content} is
- * used to deliver contents to this component.
- *
- * @author Vaadin Ltd.
- */
-@SuppressWarnings("serial")
-public class PopupView extends AbstractComponentContainer implements
- Vaadin6Component {
-
- private Content content;
- private boolean hideOnMouseOut;
- private Component visibleComponent;
-
- private static final Method POPUP_VISIBILITY_METHOD;
- static {
- try {
- POPUP_VISIBILITY_METHOD = PopupVisibilityListener.class
- .getDeclaredMethod("popupVisibilityChange",
- new Class[] { PopupVisibilityEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in PopupView");
- }
- }
-
- /**
- * Iterator for the visible components (zero or one components), used by
- * {@link PopupView#getComponentIterator()}.
- */
- private static class SingleComponentIterator implements
- Iterator<Component>, Serializable {
-
- private final Component component;
- private boolean first;
-
- public SingleComponentIterator(Component component) {
- this.component = component;
- first = (component == null);
- }
-
- @Override
- public boolean hasNext() {
- return !first;
- }
-
- @Override
- public Component next() {
- if (!first) {
- first = true;
- return component;
- } else {
- return null;
- }
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- /* Constructors */
-
- /**
- * A simple way to create a PopupPanel. Note that the minimal representation
- * may not be dynamically updated, in order to achieve this create your own
- * Content object and use {@link PopupView#PopupView(Content)}.
- *
- * @param small
- * the minimal textual representation as HTML
- * @param large
- * the full, Component-type representation
- */
- public PopupView(final java.lang.String small, final Component large) {
- this(new PopupView.Content() {
- @Override
- public java.lang.String getMinimizedValueAsHTML() {
- return small;
- }
-
- @Override
- public Component getPopupComponent() {
- return large;
- }
- });
-
- }
-
- /**
- * Creates a PopupView through the PopupView.Content interface. This allows
- * the creator to dynamically change the contents of the PopupView.
- *
- * @param content
- * the PopupView.Content that contains the information for this
- */
- public PopupView(PopupView.Content content) {
- super();
- hideOnMouseOut = true;
- setContent(content);
- }
-
- /**
- * This method will replace the current content of the panel with a new one.
- *
- * @param newContent
- * PopupView.Content object containing new information for the
- * PopupView
- * @throws IllegalArgumentException
- * if the method is passed a null value, or if one of the
- * content methods returns null
- */
- public void setContent(PopupView.Content newContent)
- throws IllegalArgumentException {
- if (newContent == null) {
- throw new IllegalArgumentException("Content must not be null");
- }
- content = newContent;
- requestRepaint();
- }
-
- /**
- * Returns the content-package for this PopupView.
- *
- * @return the PopupView.Content for this object or null
- */
- public PopupView.Content getContent() {
- return content;
- }
-
- /**
- * @deprecated Use {@link #setPopupVisible()} instead.
- */
- @Deprecated
- public void setPopupVisibility(boolean visible) {
- setPopupVisible(visible);
- }
-
- /**
- * @deprecated Use {@link #isPopupVisible()} instead.
- */
- @Deprecated
- public boolean getPopupVisibility() {
- return isPopupVisible();
- }
-
- /**
- * Set the visibility of the popup. Does not hide the minimal
- * representation.
- *
- * @param visible
- */
- public void setPopupVisible(boolean visible) {
- if (isPopupVisible() != visible) {
- if (visible) {
- visibleComponent = content.getPopupComponent();
- if (visibleComponent == null) {
- throw new java.lang.IllegalStateException(
- "PopupView.Content did not return Component to set visible");
- }
- super.addComponent(visibleComponent);
- } else {
- super.removeComponent(visibleComponent);
- visibleComponent = null;
- }
- fireEvent(new PopupVisibilityEvent(this));
- requestRepaint();
- }
- }
-
- /**
- * Return whether the popup is visible.
- *
- * @return true if the popup is showing
- */
- public boolean isPopupVisible() {
- return visibleComponent != null;
- }
-
- /**
- * Check if this popup will be hidden when the user takes the mouse cursor
- * out of the popup area.
- *
- * @return true if the popup is hidden on mouse out, false otherwise
- */
- public boolean isHideOnMouseOut() {
- return hideOnMouseOut;
- }
-
- /**
- * Should the popup automatically hide when the user takes the mouse cursor
- * out of the popup area? If this is false, the user must click outside the
- * popup to close it. The default is true.
- *
- * @param hideOnMouseOut
- *
- */
- public void setHideOnMouseOut(boolean hideOnMouseOut) {
- this.hideOnMouseOut = hideOnMouseOut;
- }
-
- /*
- * Methods inherited from AbstractComponentContainer. These are unnecessary
- * (but mandatory). Most of them are not supported in this implementation.
- */
-
- /**
- * This class only contains other components when the popup is showing.
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- return new SingleComponentIterator(visibleComponent);
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components (zero or one)
- */
- @Override
- public int getComponentCount() {
- return (visibleComponent != null ? 1 : 0);
- }
-
- /**
- * Not supported in this implementation.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#removeAllComponents()
- * @throws UnsupportedOperationException
- */
- @Override
- public void removeAllComponents() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported in this implementation.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#moveComponentsFrom(com.vaadin.ui.ComponentContainer)
- * @throws UnsupportedOperationException
- */
- @Override
- public void moveComponentsFrom(ComponentContainer source)
- throws UnsupportedOperationException {
-
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported in this implementation.
- *
- * @see com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component)
- * @throws UnsupportedOperationException
- */
- @Override
- public void addComponent(Component c) throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
-
- }
-
- /**
- * Not supported in this implementation.
- *
- * @see com.vaadin.ui.ComponentContainer#replaceComponent(com.vaadin.ui.Component,
- * com.vaadin.ui.Component)
- * @throws UnsupportedOperationException
- */
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent)
- throws UnsupportedOperationException {
-
- throw new UnsupportedOperationException();
- }
-
- /**
- * Not supported in this implementation
- *
- * @see com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui.Component)
- */
- @Override
- public void removeComponent(Component c)
- throws UnsupportedOperationException {
- throw new UnsupportedOperationException();
-
- }
-
- /*
- * Methods for server-client communications.
- */
-
- /**
- * Paint (serialize) the component for the client.
- *
- * @see com.vaadin.ui.AbstractComponent#paintContent(com.vaadin.terminal.PaintTarget)
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- String html = content.getMinimizedValueAsHTML();
- if (html == null) {
- html = "";
- }
- target.addAttribute("html", html);
- target.addAttribute("hideOnMouseOut", hideOnMouseOut);
-
- // Only paint component to client if we know that the popup is showing
- if (isPopupVisible()) {
- target.startTag("popupComponent");
- LegacyPaint.paint(visibleComponent, target);
- target.endTag("popupComponent");
- }
-
- target.addVariable(this, "popupVisibility", isPopupVisible());
- }
-
- /**
- * Deserialize changes received from client.
- *
- * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey("popupVisibility")) {
- setPopupVisible(((Boolean) variables.get("popupVisibility"))
- .booleanValue());
- }
- }
-
- /**
- * Used to deliver customized content-packages to the PopupView. These are
- * dynamically loaded when they are redrawn. The user must take care that
- * neither of these methods ever return null.
- */
- public interface Content extends Serializable {
-
- /**
- * This should return a small view of the full data.
- *
- * @return value in HTML format
- */
- public String getMinimizedValueAsHTML();
-
- /**
- * This should return the full Component representing the data
- *
- * @return a Component for the value
- */
- public Component getPopupComponent();
- }
-
- /**
- * Add a listener that is called whenever the visibility of the popup is
- * changed.
- *
- * @param listener
- * the listener to add
- * @see PopupVisibilityListener
- * @see PopupVisibilityEvent
- * @see #removeListener(PopupVisibilityListener)
- *
- */
- public void addListener(PopupVisibilityListener listener) {
- addListener(PopupVisibilityEvent.class, listener,
- POPUP_VISIBILITY_METHOD);
- }
-
- /**
- * Removes a previously added listener, so that it no longer receives events
- * when the visibility of the popup changes.
- *
- * @param listener
- * the listener to remove
- * @see PopupVisibilityListener
- * @see #addListener(PopupVisibilityListener)
- */
- public void removeListener(PopupVisibilityListener listener) {
- removeListener(PopupVisibilityEvent.class, listener,
- POPUP_VISIBILITY_METHOD);
- }
-
- /**
- * This event is received by the PopupVisibilityListeners when the
- * visibility of the popup changes. You can get the new visibility directly
- * with {@link #isPopupVisible()}, or get the PopupView that produced the
- * event with {@link #getPopupView()}.
- *
- */
- public class PopupVisibilityEvent extends Event {
-
- public PopupVisibilityEvent(PopupView source) {
- super(source);
- }
-
- /**
- * Get the PopupView instance that is the source of this event.
- *
- * @return the source PopupView
- */
- public PopupView getPopupView() {
- return (PopupView) getSource();
- }
-
- /**
- * Returns the current visibility of the popup.
- *
- * @return true if the popup is visible
- */
- public boolean isPopupVisible() {
- return getPopupView().isPopupVisible();
- }
- }
-
- /**
- * Defines a listener that can receive a PopupVisibilityEvent when the
- * visibility of the popup changes.
- *
- */
- public interface PopupVisibilityListener extends Serializable {
- /**
- * Pass to {@link PopupView#PopupVisibilityEvent} to start listening for
- * popup visibility changes.
- *
- * @param event
- * the event
- *
- * @see {@link PopupVisibilityEvent}
- * @see {@link PopupView#addListener(PopupVisibilityListener)}
- */
- public void popupVisibilityChange(PopupVisibilityEvent event);
- }
-}
diff --git a/src/com/vaadin/ui/ProgressIndicator.java b/src/com/vaadin/ui/ProgressIndicator.java
deleted file mode 100644
index fef54a267c..0000000000
--- a/src/com/vaadin/ui/ProgressIndicator.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Map;
-
-import com.vaadin.data.Property;
-import com.vaadin.data.util.ObjectProperty;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- * <code>ProgressIndicator</code> is component that shows user state of a
- * process (like long computing or file upload)
- *
- * <code>ProgressIndicator</code> has two mainmodes. One for indeterminate
- * processes and other (default) for processes which progress can be measured
- *
- * May view an other property that indicates progress 0...1
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 4
- */
-@SuppressWarnings("serial")
-public class ProgressIndicator extends AbstractField<Number> implements
- Property.Viewer, Property.ValueChangeListener, Vaadin6Component {
-
- /**
- * Content mode, where the label contains only plain text. The getValue()
- * result is coded to XML when painting.
- */
- public static final int CONTENT_TEXT = 0;
-
- /**
- * Content mode, where the label contains preformatted text.
- */
- public static final int CONTENT_PREFORMATTED = 1;
-
- private boolean indeterminate = false;
-
- private Property dataSource;
-
- private int pollingInterval = 1000;
-
- /**
- * Creates an a new ProgressIndicator.
- */
- public ProgressIndicator() {
- setPropertyDataSource(new ObjectProperty<Float>(new Float(0),
- Float.class));
- }
-
- /**
- * Creates a new instance of ProgressIndicator with given state.
- *
- * @param value
- */
- public ProgressIndicator(Float value) {
- setPropertyDataSource(new ObjectProperty<Float>(value, Float.class));
- }
-
- /**
- * Creates a new instance of ProgressIndicator with stae read from given
- * datasource.
- *
- * @param contentSource
- */
- public ProgressIndicator(Property contentSource) {
- setPropertyDataSource(contentSource);
- }
-
- /**
- * Sets the component to read-only. Readonly is not used in
- * ProgressIndicator.
- *
- * @param readOnly
- * True to enable read-only mode, False to disable it.
- */
- @Override
- public void setReadOnly(boolean readOnly) {
- if (dataSource == null) {
- throw new IllegalStateException("Datasource must be se");
- }
- dataSource.setReadOnly(readOnly);
- }
-
- /**
- * Is the component read-only ? Readonly is not used in ProgressIndicator -
- * this returns allways false.
- *
- * @return True if the component is in read only mode.
- */
- @Override
- public boolean isReadOnly() {
- if (dataSource == null) {
- throw new IllegalStateException("Datasource must be se");
- }
- return dataSource.isReadOnly();
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the Paint Operation fails.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute("indeterminate", indeterminate);
- target.addAttribute("pollinginterval", pollingInterval);
- target.addAttribute("state", getValue().toString());
- }
-
- /**
- * Gets the value of the ProgressIndicator. Value of the ProgressIndicator
- * is Float between 0 and 1.
- *
- * @return the Value of the ProgressIndicator.
- * @see com.vaadin.ui.AbstractField#getValue()
- */
- @Override
- public Number getValue() {
- if (dataSource == null) {
- throw new IllegalStateException("Datasource must be set");
- }
- // TODO conversions to eliminate cast
- return (Number) dataSource.getValue();
- }
-
- /**
- * Sets the value of the ProgressIndicator. Value of the ProgressIndicator
- * is the Float between 0 and 1.
- *
- * @param newValue
- * the New value of the ProgressIndicator.
- * @see com.vaadin.ui.AbstractField#setValue()
- */
- @Override
- public void setValue(Object newValue) {
- if (dataSource == null) {
- throw new IllegalStateException("Datasource must be set");
- }
- dataSource.setValue(newValue);
- }
-
- /**
- * @see com.vaadin.ui.AbstractField#getType()
- */
- @Override
- public Class<? extends Number> getType() {
- if (dataSource == null) {
- throw new IllegalStateException("Datasource must be set");
- }
- return dataSource.getType();
- }
-
- /**
- * Gets the viewing data-source property.
- *
- * @return the datasource.
- * @see com.vaadin.ui.AbstractField#getPropertyDataSource()
- */
- @Override
- public Property getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- * Sets the property as data-source for viewing.
- *
- * @param newDataSource
- * the new data source.
- * @see com.vaadin.ui.AbstractField#setPropertyDataSource(com.vaadin.data.Property)
- */
- @Override
- public void setPropertyDataSource(Property newDataSource) {
- // Stops listening the old data source changes
- if (dataSource != null
- && Property.ValueChangeNotifier.class
- .isAssignableFrom(dataSource.getClass())) {
- ((Property.ValueChangeNotifier) dataSource).removeListener(this);
- }
-
- // Sets the new data source
- dataSource = newDataSource;
-
- // Listens the new data source if possible
- if (dataSource != null
- && Property.ValueChangeNotifier.class
- .isAssignableFrom(dataSource.getClass())) {
- ((Property.ValueChangeNotifier) dataSource).addListener(this);
- }
- }
-
- /**
- * Gets the mode of ProgressIndicator.
- *
- * @return true if in indeterminate mode.
- */
- public boolean getContentMode() {
- return indeterminate;
- }
-
- /**
- * Sets wheter or not the ProgressIndicator is indeterminate.
- *
- * @param newValue
- * true to set to indeterminate mode.
- */
- public void setIndeterminate(boolean newValue) {
- indeterminate = newValue;
- requestRepaint();
- }
-
- /**
- * Gets whether or not the ProgressIndicator is indeterminate.
- *
- * @return true to set to indeterminate mode.
- */
- public boolean isIndeterminate() {
- return indeterminate;
- }
-
- /**
- * Sets the interval that component checks for progress.
- *
- * @param newValue
- * the interval in milliseconds.
- */
- public void setPollingInterval(int newValue) {
- pollingInterval = newValue;
- requestRepaint();
- }
-
- /**
- * Gets the interval that component checks for progress.
- *
- * @return the interval in milliseconds.
- */
- public int getPollingInterval() {
- return pollingInterval;
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // TODO Remove once Vaadin6Component is no longer implemented
-
- }
-
-}
diff --git a/src/com/vaadin/ui/RichTextArea.java b/src/com/vaadin/ui/RichTextArea.java
deleted file mode 100644
index cec952926b..0000000000
--- a/src/com/vaadin/ui/RichTextArea.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.text.Format;
-import java.util.Map;
-
-import com.vaadin.data.Property;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- * A simple RichTextArea to edit HTML format text.
- *
- * Note, that using {@link TextField#setMaxLength(int)} method in
- * {@link RichTextArea} may produce unexpected results as formatting is counted
- * into length of field.
- */
-public class RichTextArea extends AbstractField<String> implements
- Vaadin6Component {
-
- /**
- * Value formatter used to format the string contents.
- */
- @Deprecated
- private Format format;
-
- /**
- * Null representation.
- */
- private String nullRepresentation = "null";
-
- /**
- * Is setting to null from non-null value allowed by setting with null
- * representation .
- */
- private boolean nullSettingAllowed = false;
-
- /**
- * Temporary flag that indicates all content will be selected after the next
- * paint. Reset to false after painted.
- */
- private boolean selectAll = false;
-
- /**
- * Constructs an empty <code>RichTextArea</code> with no caption.
- */
- public RichTextArea() {
- setValue("");
- }
-
- /**
- *
- * Constructs an empty <code>RichTextArea</code> with the given caption.
- *
- * @param caption
- * the caption for the editor.
- */
- public RichTextArea(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>RichTextArea</code> that's bound to the specified
- * <code>Property</code> and has no caption.
- *
- * @param dataSource
- * the data source for the editor value
- */
- public RichTextArea(Property dataSource) {
- setPropertyDataSource(dataSource);
- }
-
- /**
- * Constructs a new <code>RichTextArea</code> that's bound to the specified
- * <code>Property</code> and has the given caption.
- *
- * @param caption
- * the caption for the editor.
- * @param dataSource
- * the data source for the editor value
- */
- public RichTextArea(String caption, Property dataSource) {
- this(dataSource);
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>RichTextArea</code> with the given caption and
- * initial text contents.
- *
- * @param caption
- * the caption for the editor.
- * @param value
- * the initial text content of the editor.
- */
- public RichTextArea(String caption, String value) {
- setValue(value);
- setCaption(caption);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (selectAll) {
- target.addAttribute("selectAll", true);
- selectAll = false;
- }
-
- // Adds the content as variable
- String value = getFormattedValue();
- if (value == null) {
- value = getNullRepresentation();
- }
- if (value == null) {
- throw new IllegalStateException(
- "Null values are not allowed if the null-representation is null");
- }
- target.addVariable(this, "text", value);
-
- }
-
- @Override
- public void setReadOnly(boolean readOnly) {
- super.setReadOnly(readOnly);
- // IE6 cannot support multi-classname selectors properly
- // TODO Can be optimized now that support for I6 is dropped
- if (readOnly) {
- addStyleName("v-richtextarea-readonly");
- } else {
- removeStyleName("v-richtextarea-readonly");
- }
- }
-
- /**
- * Selects all text in the rich text area. As a side effect, focuses the
- * rich text area.
- *
- * @since 6.5
- */
- public void selectAll() {
- /*
- * Set selection range functionality is currently being
- * planned/developed for GWT RTA. Only selecting all is currently
- * supported. Consider moving selectAll and other selection related
- * functions to AbstractTextField at that point to share the
- * implementation. Some third party components extending
- * AbstractTextField might however not want to support them.
- */
- selectAll = true;
- focus();
- requestRepaint();
- }
-
- /**
- * Gets the formatted string value. Sets the field value by using the
- * assigned Format.
- *
- * @return the Formatted value.
- * @see #setFormat(Format)
- * @see Format
- * @deprecated
- */
- @Deprecated
- protected String getFormattedValue() {
- Object v = getValue();
- if (v == null) {
- return null;
- }
- return v.toString();
- }
-
- @Override
- public String getValue() {
- String v = super.getValue();
- if (format == null || v == null) {
- return v;
- }
- try {
- return format.format(v);
- } catch (final IllegalArgumentException e) {
- return v;
- }
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // Sets the text
- if (variables.containsKey("text") && !isReadOnly()) {
-
- // Only do the setting if the string representation of the value
- // has been updated
- String newValue = (String) variables.get("text");
-
- final String oldValue = getFormattedValue();
- if (newValue != null
- && (oldValue == null || isNullSettingAllowed())
- && newValue.equals(getNullRepresentation())) {
- newValue = null;
- }
- if (newValue != oldValue
- && (newValue == null || !newValue.equals(oldValue))) {
- boolean wasModified = isModified();
- setValue(newValue, true);
-
- // If the modified status changes, or if we have a formatter,
- // repaint is needed after all.
- if (format != null || wasModified != isModified()) {
- requestRepaint();
- }
- }
- }
-
- }
-
- @Override
- public Class<String> getType() {
- return String.class;
- }
-
- /**
- * Gets the null-string representation.
- *
- * <p>
- * The null-valued strings are represented on the user interface by
- * replacing the null value with this string. If the null representation is
- * set null (not 'null' string), painting null value throws exception.
- * </p>
- *
- * <p>
- * The default value is string 'null'.
- * </p>
- *
- * @return the String Textual representation for null strings.
- * @see TextField#isNullSettingAllowed()
- */
- public String getNullRepresentation() {
- return nullRepresentation;
- }
-
- /**
- * Is setting nulls with null-string representation allowed.
- *
- * <p>
- * If this property is true, writing null-representation string to text
- * field always sets the field value to real null. If this property is
- * false, null setting is not made, but the null values are maintained.
- * Maintenance of null-values is made by only converting the textfield
- * contents to real null, if the text field matches the null-string
- * representation and the current value of the field is null.
- * </p>
- *
- * <p>
- * By default this setting is false
- * </p>
- *
- * @return boolean Should the null-string represenation be always converted
- * to null-values.
- * @see TextField#getNullRepresentation()
- */
- public boolean isNullSettingAllowed() {
- return nullSettingAllowed;
- }
-
- /**
- * Sets the null-string representation.
- *
- * <p>
- * The null-valued strings are represented on the user interface by
- * replacing the null value with this string. If the null representation is
- * set null (not 'null' string), painting null value throws exception.
- * </p>
- *
- * <p>
- * The default value is string 'null'
- * </p>
- *
- * @param nullRepresentation
- * Textual representation for null strings.
- * @see TextField#setNullSettingAllowed(boolean)
- */
- public void setNullRepresentation(String nullRepresentation) {
- this.nullRepresentation = nullRepresentation;
- }
-
- /**
- * Sets the null conversion mode.
- *
- * <p>
- * If this property is true, writing null-representation string to text
- * field always sets the field value to real null. If this property is
- * false, null setting is not made, but the null values are maintained.
- * Maintenance of null-values is made by only converting the textfield
- * contents to real null, if the text field matches the null-string
- * representation and the current value of the field is null.
- * </p>
- *
- * <p>
- * By default this setting is false.
- * </p>
- *
- * @param nullSettingAllowed
- * Should the null-string represenation be always converted to
- * null-values.
- * @see TextField#getNullRepresentation()
- */
- public void setNullSettingAllowed(boolean nullSettingAllowed) {
- this.nullSettingAllowed = nullSettingAllowed;
- }
-
- /**
- * Gets the value formatter of TextField.
- *
- * @return the Format used to format the value.
- * @deprecated replaced by {@link com.vaadin.data.util.PropertyFormatter}
- */
- @Deprecated
- public Format getFormat() {
- return format;
- }
-
- /**
- * Gets the value formatter of TextField.
- *
- * @param format
- * the Format used to format the value. Null disables the
- * formatting.
- * @deprecated replaced by {@link com.vaadin.data.util.PropertyFormatter}
- */
- @Deprecated
- public void setFormat(Format format) {
- this.format = format;
- requestRepaint();
- }
-
- @Override
- protected boolean isEmpty() {
- return super.isEmpty() || getValue().length() == 0;
- }
-
-}
diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java
deleted file mode 100644
index bd4842632b..0000000000
--- a/src/com/vaadin/ui/Root.java
+++ /dev/null
@@ -1,1227 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Map;
-
-import com.vaadin.Application;
-import com.vaadin.annotations.EagerInit;
-import com.vaadin.event.Action;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.event.ActionManager;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.MouseEvents.ClickListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.root.RootServerRpc;
-import com.vaadin.shared.ui.root.RootState;
-import com.vaadin.terminal.Page;
-import com.vaadin.terminal.Page.BrowserWindowResizeEvent;
-import com.vaadin.terminal.Page.BrowserWindowResizeListener;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.WrappedRequest;
-import com.vaadin.terminal.WrappedRequest.BrowserDetails;
-import com.vaadin.terminal.gwt.client.ui.root.VRoot;
-import com.vaadin.ui.Window.CloseListener;
-
-/**
- * The topmost component in any component hierarchy. There is one root for every
- * Vaadin instance in a browser window. A root may either represent an entire
- * browser window (or tab) or some part of a html page where a Vaadin
- * application is embedded.
- * <p>
- * The root is the server side entry point for various client side features that
- * are not represented as components added to a layout, e.g notifications, sub
- * windows, and executing javascript in the browser.
- * </p>
- * <p>
- * When a new application instance is needed, typically because the user opens
- * the application in a browser window,
- * {@link Application#gerRoot(WrappedRequest)} is invoked to get a root. That
- * method does by default create a root according to the
- * {@value Application#ROOT_PARAMETER} parameter from web.xml.
- * </p>
- * <p>
- * After a root has been created by the application, it is initialized using
- * {@link #init(WrappedRequest)}. This method is intended to be overridden by
- * the developer to add components to the user interface and initialize
- * non-component functionality. The component hierarchy is initialized by
- * passing a {@link ComponentContainer} with the main layout of the view to
- * {@link #setContent(ComponentContainer)}.
- * </p>
- * <p>
- * If a {@link EagerInit} annotation is present on a class extending
- * <code>Root</code>, the framework will use a faster initialization method
- * which will not ensure that {@link BrowserDetails} are present in the
- * {@link WrappedRequest} passed to the init method.
- * </p>
- *
- * @see #init(WrappedRequest)
- * @see Application#getRoot(WrappedRequest)
- *
- * @since 7.0
- */
-public abstract class Root extends AbstractComponentContainer implements
- Action.Container, Action.Notifier, Vaadin6Component {
-
- /**
- * Helper class to emulate the main window from Vaadin 6 using roots. This
- * class should be used in the same way as Window used as a browser level
- * window in Vaadin 6 with {@link com.vaadin.Application.LegacyApplication}
- */
- @Deprecated
- @EagerInit
- public static class LegacyWindow extends Root {
- private String name;
-
- /**
- * Create a new legacy window
- */
- public LegacyWindow() {
- super();
- }
-
- /**
- * Creates a new legacy window with the given caption
- *
- * @param caption
- * the caption of the window
- */
- public LegacyWindow(String caption) {
- super(caption);
- }
-
- /**
- * Creates a legacy window with the given caption and content layout
- *
- * @param caption
- * @param content
- */
- public LegacyWindow(String caption, ComponentContainer content) {
- super(caption, content);
- }
-
- @Override
- protected void init(WrappedRequest request) {
- // Just empty
- }
-
- /**
- * Gets the unique name of the window. The name of the window is used to
- * uniquely identify it.
- * <p>
- * The name also determines the URL that can be used for direct access
- * to a window. All windows can be accessed through
- * {@code http://host:port/app/win} where {@code http://host:port/app}
- * is the application URL (as returned by {@link Application#getURL()}
- * and {@code win} is the window name.
- * </p>
- * <p>
- * Note! Portlets do not support direct window access through URLs.
- * </p>
- *
- * @return the Name of the Window.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the unique name of the window. The name of the window is used to
- * uniquely identify it inside the application.
- * <p>
- * The name also determines the URL that can be used for direct access
- * to a window. All windows can be accessed through
- * {@code http://host:port/app/win} where {@code http://host:port/app}
- * is the application URL (as returned by {@link Application#getURL()}
- * and {@code win} is the window name.
- * </p>
- * <p>
- * This method can only be called before the window is added to an
- * application.
- * <p>
- * Note! Portlets do not support direct window access through URLs.
- * </p>
- *
- * @param name
- * the new name for the window or null if the application
- * should automatically assign a name to it
- * @throws IllegalStateException
- * if the window is attached to an application
- */
- public void setName(String name) {
- this.name = name;
- // The name can not be changed in application
- if (getApplication() != null) {
- throw new IllegalStateException(
- "Window name can not be changed while "
- + "the window is in application");
- }
-
- }
-
- /**
- * Gets the full URL of the window. The returned URL is window specific
- * and can be used to directly refer to the window.
- * <p>
- * Note! This method can not be used for portlets.
- * </p>
- *
- * @return the URL of the window or null if the window is not attached
- * to an application
- */
- public URL getURL() {
- Application application = getApplication();
- if (application == null) {
- return null;
- }
-
- try {
- return new URL(application.getURL(), getName() + "/");
- } catch (MalformedURLException e) {
- throw new RuntimeException(
- "Internal problem getting window URL, please report");
- }
- }
-
- /**
- * Opens the given resource in this root. The contents of this Root is
- * replaced by the {@code Resource}.
- *
- * @param resource
- * the resource to show in this root
- *
- * @deprecated As of 7.0, use getPage().open instead
- */
- @Deprecated
- public void open(Resource resource) {
- getPage().open(resource);
- }
-
- /* ********************************************************************* */
-
- /**
- * Opens the given resource in a window with the given name.
- * <p>
- * The supplied {@code windowName} is used as the target name in a
- * window.open call in the client. This means that special values such
- * as "_blank", "_self", "_top", "_parent" have special meaning. An
- * empty or <code>null</code> window name is also a special case.
- * </p>
- * <p>
- * "", null and "_self" as {@code windowName} all causes the resource to
- * be opened in the current window, replacing any old contents. For
- * downloadable content you should avoid "_self" as "_self" causes the
- * client to skip rendering of any other changes as it considers them
- * irrelevant (the page will be replaced by the resource). This can
- * speed up the opening of a resource, but it might also put the client
- * side into an inconsistent state if the window content is not
- * completely replaced e.g., if the resource is downloaded instead of
- * displayed in the browser.
- * </p>
- * <p>
- * "_blank" as {@code windowName} causes the resource to always be
- * opened in a new window or tab (depends on the browser and browser
- * settings).
- * </p>
- * <p>
- * "_top" and "_parent" as {@code windowName} works as specified by the
- * HTML standard.
- * </p>
- * <p>
- * Any other {@code windowName} will open the resource in a window with
- * that name, either by opening a new window/tab in the browser or by
- * replacing the contents of an existing window with that name.
- * </p>
- *
- * @param resource
- * the resource.
- * @param windowName
- * the name of the window.
- * @deprecated As of 7.0, use getPage().open instead
- */
- @Deprecated
- public void open(Resource resource, String windowName) {
- getPage().open(resource, windowName);
- }
-
- /**
- * Opens the given resource in a window with the given size, border and
- * name. For more information on the meaning of {@code windowName}, see
- * {@link #open(Resource, String)}.
- *
- * @param resource
- * the resource.
- * @param windowName
- * the name of the window.
- * @param width
- * the width of the window in pixels
- * @param height
- * the height of the window in pixels
- * @param border
- * the border style of the window. See {@link #BORDER_NONE
- * Window.BORDER_* constants}
- * @deprecated As of 7.0, use getPage().open instead
- */
- @Deprecated
- public void open(Resource resource, String windowName, int width,
- int height, int border) {
- getPage().open(resource, windowName, width, height, border);
- }
-
- /**
- * Adds a new {@link BrowserWindowResizeListener} to this root. The
- * listener will be notified whenever the browser window within which
- * this root resides is resized.
- *
- * @param resizeListener
- * the listener to add
- *
- * @see BrowserWindowResizeListener#browserWindowResized(BrowserWindowResizeEvent)
- * @see #setResizeLazy(boolean)
- *
- * @deprecated As of 7.0, use the similarly named api in Page instead
- */
- @Deprecated
- public void addListener(BrowserWindowResizeListener resizeListener) {
- getPage().addListener(resizeListener);
- }
-
- /**
- * Removes a {@link BrowserWindowResizeListener} from this root. The
- * listener will no longer be notified when the browser window is
- * resized.
- *
- * @param resizeListener
- * the listener to remove
- * @deprecated As of 7.0, use the similarly named api in Page instead
- */
- @Deprecated
- public void removeListener(BrowserWindowResizeListener resizeListener) {
- getPage().removeListener(resizeListener);
- }
-
- /**
- * Gets the last known height of the browser window in which this root
- * resides.
- *
- * @return the browser window height in pixels
- * @deprecated As of 7.0, use the similarly named api in Page instead
- */
- @Deprecated
- public int getBrowserWindowHeight() {
- return getPage().getBrowserWindowHeight();
- }
-
- /**
- * Gets the last known width of the browser window in which this root
- * resides.
- *
- * @return the browser window width in pixels
- *
- * @deprecated As of 7.0, use the similarly named api in Page instead
- */
- @Deprecated
- public int getBrowserWindowWidth() {
- return getPage().getBrowserWindowWidth();
- }
-
- /**
- * Executes JavaScript in this window.
- *
- * <p>
- * This method allows one to inject javascript from the server to
- * client. A client implementation is not required to implement this
- * functionality, but currently all web-based clients do implement this.
- * </p>
- *
- * <p>
- * Executing javascript this way often leads to cross-browser
- * compatibility issues and regressions that are hard to resolve. Use of
- * this method should be avoided and instead it is recommended to create
- * new widgets with GWT. For more info on creating own, reusable
- * client-side widgets in Java, read the corresponding chapter in Book
- * of Vaadin.
- * </p>
- *
- * @param script
- * JavaScript snippet that will be executed.
- *
- * @deprecated as of 7.0, use JavaScript.getCurrent().execute(String)
- * instead
- */
- @Deprecated
- public void executeJavaScript(String script) {
- getPage().getJavaScript().execute(script);
- }
-
- @Override
- public void setCaption(String caption) {
- // Override to provide backwards compatibility
- getState().setCaption(caption);
- getPage().setTitle(caption);
- }
-
- }
-
- /**
- * The application to which this root belongs
- */
- private Application application;
-
- /**
- * List of windows in this root.
- */
- private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>();
-
- /**
- * The component that should be scrolled into view after the next repaint.
- * Null if nothing should be scrolled into view.
- */
- private Component scrollIntoView;
-
- /**
- * The id of this root, used to find the server side instance of the root
- * form which a request originates. A negative value indicates that the root
- * id has not yet been assigned by the Application.
- *
- * @see Application#nextRootId
- */
- private int rootId = -1;
-
- /**
- * Keeps track of the Actions added to this component, and manages the
- * painting and handling as well.
- */
- protected ActionManager actionManager;
-
- /**
- * Thread local for keeping track of the current root.
- */
- private static final ThreadLocal<Root> currentRoot = new ThreadLocal<Root>();
-
- /** Identifies the click event */
- private static final String CLICK_EVENT_ID = VRoot.CLICK_EVENT_ID;
-
- private ConnectorTracker connectorTracker = new ConnectorTracker(this);
-
- private Page page = new Page(this);
-
- private RootServerRpc rpc = new RootServerRpc() {
- @Override
- public void click(MouseEventDetails mouseDetails) {
- fireEvent(new ClickEvent(Root.this, mouseDetails));
- }
- };
-
- /**
- * Creates a new empty root without a caption. This root will have a
- * {@link VerticalLayout} with margins enabled as its content.
- */
- public Root() {
- this((ComponentContainer) null);
- }
-
- /**
- * Creates a new root with the given component container as its content.
- *
- * @param content
- * the content container to use as this roots content.
- *
- * @see #setContent(ComponentContainer)
- */
- public Root(ComponentContainer content) {
- registerRpc(rpc);
- setSizeFull();
- setContent(content);
- }
-
- /**
- * Creates a new empty root with the given caption. This root will have a
- * {@link VerticalLayout} with margins enabled as its content.
- *
- * @param caption
- * the caption of the root, used as the page title if there's
- * nothing but the application on the web page
- *
- * @see #setCaption(String)
- */
- public Root(String caption) {
- this((ComponentContainer) null);
- setCaption(caption);
- }
-
- /**
- * Creates a new root with the given caption and content.
- *
- * @param caption
- * the caption of the root, used as the page title if there's
- * nothing but the application on the web page
- * @param content
- * the content container to use as this roots content.
- *
- * @see #setContent(ComponentContainer)
- * @see #setCaption(String)
- */
- public Root(String caption, ComponentContainer content) {
- this(content);
- setCaption(caption);
- }
-
- @Override
- public RootState getState() {
- return (RootState) super.getState();
- }
-
- @Override
- public Class<? extends RootState> getStateType() {
- // This is a workaround for a problem with creating the correct state
- // object during build
- return RootState.class;
- }
-
- /**
- * Overridden to return a value instead of referring to the parent.
- *
- * @return this root
- *
- * @see com.vaadin.ui.AbstractComponent#getRoot()
- */
- @Override
- public Root getRoot() {
- return this;
- }
-
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Application getApplication() {
- return application;
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- page.paintContent(target);
-
- if (scrollIntoView != null) {
- target.addAttribute("scrollTo", scrollIntoView);
- scrollIntoView = null;
- }
-
- if (pendingFocus != null) {
- // ensure focused component is still attached to this main window
- if (pendingFocus.getRoot() == this
- || (pendingFocus.getRoot() != null && pendingFocus
- .getRoot().getParent() == this)) {
- target.addAttribute("focused", pendingFocus);
- }
- pendingFocus = null;
- }
-
- if (actionManager != null) {
- actionManager.paintActions(null, target);
- }
-
- if (isResizeLazy()) {
- target.addAttribute(VRoot.RESIZE_LAZY, true);
- }
- }
-
- /**
- * Fire a click event to all click listeners.
- *
- * @param object
- * The raw "value" of the variable change from the client side.
- */
- private void fireClick(Map<String, Object> parameters) {
- MouseEventDetails mouseDetails = MouseEventDetails
- .deSerialize((String) parameters.get("mouseDetails"));
- fireEvent(new ClickEvent(this, mouseDetails));
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey(CLICK_EVENT_ID)) {
- fireClick((Map<String, Object>) variables.get(CLICK_EVENT_ID));
- }
-
- // Actions
- if (actionManager != null) {
- actionManager.handleActions(variables, this);
- }
-
- if (variables.containsKey(VRoot.FRAGMENT_VARIABLE)) {
- String fragment = (String) variables.get(VRoot.FRAGMENT_VARIABLE);
- getPage().setFragment(fragment, true);
- }
-
- if (variables.containsKey("height") || variables.containsKey("width")) {
- getPage().setBrowserWindowSize((Integer) variables.get("width"),
- (Integer) variables.get("height"));
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
- @Override
- public Iterator<Component> getComponentIterator() {
- // TODO could directly create some kind of combined iterator instead of
- // creating a new ArrayList
- ArrayList<Component> components = new ArrayList<Component>();
-
- if (getContent() != null) {
- components.add(getContent());
- }
-
- components.addAll(windows);
-
- return components.iterator();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentCount()
- */
- @Override
- public int getComponentCount() {
- return windows.size() + (getContent() == null ? 0 : 1);
- }
-
- /**
- * Sets the application to which this root is assigned. It is not legal to
- * change the application once it has been set nor to set a
- * <code>null</code> application.
- * <p>
- * This method is mainly intended for internal use by the framework.
- * </p>
- *
- * @param application
- * the application to set
- *
- * @throws IllegalStateException
- * if the application has already been set
- *
- * @see #getApplication()
- */
- public void setApplication(Application application) {
- if ((application == null) == (this.application == null)) {
- throw new IllegalStateException("Application has already been set");
- } else {
- this.application = application;
- }
-
- if (application != null) {
- attach();
- } else {
- detach();
- }
- }
-
- /**
- * Sets the id of this root within its application. The root id is used to
- * route requests to the right root.
- * <p>
- * This method is mainly intended for internal use by the framework.
- * </p>
- *
- * @param rootId
- * the id of this root
- *
- * @throws IllegalStateException
- * if the root id has already been set
- *
- * @see #getRootId()
- */
- public void setRootId(int rootId) {
- if (this.rootId != -1) {
- throw new IllegalStateException("Root id has already been defined");
- }
- this.rootId = rootId;
- }
-
- /**
- * Gets the id of the root, used to identify this root within its
- * application when processing requests. The root id should be present in
- * every request to the server that originates from this root.
- * {@link Application#getRootForRequest(WrappedRequest)} uses this id to
- * find the route to which the request belongs.
- *
- * @return
- */
- public int getRootId() {
- return rootId;
- }
-
- /**
- * Adds a window as a subwindow inside this root. To open a new browser
- * window or tab, you should instead use {@link open(Resource)} with an url
- * pointing to this application and ensure
- * {@link Application#getRoot(WrappedRequest)} returns an appropriate root
- * for the request.
- *
- * @param window
- * @throws IllegalArgumentException
- * if the window is already added to an application
- * @throws NullPointerException
- * if the given <code>Window</code> is <code>null</code>.
- */
- public void addWindow(Window window) throws IllegalArgumentException,
- NullPointerException {
-
- if (window == null) {
- throw new NullPointerException("Argument must not be null");
- }
-
- if (window.getApplication() != null) {
- throw new IllegalArgumentException(
- "Window is already attached to an application.");
- }
-
- attachWindow(window);
- }
-
- /**
- * Helper method to attach a window.
- *
- * @param w
- * the window to add
- */
- private void attachWindow(Window w) {
- windows.add(w);
- w.setParent(this);
- requestRepaint();
- }
-
- /**
- * Remove the given subwindow from this root.
- *
- * Since Vaadin 6.5, {@link CloseListener}s are called also when explicitly
- * removing a window by calling this method.
- *
- * Since Vaadin 6.5, returns a boolean indicating if the window was removed
- * or not.
- *
- * @param window
- * Window to be removed.
- * @return true if the subwindow was removed, false otherwise
- */
- public boolean removeWindow(Window window) {
- if (!windows.remove(window)) {
- // Window window is not a subwindow of this root.
- return false;
- }
- window.setParent(null);
- window.fireClose();
- requestRepaint();
-
- return true;
- }
-
- /**
- * Gets all the windows added to this root.
- *
- * @return an unmodifiable collection of windows
- */
- public Collection<Window> getWindows() {
- return Collections.unmodifiableCollection(windows);
- }
-
- @Override
- public void focus() {
- super.focus();
- }
-
- /**
- * Component that should be focused after the next repaint. Null if no focus
- * change should take place.
- */
- private Focusable pendingFocus;
-
- private boolean resizeLazy = false;
-
- /**
- * This method is used by Component.Focusable objects to request focus to
- * themselves. Focus renders must be handled at window level (instead of
- * Component.Focusable) due we want the last focused component to be focused
- * in client too. Not the one that is rendered last (the case we'd get if
- * implemented in Focusable only).
- *
- * To focus component from Vaadin application, use Focusable.focus(). See
- * {@link Focusable}.
- *
- * @param focusable
- * to be focused on next paint
- */
- public void setFocusedComponent(Focusable focusable) {
- pendingFocus = focusable;
- requestRepaint();
- }
-
- /**
- * Scrolls any component between the component and root to a suitable
- * position so the component is visible to the user. The given component
- * must belong to this root.
- *
- * @param component
- * the component to be scrolled into view
- * @throws IllegalArgumentException
- * if {@code component} does not belong to this root
- */
- public void scrollIntoView(Component component)
- throws IllegalArgumentException {
- if (component.getRoot() != this) {
- throw new IllegalArgumentException(
- "The component where to scroll must belong to this root.");
- }
- scrollIntoView = component;
- requestRepaint();
- }
-
- /**
- * Gets the content of this root. The content is a component container that
- * serves as the outermost item of the visual contents of this root.
- *
- * @return a component container to use as content
- *
- * @see #setContent(ComponentContainer)
- * @see #createDefaultLayout()
- */
- public ComponentContainer getContent() {
- return (ComponentContainer) getState().getContent();
- }
-
- /**
- * Helper method to create the default content layout that is used if no
- * content has not been explicitly defined.
- *
- * @return a newly created layout
- */
- private static VerticalLayout createDefaultLayout() {
- VerticalLayout layout = new VerticalLayout();
- layout.setMargin(true);
- return layout;
- }
-
- /**
- * Sets the content of this root. The content is a component container that
- * serves as the outermost item of the visual contents of this root. If no
- * content has been set, a {@link VerticalLayout} with margins enabled will
- * be used by default - see {@link #createDefaultLayout()}. The content can
- * also be set in a constructor.
- *
- * @return a component container to use as content
- *
- * @see #Root(ComponentContainer)
- * @see #createDefaultLayout()
- */
- public void setContent(ComponentContainer content) {
- if (content == null) {
- content = createDefaultLayout();
- }
-
- if (getState().getContent() != null) {
- super.removeComponent((Component) getState().getContent());
- }
- getState().setContent(content);
- if (content != null) {
- super.addComponent(content);
- }
-
- requestRepaint();
- }
-
- /**
- * Adds a component to this root. The component is not added directly to the
- * root, but instead to the content container ({@link #getContent()}).
- *
- * @param component
- * the component to add to this root
- *
- * @see #getContent()
- */
- @Override
- public void addComponent(Component component) {
- getContent().addComponent(component);
- }
-
- /**
- * This implementation removes the component from the content container (
- * {@link #getContent()}) instead of from the actual root.
- */
- @Override
- public void removeComponent(Component component) {
- getContent().removeComponent(component);
- }
-
- /**
- * This implementation removes the components from the content container (
- * {@link #getContent()}) instead of from the actual root.
- */
- @Override
- public void removeAllComponents() {
- getContent().removeAllComponents();
- }
-
- /**
- * Internal initialization method, should not be overridden. This method is
- * not declared as final because that would break compatibility with e.g.
- * CDI.
- *
- * @param request
- * the initialization request
- */
- public void doInit(WrappedRequest request) {
- getPage().init(request);
-
- // Call the init overridden by the application developer
- init(request);
- }
-
- /**
- * Initializes this root. This method is intended to be overridden by
- * subclasses to build the view and configure non-component functionality.
- * Performing the initialization in a constructor is not suggested as the
- * state of the root is not properly set up when the constructor is invoked.
- * <p>
- * The {@link WrappedRequest} can be used to get information about the
- * request that caused this root to be created. By default, the
- * {@link BrowserDetails} will be available in the request. If the browser
- * details are not required, loading the application in the browser can take
- * some shortcuts giving a faster initial rendering. This can be indicated
- * by adding the {@link EagerInit} annotation to the Root class.
- * </p>
- *
- * @param request
- * the wrapped request that caused this root to be created
- */
- protected abstract void init(WrappedRequest request);
-
- /**
- * Sets the thread local for the current root. This method is used by the
- * framework to set the current application whenever a new request is
- * processed and it is cleared when the request has been processed.
- * <p>
- * The application developer can also use this method to define the current
- * root outside the normal request handling, e.g. when initiating custom
- * background threads.
- * </p>
- *
- * @param root
- * the root to register as the current root
- *
- * @see #getCurrent()
- * @see ThreadLocal
- */
- public static void setCurrent(Root root) {
- currentRoot.set(root);
- }
-
- /**
- * Gets the currently used root. The current root is automatically defined
- * when processing requests to the server. In other cases, (e.g. from
- * background threads), the current root is not automatically defined.
- *
- * @return the current root instance if available, otherwise
- * <code>null</code>
- *
- * @see #setCurrent(Root)
- */
- public static Root getCurrent() {
- return currentRoot.get();
- }
-
- public void setScrollTop(int scrollTop) {
- throw new RuntimeException("Not yet implemented");
- }
-
- @Override
- protected ActionManager getActionManager() {
- if (actionManager == null) {
- actionManager = new ActionManager(this);
- }
- return actionManager;
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void addAction(
- T action) {
- getActionManager().addAction(action);
- }
-
- @Override
- public <T extends Action & com.vaadin.event.Action.Listener> void removeAction(
- T action) {
- if (actionManager != null) {
- actionManager.removeAction(action);
- }
- }
-
- @Override
- public void addActionHandler(Handler actionHandler) {
- getActionManager().addActionHandler(actionHandler);
- }
-
- @Override
- public void removeActionHandler(Handler actionHandler) {
- if (actionManager != null) {
- actionManager.removeActionHandler(actionHandler);
- }
- }
-
- /**
- * Should resize operations be lazy, i.e. should there be a delay before
- * layout sizes are recalculated. Speeds up resize operations in slow UIs
- * with the penalty of slightly decreased usability.
- * <p>
- * Default value: <code>false</code>
- *
- * @param resizeLazy
- * true to use a delay before recalculating sizes, false to
- * calculate immediately.
- */
- public void setResizeLazy(boolean resizeLazy) {
- this.resizeLazy = resizeLazy;
- requestRepaint();
- }
-
- /**
- * Checks whether lazy resize is enabled.
- *
- * @return <code>true</code> if lazy resize is enabled, <code>false</code>
- * if lazy resize is not enabled
- */
- public boolean isResizeLazy() {
- return resizeLazy;
- }
-
- /**
- * Add a click listener to the Root. The listener is called whenever the
- * user clicks inside the Root. Also when the click targets a component
- * inside the Root, provided the targeted component does not prevent the
- * click event from propagating.
- *
- * Use {@link #removeListener(ClickListener)} to remove the listener.
- *
- * @param listener
- * The listener to add
- */
- public void addListener(ClickListener listener) {
- addListener(CLICK_EVENT_ID, ClickEvent.class, listener,
- ClickListener.clickMethod);
- }
-
- /**
- * Remove a click listener from the Root. The listener should earlier have
- * been added using {@link #addListener(ClickListener)}.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(ClickListener listener) {
- removeListener(CLICK_EVENT_ID, ClickEvent.class, listener);
- }
-
- @Override
- public boolean isConnectorEnabled() {
- // TODO How can a Root be invisible? What does it mean?
- return isVisible() && isEnabled();
- }
-
- public ConnectorTracker getConnectorTracker() {
- return connectorTracker;
- }
-
- public Page getPage() {
- return page;
- }
-
- /**
- * Setting the caption of a Root is not supported. To set the title of the
- * HTML page, use Page.setTitle
- *
- * @deprecated as of 7.0.0, use {@link Page#setTitle(String)}
- */
- @Override
- @Deprecated
- public void setCaption(String caption) {
- throw new IllegalStateException(
- "You can not set the title of a Root. To set the title of the HTML page, use Page.setTitle");
- }
-
- /**
- * Shows a notification message on the middle of the root. The message
- * automatically disappears ("humanized message").
- *
- * Care should be taken to to avoid XSS vulnerabilities as the caption is
- * rendered as html.
- *
- * @see #showNotification(Notification)
- * @see Notification
- *
- * @param caption
- * The message
- *
- * @deprecated As of 7.0, use Notification.show instead but be aware that
- * Notification.show does not allow HTML.
- */
- @Deprecated
- public void showNotification(String caption) {
- Notification notification = new Notification(caption);
- notification.setHtmlContentAllowed(true);// Backwards compatibility
- getPage().showNotification(notification);
- }
-
- /**
- * Shows a notification message the root. The position and behavior of the
- * message depends on the type, which is one of the basic types defined in
- * {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE.
- *
- * Care should be taken to to avoid XSS vulnerabilities as the caption is
- * rendered as html.
- *
- * @see #showNotification(Notification)
- * @see Notification
- *
- * @param caption
- * The message
- * @param type
- * The message type
- *
- * @deprecated As of 7.0, use Notification.show instead but be aware that
- * Notification.show does not allow HTML.
- */
- @Deprecated
- public void showNotification(String caption, int type) {
- Notification notification = new Notification(caption, type);
- notification.setHtmlContentAllowed(true);// Backwards compatibility
- getPage().showNotification(notification);
- }
-
- /**
- * Shows a notification consisting of a bigger caption and a smaller
- * description on the middle of the root. The message automatically
- * disappears ("humanized message").
- *
- * Care should be taken to to avoid XSS vulnerabilities as the caption and
- * description are rendered as html.
- *
- * @see #showNotification(Notification)
- * @see Notification
- *
- * @param caption
- * The caption of the message
- * @param description
- * The message description
- *
- * @deprecated As of 7.0, use new Notification(...).show(Page) instead but
- * be aware that HTML by default not allowed.
- */
- @Deprecated
- public void showNotification(String caption, String description) {
- Notification notification = new Notification(caption, description);
- notification.setHtmlContentAllowed(true);// Backwards compatibility
- getPage().showNotification(notification);
- }
-
- /**
- * Shows a notification consisting of a bigger caption and a smaller
- * description. The position and behavior of the message depends on the
- * type, which is one of the basic types defined in {@link Notification} ,
- * for instance Notification.TYPE_WARNING_MESSAGE.
- *
- * Care should be taken to to avoid XSS vulnerabilities as the caption and
- * description are rendered as html.
- *
- * @see #showNotification(Notification)
- * @see Notification
- *
- * @param caption
- * The caption of the message
- * @param description
- * The message description
- * @param type
- * The message type
- *
- * @deprecated As of 7.0, use new Notification(...).show(Page) instead but
- * be aware that HTML by default not allowed.
- */
- @Deprecated
- public void showNotification(String caption, String description, int type) {
- Notification notification = new Notification(caption, description, type);
- notification.setHtmlContentAllowed(true);// Backwards compatibility
- getPage().showNotification(notification);
- }
-
- /**
- * Shows a notification consisting of a bigger caption and a smaller
- * description. The position and behavior of the message depends on the
- * type, which is one of the basic types defined in {@link Notification} ,
- * for instance Notification.TYPE_WARNING_MESSAGE.
- *
- * Care should be taken to avoid XSS vulnerabilities if html content is
- * allowed.
- *
- * @see #showNotification(Notification)
- * @see Notification
- *
- * @param caption
- * The message caption
- * @param description
- * The message description
- * @param type
- * The type of message
- * @param htmlContentAllowed
- * Whether html in the caption and description should be
- * displayed as html or as plain text
- *
- * @deprecated As of 7.0, use new Notification(...).show(Page).
- */
- @Deprecated
- public void showNotification(String caption, String description, int type,
- boolean htmlContentAllowed) {
- getPage()
- .showNotification(
- new Notification(caption, description, type,
- htmlContentAllowed));
- }
-
- /**
- * Shows a notification message.
- *
- * @see Notification
- * @see #showNotification(String)
- * @see #showNotification(String, int)
- * @see #showNotification(String, String)
- * @see #showNotification(String, String, int)
- *
- * @param notification
- * The notification message to show
- *
- * @deprecated As of 7.0, use Notification.show instead
- */
- @Deprecated
- public void showNotification(Notification notification) {
- getPage().showNotification(notification);
- }
-
-}
diff --git a/src/com/vaadin/ui/Select.java b/src/com/vaadin/ui/Select.java
deleted file mode 100644
index f60935c64b..0000000000
--- a/src/com/vaadin/ui/Select.java
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.util.filter.SimpleStringFilter;
-import com.vaadin.event.FieldEvents;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-
-/**
- * <p>
- * A class representing a selection of items the user has selected in a UI. The
- * set of choices is presented as a set of {@link com.vaadin.data.Item}s in a
- * {@link com.vaadin.data.Container}.
- * </p>
- *
- * <p>
- * A <code>Select</code> component may be in single- or multiselect mode.
- * Multiselect mode means that more than one item can be selected
- * simultaneously.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Select extends AbstractSelect implements AbstractSelect.Filtering,
- FieldEvents.BlurNotifier, FieldEvents.FocusNotifier {
-
- /**
- * Holds value of property pageLength. 0 disables paging.
- */
- protected int pageLength = 10;
-
- private int columns = 0;
-
- // Current page when the user is 'paging' trough options
- private int currentPage = -1;
-
- private int filteringMode = FILTERINGMODE_STARTSWITH;
-
- private String filterstring;
- private String prevfilterstring;
-
- /**
- * Number of options that pass the filter, excluding the null item if any.
- */
- private int filteredSize;
-
- /**
- * Cache of filtered options, used only by the in-memory filtering system.
- */
- private List<Object> filteredOptions;
-
- /**
- * Flag to indicate that request repaint is called by filter request only
- */
- private boolean optionRequest;
-
- /**
- * True if the container is being filtered temporarily and item set change
- * notifications should be suppressed.
- */
- private boolean filteringContainer;
-
- /**
- * Flag to indicate whether to scroll the selected item visible (select the
- * page on which it is) when opening the popup or not. Only applies to
- * single select mode.
- *
- * This requires finding the index of the item, which can be expensive in
- * many large lazy loading containers.
- */
- private boolean scrollToSelectedItem = true;
-
- /* Constructors */
-
- /* Component methods */
-
- public Select() {
- super();
- }
-
- public Select(String caption, Collection<?> options) {
- super(caption, options);
- }
-
- public Select(String caption, Container dataSource) {
- super(caption, dataSource);
- }
-
- public Select(String caption) {
- super(caption);
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the Paint Event.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (isMultiSelect()) {
- // background compatibility hack. This object shouldn't be used for
- // multiselect lists anymore (ListSelect instead). This fallbacks to
- // a simpler paint method in super class.
- super.paintContent(target);
- // Fix for #4553
- target.addAttribute("type", "legacy-multi");
- return;
- }
-
- // clear caption change listeners
- getCaptionChangeListener().clear();
-
- // The tab ordering number
- if (getTabIndex() != 0) {
- target.addAttribute("tabindex", getTabIndex());
- }
-
- // If the field is modified, but not committed, set modified attribute
- if (isModified()) {
- target.addAttribute("modified", true);
- }
-
- if (isNewItemsAllowed()) {
- target.addAttribute("allownewitem", true);
- }
-
- boolean needNullSelectOption = false;
- if (isNullSelectionAllowed()) {
- target.addAttribute("nullselect", true);
- needNullSelectOption = (getNullSelectionItemId() == null);
- if (!needNullSelectOption) {
- target.addAttribute("nullselectitem", true);
- }
- }
-
- // Constructs selected keys array
- String[] selectedKeys;
- if (isMultiSelect()) {
- selectedKeys = new String[((Set<?>) getValue()).size()];
- } else {
- selectedKeys = new String[(getValue() == null
- && getNullSelectionItemId() == null ? 0 : 1)];
- }
-
- target.addAttribute("pagelength", pageLength);
-
- target.addAttribute("filteringmode", getFilteringMode());
-
- // Paints the options and create array of selected id keys
- int keyIndex = 0;
-
- target.startTag("options");
-
- if (currentPage < 0) {
- optionRequest = false;
- currentPage = 0;
- filterstring = "";
- }
-
- boolean nullFilteredOut = filterstring != null
- && !"".equals(filterstring)
- && filteringMode != FILTERINGMODE_OFF;
- // null option is needed and not filtered out, even if not on current
- // page
- boolean nullOptionVisible = needNullSelectOption && !nullFilteredOut;
-
- // first try if using container filters is possible
- List<?> options = getOptionsWithFilter(nullOptionVisible);
- if (null == options) {
- // not able to use container filters, perform explicit in-memory
- // filtering
- options = getFilteredOptions();
- filteredSize = options.size();
- options = sanitetizeList(options, nullOptionVisible);
- }
-
- final boolean paintNullSelection = needNullSelectOption
- && currentPage == 0 && !nullFilteredOut;
-
- if (paintNullSelection) {
- target.startTag("so");
- target.addAttribute("caption", "");
- target.addAttribute("key", "");
- target.endTag("so");
- }
-
- final Iterator<?> i = options.iterator();
- // Paints the available selection options from data source
-
- while (i.hasNext()) {
-
- final Object id = i.next();
-
- if (!isNullSelectionAllowed() && id != null
- && id.equals(getNullSelectionItemId()) && !isSelected(id)) {
- continue;
- }
-
- // Gets the option attribute values
- final String key = itemIdMapper.key(id);
- final String caption = getItemCaption(id);
- final Resource icon = getItemIcon(id);
- getCaptionChangeListener().addNotifierForItem(id);
-
- // Paints the option
- target.startTag("so");
- if (icon != null) {
- target.addAttribute("icon", icon);
- }
- target.addAttribute("caption", caption);
- if (id != null && id.equals(getNullSelectionItemId())) {
- target.addAttribute("nullselection", true);
- }
- target.addAttribute("key", key);
- if (isSelected(id) && keyIndex < selectedKeys.length) {
- target.addAttribute("selected", true);
- selectedKeys[keyIndex++] = key;
- }
- target.endTag("so");
- }
- target.endTag("options");
-
- target.addAttribute("totalitems", size()
- + (needNullSelectOption ? 1 : 0));
- if (filteredSize > 0 || nullOptionVisible) {
- target.addAttribute("totalMatches", filteredSize
- + (nullOptionVisible ? 1 : 0));
- }
-
- // Paint variables
- target.addVariable(this, "selected", selectedKeys);
- if (isNewItemsAllowed()) {
- target.addVariable(this, "newitem", "");
- }
-
- target.addVariable(this, "filter", filterstring);
- target.addVariable(this, "page", currentPage);
-
- currentPage = -1; // current page is always set by client
-
- optionRequest = true;
- }
-
- /**
- * Returns the filtered options for the current page using a container
- * filter.
- *
- * As a size effect, {@link #filteredSize} is set to the total number of
- * items passing the filter.
- *
- * The current container must be {@link Filterable} and {@link Indexed}, and
- * the filtering mode must be suitable for container filtering (tested with
- * {@link #canUseContainerFilter()}).
- *
- * Use {@link #getFilteredOptions()} and
- * {@link #sanitetizeList(List, boolean)} if this is not the case.
- *
- * @param needNullSelectOption
- * @return filtered list of options (may be empty) or null if cannot use
- * container filters
- */
- protected List<?> getOptionsWithFilter(boolean needNullSelectOption) {
- Container container = getContainerDataSource();
-
- if (pageLength == 0) {
- // no paging: return all items
- filteredSize = container.size();
- return new ArrayList<Object>(container.getItemIds());
- }
-
- if (!(container instanceof Filterable)
- || !(container instanceof Indexed)
- || getItemCaptionMode() != ITEM_CAPTION_MODE_PROPERTY) {
- return null;
- }
-
- Filterable filterable = (Filterable) container;
-
- Filter filter = buildFilter(filterstring, filteringMode);
-
- // adding and removing filters leads to extraneous item set
- // change events from the underlying container, but the ComboBox does
- // not process or propagate them based on the flag filteringContainer
- if (filter != null) {
- filteringContainer = true;
- filterable.addContainerFilter(filter);
- }
-
- Indexed indexed = (Indexed) container;
-
- int indexToEnsureInView = -1;
-
- // if not an option request (item list when user changes page), go
- // to page with the selected item after filtering if accepted by
- // filter
- Object selection = getValue();
- if (isScrollToSelectedItem() && !optionRequest && !isMultiSelect()
- && selection != null) {
- // ensure proper page
- indexToEnsureInView = indexed.indexOfId(selection);
- }
-
- filteredSize = container.size();
- currentPage = adjustCurrentPage(currentPage, needNullSelectOption,
- indexToEnsureInView, filteredSize);
- int first = getFirstItemIndexOnCurrentPage(needNullSelectOption,
- filteredSize);
- int last = getLastItemIndexOnCurrentPage(needNullSelectOption,
- filteredSize, first);
-
- List<Object> options = new ArrayList<Object>();
- for (int i = first; i <= last && i < filteredSize; ++i) {
- options.add(indexed.getIdByIndex(i));
- }
-
- // to the outside, filtering should not be visible
- if (filter != null) {
- filterable.removeContainerFilter(filter);
- filteringContainer = false;
- }
-
- return options;
- }
-
- /**
- * Constructs a filter instance to use when using a Filterable container in
- * the <code>ITEM_CAPTION_MODE_PROPERTY</code> mode.
- *
- * Note that the client side implementation expects the filter string to
- * apply to the item caption string it sees, so changing the behavior of
- * this method can cause problems.
- *
- * @param filterString
- * @param filteringMode
- * @return
- */
- protected Filter buildFilter(String filterString, int filteringMode) {
- Filter filter = null;
-
- if (null != filterString && !"".equals(filterString)) {
- switch (filteringMode) {
- case FILTERINGMODE_OFF:
- break;
- case FILTERINGMODE_STARTSWITH:
- filter = new SimpleStringFilter(getItemCaptionPropertyId(),
- filterString, true, true);
- break;
- case FILTERINGMODE_CONTAINS:
- filter = new SimpleStringFilter(getItemCaptionPropertyId(),
- filterString, true, false);
- break;
- }
- }
- return filter;
- }
-
- @Override
- public void containerItemSetChange(Container.ItemSetChangeEvent event) {
- if (!filteringContainer) {
- super.containerItemSetChange(event);
- }
- }
-
- /**
- * Makes correct sublist of given list of options.
- *
- * If paint is not an option request (affected by page or filter change),
- * page will be the one where possible selection exists.
- *
- * Detects proper first and last item in list to return right page of
- * options. Also, if the current page is beyond the end of the list, it will
- * be adjusted.
- *
- * @param options
- * @param needNullSelectOption
- * flag to indicate if nullselect option needs to be taken into
- * consideration
- */
- private List<?> sanitetizeList(List<?> options, boolean needNullSelectOption) {
-
- if (pageLength != 0 && options.size() > pageLength) {
-
- int indexToEnsureInView = -1;
-
- // if not an option request (item list when user changes page), go
- // to page with the selected item after filtering if accepted by
- // filter
- Object selection = getValue();
- if (isScrollToSelectedItem() && !optionRequest && !isMultiSelect()
- && selection != null) {
- // ensure proper page
- indexToEnsureInView = options.indexOf(selection);
- }
-
- int size = options.size();
- currentPage = adjustCurrentPage(currentPage, needNullSelectOption,
- indexToEnsureInView, size);
- int first = getFirstItemIndexOnCurrentPage(needNullSelectOption,
- size);
- int last = getLastItemIndexOnCurrentPage(needNullSelectOption,
- size, first);
- return options.subList(first, last + 1);
- } else {
- return options;
- }
- }
-
- /**
- * Returns the index of the first item on the current page. The index is to
- * the underlying (possibly filtered) contents. The null item, if any, does
- * not have an index but takes up a slot on the first page.
- *
- * @param needNullSelectOption
- * true if a null option should be shown before any other options
- * (takes up the first slot on the first page, not counted in
- * index)
- * @param size
- * number of items after filtering (not including the null item,
- * if any)
- * @return first item to show on the UI (index to the filtered list of
- * options, not taking the null item into consideration if any)
- */
- private int getFirstItemIndexOnCurrentPage(boolean needNullSelectOption,
- int size) {
- // Not all options are visible, find out which ones are on the
- // current "page".
- int first = currentPage * pageLength;
- if (needNullSelectOption && currentPage > 0) {
- first--;
- }
- return first;
- }
-
- /**
- * Returns the index of the last item on the current page. The index is to
- * the underlying (possibly filtered) contents. If needNullSelectOption is
- * true, the null item takes up the first slot on the first page,
- * effectively reducing the first page size by one.
- *
- * @param needNullSelectOption
- * true if a null option should be shown before any other options
- * (takes up the first slot on the first page, not counted in
- * index)
- * @param size
- * number of items after filtering (not including the null item,
- * if any)
- * @param first
- * index in the filtered view of the first item of the page
- * @return index in the filtered view of the last item on the page
- */
- private int getLastItemIndexOnCurrentPage(boolean needNullSelectOption,
- int size, int first) {
- // page length usable for non-null items
- int effectivePageLength = pageLength
- - (needNullSelectOption && (currentPage == 0) ? 1 : 0);
- return Math.min(size - 1, first + effectivePageLength - 1);
- }
-
- /**
- * Adjusts the index of the current page if necessary: make sure the current
- * page is not after the end of the contents, and optionally go to the page
- * containg a specific item. There are no side effects but the adjusted page
- * index is returned.
- *
- * @param page
- * page number to use as the starting point
- * @param needNullSelectOption
- * true if a null option should be shown before any other options
- * (takes up the first slot on the first page, not counted in
- * index)
- * @param indexToEnsureInView
- * index of an item that should be included on the page (in the
- * data set, not counting the null item if any), -1 for none
- * @param size
- * number of items after filtering (not including the null item,
- * if any)
- */
- private int adjustCurrentPage(int page, boolean needNullSelectOption,
- int indexToEnsureInView, int size) {
- if (indexToEnsureInView != -1) {
- int newPage = (indexToEnsureInView + (needNullSelectOption ? 1 : 0))
- / pageLength;
- page = newPage;
- }
- // adjust the current page if beyond the end of the list
- if (page * pageLength > size) {
- page = (size + (needNullSelectOption ? 1 : 0)) / pageLength;
- }
- return page;
- }
-
- /**
- * Filters the options in memory and returns the full filtered list.
- *
- * This can be less efficient than using container filters, so use
- * {@link #getOptionsWithFilter(boolean)} if possible (filterable container
- * and suitable item caption mode etc.).
- *
- * @return
- */
- protected List<?> getFilteredOptions() {
- if (null == filterstring || "".equals(filterstring)
- || FILTERINGMODE_OFF == filteringMode) {
- prevfilterstring = null;
- filteredOptions = new LinkedList<Object>(getItemIds());
- return filteredOptions;
- }
-
- if (filterstring.equals(prevfilterstring)) {
- return filteredOptions;
- }
-
- Collection<?> items;
- if (prevfilterstring != null
- && filterstring.startsWith(prevfilterstring)) {
- items = filteredOptions;
- } else {
- items = getItemIds();
- }
- prevfilterstring = filterstring;
-
- filteredOptions = new LinkedList<Object>();
- for (final Iterator<?> it = items.iterator(); it.hasNext();) {
- final Object itemId = it.next();
- String caption = getItemCaption(itemId);
- if (caption == null || caption.equals("")) {
- continue;
- } else {
- caption = caption.toLowerCase();
- }
- switch (filteringMode) {
- case FILTERINGMODE_CONTAINS:
- if (caption.indexOf(filterstring) > -1) {
- filteredOptions.add(itemId);
- }
- break;
- case FILTERINGMODE_STARTSWITH:
- default:
- if (caption.startsWith(filterstring)) {
- filteredOptions.add(itemId);
- }
- break;
- }
- }
-
- return filteredOptions;
- }
-
- /**
- * Invoked when the value of a variable has changed.
- *
- * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- // Not calling super.changeVariables due the history of select
- // component hierarchy
-
- // Selection change
- if (variables.containsKey("selected")) {
- final String[] ka = (String[]) variables.get("selected");
-
- if (isMultiSelect()) {
- // Multiselect mode
-
- // TODO Optimize by adding repaintNotNeeded whan applicaple
-
- // Converts the key-array to id-set
- final LinkedList<Object> s = new LinkedList<Object>();
- for (int i = 0; i < ka.length; i++) {
- final Object id = itemIdMapper.get(ka[i]);
- if (id != null && containsId(id)) {
- s.add(id);
- }
- }
-
- // Limits the deselection to the set of visible items
- // (non-visible items can not be deselected)
- final Collection<?> visible = getVisibleItemIds();
- if (visible != null) {
- @SuppressWarnings("unchecked")
- Set<Object> newsel = (Set<Object>) getValue();
- if (newsel == null) {
- newsel = new HashSet<Object>();
- } else {
- newsel = new HashSet<Object>(newsel);
- }
- newsel.removeAll(visible);
- newsel.addAll(s);
- setValue(newsel, true);
- }
- } else {
- // Single select mode
- if (ka.length == 0) {
-
- // Allows deselection only if the deselected item is visible
- final Object current = getValue();
- final Collection<?> visible = getVisibleItemIds();
- if (visible != null && visible.contains(current)) {
- setValue(null, true);
- }
- } else {
- final Object id = itemIdMapper.get(ka[0]);
- if (id != null && id.equals(getNullSelectionItemId())) {
- setValue(null, true);
- } else {
- setValue(id, true);
- }
- }
- }
- }
-
- String newFilter;
- if ((newFilter = (String) variables.get("filter")) != null) {
- // this is a filter request
- currentPage = ((Integer) variables.get("page")).intValue();
- filterstring = newFilter;
- if (filterstring != null) {
- filterstring = filterstring.toLowerCase();
- }
- optionRepaint();
- } else if (isNewItemsAllowed()) {
- // New option entered (and it is allowed)
- final String newitem = (String) variables.get("newitem");
- if (newitem != null && newitem.length() > 0) {
- getNewItemHandler().addNewItem(newitem);
- // rebuild list
- filterstring = null;
- prevfilterstring = null;
- }
- }
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
-
- }
-
- @Override
- public void requestRepaint() {
- super.requestRepaint();
- optionRequest = false;
- prevfilterstring = filterstring;
- filterstring = null;
- }
-
- private void optionRepaint() {
- super.requestRepaint();
- }
-
- @Override
- public void setFilteringMode(int filteringMode) {
- this.filteringMode = filteringMode;
- }
-
- @Override
- public int getFilteringMode() {
- return filteringMode;
- }
-
- /**
- * Note, one should use more generic setWidth(String) method instead of
- * this. This now days actually converts columns to width with em css unit.
- *
- * Sets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- *
- * @deprecated
- *
- * @param columns
- * the number of columns to set.
- */
- @Deprecated
- public void setColumns(int columns) {
- if (columns < 0) {
- columns = 0;
- }
- if (this.columns != columns) {
- this.columns = columns;
- setWidth(columns, Select.UNITS_EM);
- requestRepaint();
- }
- }
-
- /**
- * @deprecated see setter function
- * @return
- */
- @Deprecated
- public int getColumns() {
- return columns;
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
-
- }
-
- /**
- * @deprecated use {@link ListSelect}, {@link OptionGroup} or
- * {@link TwinColSelect} instead
- * @see com.vaadin.ui.AbstractSelect#setMultiSelect(boolean)
- * @throws UnsupportedOperationException
- * if trying to activate multiselect mode
- */
- @Deprecated
- @Override
- public void setMultiSelect(boolean multiSelect) {
- if (multiSelect) {
- throw new UnsupportedOperationException("Multiselect not supported");
- }
- }
-
- /**
- * @deprecated use {@link ListSelect}, {@link OptionGroup} or
- * {@link TwinColSelect} instead
- *
- * @see com.vaadin.ui.AbstractSelect#isMultiSelect()
- */
- @Deprecated
- @Override
- public boolean isMultiSelect() {
- return super.isMultiSelect();
- }
-
- /**
- * Sets whether to scroll the selected item visible (directly open the page
- * on which it is) when opening the combo box popup or not. Only applies to
- * single select mode.
- *
- * This requires finding the index of the item, which can be expensive in
- * many large lazy loading containers.
- *
- * @param scrollToSelectedItem
- * true to find the page with the selected item when opening the
- * selection popup
- */
- public void setScrollToSelectedItem(boolean scrollToSelectedItem) {
- this.scrollToSelectedItem = scrollToSelectedItem;
- }
-
- /**
- * Returns true if the select should find the page with the selected item
- * when opening the popup (single select combo box only).
- *
- * @see #setScrollToSelectedItem(boolean)
- *
- * @return true if the page with the selected item will be shown when
- * opening the popup
- */
- public boolean isScrollToSelectedItem() {
- return scrollToSelectedItem;
- }
-
-}
diff --git a/src/com/vaadin/ui/Slider.java b/src/com/vaadin/ui/Slider.java
deleted file mode 100644
index 94afe4e2bd..0000000000
--- a/src/com/vaadin/ui/Slider.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Map;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-
-/**
- * A component for selecting a numerical value within a range.
- *
- * Example code: <code>
- * class MyPlayer extends CustomComponent implements ValueChangeListener {
- *
- * Label volumeIndicator = new Label();
- * Slider slider;
- *
- * public MyPlayer() {
- * VerticalLayout vl = new VerticalLayout();
- * setCompositionRoot(vl);
- * slider = new Slider("Volume", 0, 100);
- * slider.setImmediate(true);
- * slider.setValue(new Double(50));
- * vl.addComponent(slider);
- * vl.addComponent(volumeIndicator);
- * volumeIndicator.setValue("Current volume:" + 50.0);
- * slider.addListener(this);
- *
- * }
- *
- * public void setVolume(double d) {
- * volumeIndicator.setValue("Current volume: " + d);
- * }
- *
- * public void valueChange(ValueChangeEvent event) {
- * Double d = (Double) event.getProperty().getValue();
- * setVolume(d.doubleValue());
- * }
- * }
- *
- * </code>
- *
- * @author Vaadin Ltd.
- */
-public class Slider extends AbstractField<Double> implements Vaadin6Component {
-
- public static final int ORIENTATION_HORIZONTAL = 0;
-
- public static final int ORIENTATION_VERTICAL = 1;
-
- /** Minimum value of slider */
- private double min = 0;
-
- /** Maximum value of slider */
- private double max = 100;
-
- /**
- * Resolution, how many digits are considered relevant after the decimal
- * point. Must be a non-negative value
- */
- private int resolution = 0;
-
- /**
- * Slider orientation (horizontal/vertical), defaults .
- */
- private int orientation = ORIENTATION_HORIZONTAL;
-
- /**
- * Default slider constructor. Sets all values to defaults and the slide
- * handle at minimum value.
- *
- */
- public Slider() {
- super();
- super.setValue(new Double(min));
- }
-
- /**
- * Create a new slider with the caption given as parameter.
- *
- * The range of the slider is set to 0-100 and only integer values are
- * allowed.
- *
- * @param caption
- * The caption for this slider (e.g. "Volume").
- */
- public Slider(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Create a new slider with the given range and resolution.
- *
- * @param min
- * The minimum value of the slider
- * @param max
- * The maximum value of the slider
- * @param resolution
- * The number of digits after the decimal point.
- */
- public Slider(double min, double max, int resolution) {
- this();
- setMin(min);
- setMax(max);
- setResolution(resolution);
- }
-
- /**
- * Create a new slider with the given range that only allows integer values.
- *
- * @param min
- * The minimum value of the slider
- * @param max
- * The maximum value of the slider
- */
- public Slider(int min, int max) {
- this();
- setMin(min);
- setMax(max);
- setResolution(0);
- }
-
- /**
- * Create a new slider with the given caption and range that only allows
- * integer values.
- *
- * @param caption
- * The caption for the slider
- * @param min
- * The minimum value of the slider
- * @param max
- * The maximum value of the slider
- */
- public Slider(String caption, int min, int max) {
- this(min, max);
- setCaption(caption);
- }
-
- /**
- * Gets the maximum slider value
- *
- * @return the largest value the slider can have
- */
- public double getMax() {
- return max;
- }
-
- /**
- * Set the maximum slider value. If the current value of the slider is
- * larger than this, the value is set to the new maximum.
- *
- * @param max
- * The new maximum slider value
- */
- public void setMax(double max) {
- this.max = max;
- if (getValue() > max) {
- setValue(max);
- }
- requestRepaint();
- }
-
- /**
- * Gets the minimum slider value
- *
- * @return the smallest value the slider can have
- */
- public double getMin() {
- return min;
- }
-
- /**
- * Set the minimum slider value. If the current value of the slider is
- * smaller than this, the value is set to the new minimum.
- *
- * @param max
- * The new minimum slider value
- */
- public void setMin(double min) {
- this.min = min;
- if (getValue() < min) {
- setValue(min);
- }
- requestRepaint();
- }
-
- /**
- * Get the current orientation of the slider (horizontal or vertical).
- *
- * @return {@link #ORIENTATION_HORIZONTAL} or
- * {@link #ORIENTATION_HORIZONTAL}
- */
- public int getOrientation() {
- return orientation;
- }
-
- /**
- * Set the orientation of the slider.
- *
- * @param The
- * new orientation, either {@link #ORIENTATION_HORIZONTAL} or
- * {@link #ORIENTATION_VERTICAL}
- */
- public void setOrientation(int orientation) {
- this.orientation = orientation;
- requestRepaint();
- }
-
- /**
- * Get the current resolution of the slider. The resolution is the number of
- * digits after the decimal point.
- *
- * @return resolution
- */
- public int getResolution() {
- return resolution;
- }
-
- /**
- * Set a new resolution for the slider. The resolution is the number of
- * digits after the decimal point.
- *
- * @param resolution
- */
- public void setResolution(int resolution) {
- if (resolution < 0) {
- return;
- }
- this.resolution = resolution;
- requestRepaint();
- }
-
- /**
- * Sets the value of the slider.
- *
- * @param value
- * The new value of the slider.
- * @param repaintIsNotNeeded
- * If true, client-side is not requested to repaint itself.
- * @throws ValueOutOfBoundsException
- * If the given value is not inside the range of the slider.
- * @see #setMin(double) {@link #setMax(double)}
- */
- @Override
- protected void setValue(Double value, boolean repaintIsNotNeeded) {
- final double v = value.doubleValue();
- double newValue;
- if (resolution > 0) {
- // Round up to resolution
- newValue = (int) (v * Math.pow(10, resolution));
- newValue = newValue / Math.pow(10, resolution);
- if (min > newValue || max < newValue) {
- throw new ValueOutOfBoundsException(value);
- }
- } else {
- newValue = (int) v;
- if (min > newValue || max < newValue) {
- throw new ValueOutOfBoundsException(value);
- }
- }
- super.setValue(newValue, repaintIsNotNeeded);
- }
-
- @Override
- public void setValue(Object newFieldValue)
- throws com.vaadin.data.Property.ReadOnlyException {
- if (newFieldValue != null && newFieldValue instanceof Number
- && !(newFieldValue instanceof Double)) {
- // Support setting all types of Numbers
- newFieldValue = ((Number) newFieldValue).doubleValue();
- }
-
- super.setValue(newFieldValue);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- target.addAttribute("min", min);
- if (max > min) {
- target.addAttribute("max", max);
- } else {
- target.addAttribute("max", min);
- }
- target.addAttribute("resolution", resolution);
-
- if (resolution > 0) {
- target.addVariable(this, "value", getValue().doubleValue());
- } else {
- target.addVariable(this, "value", getValue().intValue());
- }
-
- if (orientation == ORIENTATION_VERTICAL) {
- target.addAttribute("vertical", true);
- }
-
- }
-
- /**
- * Invoked when the value of a variable has changed. Slider listeners are
- * notified if the slider value has changed.
- *
- * @param source
- * @param variables
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey("value")) {
- final Object value = variables.get("value");
- final Double newValue = new Double(value.toString());
- if (newValue != null && newValue != getValue()
- && !newValue.equals(getValue())) {
- try {
- setValue(newValue, true);
- } catch (final ValueOutOfBoundsException e) {
- // Convert to nearest bound
- double out = e.getValue().doubleValue();
- if (out < min) {
- out = min;
- }
- if (out > max) {
- out = max;
- }
- super.setValue(new Double(out), false);
- }
- }
- }
- }
-
- /**
- * Thrown when the value of the slider is about to be set to a value that is
- * outside the valid range of the slider.
- *
- * @author Vaadin Ltd.
- *
- */
- public class ValueOutOfBoundsException extends RuntimeException {
-
- private final Double value;
-
- /**
- * Constructs an <code>ValueOutOfBoundsException</code> with the
- * specified detail message.
- *
- * @param valueOutOfBounds
- */
- public ValueOutOfBoundsException(Double valueOutOfBounds) {
- value = valueOutOfBounds;
- }
-
- /**
- * Gets the value that is outside the valid range of the slider.
- *
- * @return the value that is out of bounds
- */
- public Double getValue() {
- return value;
- }
-
- }
-
- @Override
- public Class<Double> getType() {
- return Double.class;
- }
-
-}
diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java
deleted file mode 100644
index c52e9394c0..0000000000
--- a/src/com/vaadin/ui/TabSheet.java
+++ /dev/null
@@ -1,1328 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.BlurNotifier;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.event.FieldEvents.FocusNotifier;
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.KeyMapper;
-import com.vaadin.terminal.LegacyPaint;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.tabsheet.TabsheetBaseConnector;
-import com.vaadin.terminal.gwt.client.ui.tabsheet.VTabsheet;
-import com.vaadin.ui.Component.Focusable;
-import com.vaadin.ui.themes.Reindeer;
-import com.vaadin.ui.themes.Runo;
-
-/**
- * TabSheet component.
- *
- * Tabs are typically identified by the component contained on the tab (see
- * {@link ComponentContainer}), and tab metadata (including caption, icon,
- * visibility, enabledness, closability etc.) is kept in separate {@link Tab}
- * instances.
- *
- * Tabs added with {@link #addComponent(Component)} get the caption and the icon
- * of the component at the time when the component is created, and these are not
- * automatically updated after tab creation.
- *
- * A tab sheet can have multiple tab selection listeners and one tab close
- * handler ({@link CloseHandler}), which by default removes the tab from the
- * TabSheet.
- *
- * The {@link TabSheet} can be styled with the .v-tabsheet, .v-tabsheet-tabs and
- * .v-tabsheet-content styles. Themes may also have pre-defined variations of
- * the tab sheet presentation, such as {@link Reindeer#TABSHEET_BORDERLESS},
- * {@link Runo#TABSHEET_SMALL} and several other styles in {@link Reindeer}.
- *
- * The current implementation does not load the tabs to the UI before the first
- * time they are shown, but this may change in future releases.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-public class TabSheet extends AbstractComponentContainer implements Focusable,
- FocusNotifier, BlurNotifier, Vaadin6Component {
-
- /**
- * List of component tabs (tab contents). In addition to being on this list,
- * there is a {@link Tab} object in tabs for each tab with meta-data about
- * the tab.
- */
- private final ArrayList<Component> components = new ArrayList<Component>();
-
- /**
- * Map containing information related to the tabs (caption, icon etc).
- */
- private final HashMap<Component, Tab> tabs = new HashMap<Component, Tab>();
-
- /**
- * Selected tab content component.
- */
- private Component selected = null;
-
- /**
- * Mapper between server-side component instances (tab contents) and keys
- * given to the client that identify tabs.
- */
- private final KeyMapper<Component> keyMapper = new KeyMapper<Component>();
-
- /**
- * When true, the tab selection area is not displayed to the user.
- */
- private boolean tabsHidden;
-
- /**
- * Handler to be called when a tab is closed.
- */
- private CloseHandler closeHandler;
-
- private int tabIndex;
-
- /**
- * Constructs a new Tabsheet. Tabsheet is immediate by default, and the
- * default close handler removes the tab being closed.
- */
- public TabSheet() {
- super();
- // expand horizontally by default
- setWidth(100, UNITS_PERCENTAGE);
- setImmediate(true);
- setCloseHandler(new CloseHandler() {
-
- @Override
- public void onTabClose(TabSheet tabsheet, Component c) {
- tabsheet.removeComponent(c);
- }
- });
- }
-
- /**
- * Gets the component container iterator for going through all the
- * components (tab contents).
- *
- * @return the unmodifiable Iterator of the tab content components
- */
-
- @Override
- public Iterator<Component> getComponentIterator() {
- return Collections.unmodifiableList(components).iterator();
- }
-
- /**
- * Gets the number of contained components (tabs). Consistent with the
- * iterator returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components
- */
-
- @Override
- public int getComponentCount() {
- return components.size();
- }
-
- /**
- * Removes a component and its corresponding tab.
- *
- * If the tab was selected, the first eligible (visible and enabled)
- * remaining tab is selected.
- *
- * @param c
- * the component to be removed.
- */
-
- @Override
- public void removeComponent(Component c) {
- if (c != null && components.contains(c)) {
- super.removeComponent(c);
- keyMapper.remove(c);
- components.remove(c);
- tabs.remove(c);
- if (c.equals(selected)) {
- if (components.isEmpty()) {
- setSelected(null);
- } else {
- // select the first enabled and visible tab, if any
- updateSelection();
- fireSelectedTabChange();
- }
- }
- requestRepaint();
- }
- }
-
- /**
- * Removes a {@link Tab} and the component associated with it, as previously
- * added with {@link #addTab(Component)},
- * {@link #addTab(Component, String, Resource)} or
- * {@link #addComponent(Component)}.
- * <p>
- * If the tab was selected, the first eligible (visible and enabled)
- * remaining tab is selected.
- * </p>
- *
- * @see #addTab(Component)
- * @see #addTab(Component, String, Resource)
- * @see #addComponent(Component)
- * @see #removeComponent(Component)
- * @param tab
- * the Tab to remove
- */
- public void removeTab(Tab tab) {
- removeComponent(tab.getComponent());
- }
-
- /**
- * Adds a new tab into TabSheet. Component caption and icon are copied to
- * the tab metadata at creation time.
- *
- * @see #addTab(Component)
- *
- * @param c
- * the component to be added.
- */
-
- @Override
- public void addComponent(Component c) {
- addTab(c);
- }
-
- /**
- * Adds a new tab into TabSheet.
- *
- * The first tab added to a tab sheet is automatically selected and a tab
- * selection event is fired.
- *
- * If the component is already present in the tab sheet, changes its caption
- * and returns the corresponding (old) tab, preserving other tab metadata.
- *
- * @param c
- * the component to be added onto tab - should not be null.
- * @param caption
- * the caption to be set for the component and used rendered in
- * tab bar
- * @return the created {@link Tab}
- */
- public Tab addTab(Component c, String caption) {
- return addTab(c, caption, null);
- }
-
- /**
- * Adds a new tab into TabSheet.
- *
- * The first tab added to a tab sheet is automatically selected and a tab
- * selection event is fired.
- *
- * If the component is already present in the tab sheet, changes its caption
- * and icon and returns the corresponding (old) tab, preserving other tab
- * metadata.
- *
- * @param c
- * the component to be added onto tab - should not be null.
- * @param caption
- * the caption to be set for the component and used rendered in
- * tab bar
- * @param icon
- * the icon to be set for the component and used rendered in tab
- * bar
- * @return the created {@link Tab}
- */
- public Tab addTab(Component c, String caption, Resource icon) {
- return addTab(c, caption, icon, components.size());
- }
-
- /**
- * Adds a new tab into TabSheet.
- *
- * The first tab added to a tab sheet is automatically selected and a tab
- * selection event is fired.
- *
- * If the component is already present in the tab sheet, changes its caption
- * and icon and returns the corresponding (old) tab, preserving other tab
- * metadata like the position.
- *
- * @param c
- * the component to be added onto tab - should not be null.
- * @param caption
- * the caption to be set for the component and used rendered in
- * tab bar
- * @param icon
- * the icon to be set for the component and used rendered in tab
- * bar
- * @param position
- * the position at where the the tab should be added.
- * @return the created {@link Tab}
- */
- public Tab addTab(Component c, String caption, Resource icon, int position) {
- if (c == null) {
- return null;
- } else if (tabs.containsKey(c)) {
- Tab tab = tabs.get(c);
- tab.setCaption(caption);
- tab.setIcon(icon);
- return tab;
- } else {
- components.add(position, c);
-
- Tab tab = new TabSheetTabImpl(caption, icon);
-
- tabs.put(c, tab);
- if (selected == null) {
- setSelected(c);
- fireSelectedTabChange();
- }
- super.addComponent(c);
- requestRepaint();
- return tab;
- }
- }
-
- /**
- * Adds a new tab into TabSheet. Component caption and icon are copied to
- * the tab metadata at creation time.
- *
- * If the tab sheet already contains the component, its tab is returned.
- *
- * @param c
- * the component to be added onto tab - should not be null.
- * @return the created {@link Tab}
- */
- public Tab addTab(Component c) {
- return addTab(c, components.size());
- }
-
- /**
- * Adds a new tab into TabSheet. Component caption and icon are copied to
- * the tab metadata at creation time.
- *
- * If the tab sheet already contains the component, its tab is returned.
- *
- * @param c
- * the component to be added onto tab - should not be null.
- * @param position
- * The position where the tab should be added
- * @return the created {@link Tab}
- */
- public Tab addTab(Component c, int position) {
- if (c == null) {
- return null;
- } else if (tabs.containsKey(c)) {
- return tabs.get(c);
- } else {
- return addTab(c, c.getCaption(), c.getIcon(), position);
- }
- }
-
- /**
- * Moves all components from another container to this container. The
- * components are removed from the other container.
- *
- * If the source container is a {@link TabSheet}, component captions and
- * icons are copied from it.
- *
- * @param source
- * the container components are removed from.
- */
-
- @Override
- public void moveComponentsFrom(ComponentContainer source) {
- for (final Iterator<Component> i = source.getComponentIterator(); i
- .hasNext();) {
- final Component c = i.next();
- String caption = null;
- Resource icon = null;
- if (TabSheet.class.isAssignableFrom(source.getClass())) {
- caption = ((TabSheet) source).getTabCaption(c);
- icon = ((TabSheet) source).getTabIcon(c);
- }
- source.removeComponent(c);
- addTab(c, caption, icon);
-
- }
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * the paint target
- * @throws PaintException
- * if the paint operation failed.
- */
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- if (areTabsHidden()) {
- target.addAttribute("hidetabs", true);
- }
-
- if (tabIndex != 0) {
- target.addAttribute("tabindex", tabIndex);
- }
-
- target.startTag("tabs");
-
- for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
- final Component component = i.next();
-
- Tab tab = tabs.get(component);
-
- target.startTag("tab");
- if (!tab.isEnabled() && tab.isVisible()) {
- target.addAttribute(
- TabsheetBaseConnector.ATTRIBUTE_TAB_DISABLED, true);
- }
-
- if (!tab.isVisible()) {
- target.addAttribute("hidden", true);
- }
-
- if (tab.isClosable()) {
- target.addAttribute("closable", true);
- }
-
- // tab icon, caption and description, but used via
- // VCaption.updateCaption(uidl)
- final Resource icon = tab.getIcon();
- if (icon != null) {
- target.addAttribute(TabsheetBaseConnector.ATTRIBUTE_TAB_ICON,
- icon);
- }
- final String caption = tab.getCaption();
- if (caption != null && caption.length() > 0) {
- target.addAttribute(
- TabsheetBaseConnector.ATTRIBUTE_TAB_CAPTION, caption);
- }
- ErrorMessage tabError = tab.getComponentError();
- if (tabError != null) {
- target.addAttribute(
- TabsheetBaseConnector.ATTRIBUTE_TAB_ERROR_MESSAGE,
- tabError.getFormattedHtmlMessage());
- }
- final String description = tab.getDescription();
- if (description != null) {
- target.addAttribute(
- TabsheetBaseConnector.ATTRIBUTE_TAB_DESCRIPTION,
- description);
- }
-
- final String styleName = tab.getStyleName();
- if (styleName != null && styleName.length() != 0) {
- target.addAttribute(VTabsheet.TAB_STYLE_NAME, styleName);
- }
-
- target.addAttribute("key", keyMapper.key(component));
- if (component.equals(selected)) {
- target.addAttribute("selected", true);
- LegacyPaint.paint(component, target);
- }
- target.endTag("tab");
- }
-
- target.endTag("tabs");
-
- if (selected != null) {
- target.addVariable(this, "selected", keyMapper.key(selected));
- }
-
- }
-
- /**
- * Are the tab selection parts ("tabs") hidden.
- *
- * @return true if the tabs are hidden in the UI
- */
- public boolean areTabsHidden() {
- return tabsHidden;
- }
-
- /**
- * Hides or shows the tab selection parts ("tabs").
- *
- * @param tabsHidden
- * true if the tabs should be hidden
- */
- public void hideTabs(boolean tabsHidden) {
- this.tabsHidden = tabsHidden;
- requestRepaint();
- }
-
- /**
- * Gets tab caption. The tab is identified by the tab content component.
- *
- * @param c
- * the component in the tab
- * @deprecated Use {@link #getTab(Component)} and {@link Tab#getCaption()}
- * instead.
- */
- @Deprecated
- public String getTabCaption(Component c) {
- Tab info = tabs.get(c);
- if (info == null) {
- return "";
- } else {
- return info.getCaption();
- }
- }
-
- /**
- * Sets tab caption. The tab is identified by the tab content component.
- *
- * @param c
- * the component in the tab
- * @param caption
- * the caption to set.
- * @deprecated Use {@link #getTab(Component)} and
- * {@link Tab#setCaption(String)} instead.
- */
- @Deprecated
- public void setTabCaption(Component c, String caption) {
- Tab info = tabs.get(c);
- if (info != null) {
- info.setCaption(caption);
- requestRepaint();
- }
- }
-
- /**
- * Gets the icon for a tab. The tab is identified by the tab content
- * component.
- *
- * @param c
- * the component in the tab
- * @deprecated Use {@link #getTab(Component)} and {@link Tab#getIcon()}
- * instead.
- */
- @Deprecated
- public Resource getTabIcon(Component c) {
- Tab info = tabs.get(c);
- if (info == null) {
- return null;
- } else {
- return info.getIcon();
- }
- }
-
- /**
- * Sets icon for the given component. The tab is identified by the tab
- * content component.
- *
- * @param c
- * the component in the tab
- * @param icon
- * the icon to set
- * @deprecated Use {@link #getTab(Component)} and
- * {@link Tab#setIcon(Resource)} instead.
- */
- @Deprecated
- public void setTabIcon(Component c, Resource icon) {
- Tab info = tabs.get(c);
- if (info != null) {
- info.setIcon(icon);
- requestRepaint();
- }
- }
-
- /**
- * Returns the {@link Tab} (metadata) for a component. The {@link Tab}
- * object can be used for setting caption,icon, etc for the tab.
- *
- * @param c
- * the component
- * @return The tab instance associated with the given component, or null if
- * the tabsheet does not contain the component.
- */
- public Tab getTab(Component c) {
- return tabs.get(c);
- }
-
- /**
- * Returns the {@link Tab} (metadata) for a component. The {@link Tab}
- * object can be used for setting caption,icon, etc for the tab.
- *
- * @param position
- * the position of the tab
- * @return The tab in the given position, or null if the position is out of
- * bounds.
- */
- public Tab getTab(int position) {
- if (position >= 0 && position < getComponentCount()) {
- return getTab(components.get(position));
- } else {
- return null;
- }
- }
-
- /**
- * Sets the selected tab. The tab is identified by the tab content
- * component. Does nothing if the tabsheet doesn't contain the component.
- *
- * @param c
- */
- public void setSelectedTab(Component c) {
- if (c != null && components.contains(c) && !c.equals(selected)) {
- setSelected(c);
- updateSelection();
- fireSelectedTabChange();
- requestRepaint();
- }
- }
-
- /**
- * Sets the selected tab in the TabSheet. Ensures that the selected tab is
- * repainted if needed.
- *
- * @param c
- * The new selection or null for no selection
- */
- private void setSelected(Component c) {
- selected = c;
- // Repaint of the selected component is needed as only the selected
- // component is communicated to the client. Otherwise this will be a
- // "cached" update even though the client knows nothing about the
- // connector
- if (selected instanceof ComponentContainer) {
- ((ComponentContainer) selected).requestRepaintAll();
- } else if (selected instanceof Table) {
- // Workaround until there's a generic way of telling a component
- // that there is no client side state to rely on. See #8642
- ((Table) selected).refreshRowCache();
- } else if (selected != null) {
- selected.requestRepaint();
- }
-
- }
-
- /**
- * Sets the selected tab. The tab is identified by the corresponding
- * {@link Tab Tab} instance. Does nothing if the tabsheet doesn't contain
- * the given tab.
- *
- * @param tab
- */
- public void setSelectedTab(Tab tab) {
- if (tab != null) {
- setSelectedTab(tab.getComponent());
- }
- }
-
- /**
- * Sets the selected tab, identified by its position. Does nothing if the
- * position is out of bounds.
- *
- * @param position
- */
- public void setSelectedTab(int position) {
- setSelectedTab(getTab(position));
- }
-
- /**
- * Checks if the current selection is valid, and updates the selection if
- * the previously selected component is not visible and enabled. The first
- * visible and enabled tab is selected if the current selection is empty or
- * invalid.
- *
- * This method does not fire tab change events, but the caller should do so
- * if appropriate.
- *
- * @return true if selection was changed, false otherwise
- */
- private boolean updateSelection() {
- Component originalSelection = selected;
- for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
- final Component component = i.next();
-
- Tab tab = tabs.get(component);
-
- /*
- * If we have no selection, if the current selection is invisible or
- * if the current selection is disabled (but the whole component is
- * not) we select this tab instead
- */
- Tab selectedTabInfo = null;
- if (selected != null) {
- selectedTabInfo = tabs.get(selected);
- }
- if (selected == null || selectedTabInfo == null
- || !selectedTabInfo.isVisible()
- || !selectedTabInfo.isEnabled()) {
-
- // The current selection is not valid so we need to change
- // it
- if (tab.isEnabled() && tab.isVisible()) {
- setSelected(component);
- break;
- } else {
- /*
- * The current selection is not valid but this tab cannot be
- * selected either.
- */
- setSelected(null);
- }
- }
- }
- return originalSelection != selected;
- }
-
- /**
- * Gets the selected tab content component.
- *
- * @return the selected tab contents
- */
- public Component getSelectedTab() {
- return selected;
- }
-
- // inherits javadoc
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey("selected")) {
- setSelectedTab(keyMapper.get((String) variables.get("selected")));
- }
- if (variables.containsKey("close")) {
- final Component tab = keyMapper
- .get((String) variables.get("close"));
- if (tab != null) {
- closeHandler.onTabClose(this, tab);
- }
- }
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- }
- if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
- }
-
- /**
- * Replaces a component (tab content) with another. This can be used to
- * change tab contents or to rearrange tabs. The tab position and some
- * metadata are preserved when moving components within the same
- * {@link TabSheet}.
- *
- * If the oldComponent is not present in the tab sheet, the new one is added
- * at the end.
- *
- * If the oldComponent is already in the tab sheet but the newComponent
- * isn't, the old tab is replaced with a new one, and the caption and icon
- * of the old one are copied to the new tab.
- *
- * If both old and new components are present, their positions are swapped.
- *
- * {@inheritDoc}
- */
-
- @Override
- public void replaceComponent(Component oldComponent, Component newComponent) {
-
- if (selected == oldComponent) {
- // keep selection w/o selectedTabChange event
- setSelected(newComponent);
- }
-
- Tab newTab = tabs.get(newComponent);
- Tab oldTab = tabs.get(oldComponent);
-
- // Gets the locations
- int oldLocation = -1;
- int newLocation = -1;
- int location = 0;
- for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
- final Component component = i.next();
-
- if (component == oldComponent) {
- oldLocation = location;
- }
- if (component == newComponent) {
- newLocation = location;
- }
-
- location++;
- }
-
- if (oldLocation == -1) {
- addComponent(newComponent);
- } else if (newLocation == -1) {
- removeComponent(oldComponent);
- newTab = addTab(newComponent, oldLocation);
- // Copy all relevant metadata to the new tab (#8793)
- // TODO Should reuse the old tab instance instead?
- copyTabMetadata(oldTab, newTab);
- } else {
- components.set(oldLocation, newComponent);
- components.set(newLocation, oldComponent);
-
- // Tab associations are not changed, but metadata is swapped between
- // the instances
- // TODO Should reassociate the instances instead?
- Tab tmp = new TabSheetTabImpl(null, null);
- copyTabMetadata(newTab, tmp);
- copyTabMetadata(oldTab, newTab);
- copyTabMetadata(tmp, oldTab);
-
- requestRepaint();
- }
-
- }
-
- /* Click event */
-
- private static final Method SELECTED_TAB_CHANGE_METHOD;
- static {
- try {
- SELECTED_TAB_CHANGE_METHOD = SelectedTabChangeListener.class
- .getDeclaredMethod("selectedTabChange",
- new Class[] { SelectedTabChangeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in TabSheet");
- }
- }
-
- /**
- * Selected tab change event. This event is sent when the selected (shown)
- * tab in the tab sheet is changed.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class SelectedTabChangeEvent extends Component.Event {
-
- /**
- * New instance of selected tab change event
- *
- * @param source
- * the Source of the event.
- */
- public SelectedTabChangeEvent(Component source) {
- super(source);
- }
-
- /**
- * TabSheet where the event occurred.
- *
- * @return the Source of the event.
- */
- public TabSheet getTabSheet() {
- return (TabSheet) getSource();
- }
- }
-
- /**
- * Selected tab change event listener. The listener is called whenever
- * another tab is selected, including when adding the first tab to a
- * tabsheet.
- *
- * @author Vaadin Ltd.
- *
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface SelectedTabChangeListener extends Serializable {
-
- /**
- * Selected (shown) tab in tab sheet has has been changed.
- *
- * @param event
- * the selected tab change event.
- */
- public void selectedTabChange(SelectedTabChangeEvent event);
- }
-
- /**
- * Adds a tab selection listener
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(SelectedTabChangeListener listener) {
- addListener(SelectedTabChangeEvent.class, listener,
- SELECTED_TAB_CHANGE_METHOD);
- }
-
- /**
- * Removes a tab selection listener
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(SelectedTabChangeListener listener) {
- removeListener(SelectedTabChangeEvent.class, listener,
- SELECTED_TAB_CHANGE_METHOD);
- }
-
- /**
- * Sends an event that the currently selected tab has changed.
- */
- protected void fireSelectedTabChange() {
- fireEvent(new SelectedTabChangeEvent(this));
- }
-
- /**
- * Tab meta-data for a component in a {@link TabSheet}.
- *
- * The meta-data includes the tab caption, icon, visibility and enabledness,
- * closability, description (tooltip) and an optional component error shown
- * in the tab.
- *
- * Tabs are identified by the component contained on them in most cases, and
- * the meta-data can be obtained with {@link TabSheet#getTab(Component)}.
- */
- public interface Tab extends Serializable {
- /**
- * Returns the visible status for the tab. An invisible tab is not shown
- * in the tab bar and cannot be selected.
- *
- * @return true for visible, false for hidden
- */
- public boolean isVisible();
-
- /**
- * Sets the visible status for the tab. An invisible tab is not shown in
- * the tab bar and cannot be selected, selection is changed
- * automatically when there is an attempt to select an invisible tab.
- *
- * @param visible
- * true for visible, false for hidden
- */
- public void setVisible(boolean visible);
-
- /**
- * Returns the closability status for the tab.
- *
- * @return true if the tab is allowed to be closed by the end user,
- * false for not allowing closing
- */
- public boolean isClosable();
-
- /**
- * Sets the closability status for the tab. A closable tab can be closed
- * by the user through the user interface. This also controls if a close
- * button is shown to the user or not.
- * <p>
- * Note! Currently only supported by TabSheet, not Accordion.
- * </p>
- *
- * @param visible
- * true if the end user is allowed to close the tab, false
- * for not allowing to close. Should default to false.
- */
- public void setClosable(boolean closable);
-
- /**
- * Returns the enabled status for the tab. A disabled tab is shown as
- * such in the tab bar and cannot be selected.
- *
- * @return true for enabled, false for disabled
- */
- public boolean isEnabled();
-
- /**
- * Sets the enabled status for the tab. A disabled tab is shown as such
- * in the tab bar and cannot be selected.
- *
- * @param enabled
- * true for enabled, false for disabled
- */
- public void setEnabled(boolean enabled);
-
- /**
- * Sets the caption for the tab.
- *
- * @param caption
- * the caption to set
- */
- public void setCaption(String caption);
-
- /**
- * Gets the caption for the tab.
- */
- public String getCaption();
-
- /**
- * Gets the icon for the tab.
- */
- public Resource getIcon();
-
- /**
- * Sets the icon for the tab.
- *
- * @param icon
- * the icon to set
- */
- public void setIcon(Resource icon);
-
- /**
- * Gets the description for the tab. The description can be used to
- * briefly describe the state of the tab to the user, and is typically
- * shown as a tooltip when hovering over the tab.
- *
- * @return the description for the tab
- */
- public String getDescription();
-
- /**
- * Sets the description for the tab. The description can be used to
- * briefly describe the state of the tab to the user, and is typically
- * shown as a tooltip when hovering over the tab.
- *
- * @param description
- * the new description string for the tab.
- */
- public void setDescription(String description);
-
- /**
- * Sets an error indicator to be shown in the tab. This can be used e.g.
- * to communicate to the user that there is a problem in the contents of
- * the tab.
- *
- * @see AbstractComponent#setComponentError(ErrorMessage)
- *
- * @param componentError
- * error message or null for none
- */
- public void setComponentError(ErrorMessage componentError);
-
- /**
- * Gets the current error message shown for the tab.
- *
- * TODO currently not sent to the client
- *
- * @see AbstractComponent#setComponentError(ErrorMessage)
- */
- public ErrorMessage getComponentError();
-
- /**
- * Get the component related to the Tab
- */
- public Component getComponent();
-
- /**
- * Sets a style name for the tab. The style name will be rendered as a
- * HTML class name, which can be used in a CSS definition.
- *
- * <pre>
- * Tab tab = tabsheet.addTab(tabContent, &quot;Tab text&quot;);
- * tab.setStyleName(&quot;mystyle&quot;);
- * </pre>
- * <p>
- * The used style name will be prefixed with "
- * {@code v-tabsheet-tabitemcell-}". For example, if you give a tab the
- * style "{@code mystyle}", the tab will get a "
- * {@code v-tabsheet-tabitemcell-mystyle}" style. You could then style
- * the component with:
- * </p>
- *
- * <pre>
- * .v-tabsheet-tabitemcell-mystyle {font-style: italic;}
- * </pre>
- *
- * <p>
- * This method will trigger a {@link RepaintRequestEvent} on the
- * TabSheet to which the Tab belongs.
- * </p>
- *
- * @param styleName
- * the new style to be set for tab
- * @see #getStyleName()
- */
- public void setStyleName(String styleName);
-
- /**
- * Gets the user-defined CSS style name of the tab. Built-in style names
- * defined in Vaadin or GWT are not returned.
- *
- * @return the style name or of the tab
- * @see #setStyleName(String)
- */
- public String getStyleName();
- }
-
- /**
- * TabSheet's implementation of {@link Tab} - tab metadata.
- */
- public class TabSheetTabImpl implements Tab {
-
- private String caption = "";
- private Resource icon = null;
- private boolean enabled = true;
- private boolean visible = true;
- private boolean closable = false;
- private String description = null;
- private ErrorMessage componentError = null;
- private String styleName;
-
- public TabSheetTabImpl(String caption, Resource icon) {
- if (caption == null) {
- caption = "";
- }
- this.caption = caption;
- this.icon = icon;
- }
-
- /**
- * Returns the tab caption. Can never be null.
- */
-
- @Override
- public String getCaption() {
- return caption;
- }
-
- @Override
- public void setCaption(String caption) {
- this.caption = caption;
- requestRepaint();
- }
-
- @Override
- public Resource getIcon() {
- return icon;
- }
-
- @Override
- public void setIcon(Resource icon) {
- this.icon = icon;
- requestRepaint();
- }
-
- @Override
- public boolean isEnabled() {
- return enabled;
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- if (updateSelection()) {
- fireSelectedTabChange();
- }
- requestRepaint();
- }
-
- @Override
- public boolean isVisible() {
- return visible;
- }
-
- @Override
- public void setVisible(boolean visible) {
- this.visible = visible;
- if (updateSelection()) {
- fireSelectedTabChange();
- }
- requestRepaint();
- }
-
- @Override
- public boolean isClosable() {
- return closable;
- }
-
- @Override
- public void setClosable(boolean closable) {
- this.closable = closable;
- requestRepaint();
- }
-
- public void close() {
-
- }
-
- @Override
- public String getDescription() {
- return description;
- }
-
- @Override
- public void setDescription(String description) {
- this.description = description;
- requestRepaint();
- }
-
- @Override
- public ErrorMessage getComponentError() {
- return componentError;
- }
-
- @Override
- public void setComponentError(ErrorMessage componentError) {
- this.componentError = componentError;
- requestRepaint();
- }
-
- @Override
- public Component getComponent() {
- for (Map.Entry<Component, Tab> entry : tabs.entrySet()) {
- if (entry.getValue() == this) {
- return entry.getKey();
- }
- }
- return null;
- }
-
- @Override
- public void setStyleName(String styleName) {
- this.styleName = styleName;
- requestRepaint();
- }
-
- @Override
- public String getStyleName() {
- return styleName;
- }
- }
-
- /**
- * CloseHandler is used to process tab closing events. Default behavior is
- * to remove the tab from the TabSheet.
- *
- * @author Jouni Koivuviita / Vaadin Ltd.
- * @since 6.2.0
- *
- */
- public interface CloseHandler extends Serializable {
-
- /**
- * Called when a user has pressed the close icon of a tab in the client
- * side widget.
- *
- * @param tabsheet
- * the TabSheet to which the tab belongs to
- * @param tabContent
- * the component that corresponds to the tab whose close
- * button was clicked
- */
- void onTabClose(final TabSheet tabsheet, final Component tabContent);
- }
-
- /**
- * Provide a custom {@link CloseHandler} for this TabSheet if you wish to
- * perform some additional tasks when a user clicks on a tabs close button,
- * e.g. show a confirmation dialogue before removing the tab.
- *
- * To remove the tab, if you provide your own close handler, you must call
- * {@link #removeComponent(Component)} yourself.
- *
- * The default CloseHandler for TabSheet will only remove the tab.
- *
- * @param handler
- */
- public void setCloseHandler(CloseHandler handler) {
- closeHandler = handler;
- }
-
- /**
- * Sets the position of the tab.
- *
- * @param tab
- * The tab
- * @param position
- * The new position of the tab
- */
- public void setTabPosition(Tab tab, int position) {
- int oldPosition = getTabPosition(tab);
- components.remove(oldPosition);
- components.add(position, tab.getComponent());
- requestRepaint();
- }
-
- /**
- * Gets the position of the tab
- *
- * @param tab
- * The tab
- * @return
- */
- public int getTabPosition(Tab tab) {
- return components.indexOf(tab.getComponent());
- }
-
- @Override
- public void focus() {
- super.focus();
- }
-
- @Override
- public int getTabIndex() {
- return tabIndex;
- }
-
- @Override
- public void setTabIndex(int tabIndex) {
- this.tabIndex = tabIndex;
- requestRepaint();
- }
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
-
- }
-
- @Override
- public boolean isComponentVisible(Component childComponent) {
- return childComponent == getSelectedTab();
- }
-
- /**
- * Copies properties from one Tab to another.
- *
- * @param from
- * The tab whose data to copy.
- * @param to
- * The tab to which copy the data.
- */
- private static void copyTabMetadata(Tab from, Tab to) {
- to.setCaption(from.getCaption());
- to.setIcon(from.getIcon());
- to.setDescription(from.getDescription());
- to.setVisible(from.isVisible());
- to.setEnabled(from.isEnabled());
- to.setClosable(from.isClosable());
- to.setStyleName(from.getStyleName());
- to.setComponentError(from.getComponentError());
- }
-}
diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java
deleted file mode 100644
index 39b7fb7473..0000000000
--- a/src/com/vaadin/ui/Table.java
+++ /dev/null
@@ -1,5449 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.util.ContainerOrderedWrapper;
-import com.vaadin.data.util.IndexedContainer;
-import com.vaadin.data.util.converter.Converter;
-import com.vaadin.data.util.converter.ConverterUtil;
-import com.vaadin.event.Action;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.event.DataBoundTransferable;
-import com.vaadin.event.ItemClickEvent;
-import com.vaadin.event.ItemClickEvent.ItemClickListener;
-import com.vaadin.event.ItemClickEvent.ItemClickNotifier;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DragSource;
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.terminal.KeyMapper;
-import com.vaadin.terminal.LegacyPaint;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.table.VScrollTable;
-
-/**
- * <p>
- * <code>Table</code> is used for representing data or components in a pageable
- * and selectable table.
- * </p>
- *
- * <p>
- * Scalability of the Table is largely dictated by the container. A table does
- * not have a limit for the number of items and is just as fast with hundreds of
- * thousands of items as with just a few. The current GWT implementation with
- * scrolling however limits the number of rows to around 500000, depending on
- * the browser and the pixel height of rows.
- * </p>
- *
- * <p>
- * Components in a Table will not have their caption nor icon rendered.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings({ "deprecation" })
-public class Table extends AbstractSelect implements Action.Container,
- Container.Ordered, Container.Sortable, ItemClickNotifier, DragSource,
- DropTarget, HasComponents {
-
- private transient Logger logger = null;
-
- /**
- * Modes that Table support as drag sourse.
- */
- public enum TableDragMode {
- /**
- * Table does not start drag and drop events. HTM5 style events started
- * by browser may still happen.
- */
- NONE,
- /**
- * Table starts drag with a one row only.
- */
- ROW,
- /**
- * Table drags selected rows, if drag starts on a selected rows. Else it
- * starts like in ROW mode. Note, that in Transferable there will still
- * be only the row on which the drag started, other dragged rows need to
- * be checked from the source Table.
- */
- MULTIROW
- }
-
- protected static final int CELL_KEY = 0;
-
- protected static final int CELL_HEADER = 1;
-
- protected static final int CELL_ICON = 2;
-
- protected static final int CELL_ITEMID = 3;
-
- protected static final int CELL_GENERATED_ROW = 4;
-
- protected static final int CELL_FIRSTCOL = 5;
-
- public enum Align {
- /**
- * Left column alignment. <b>This is the default behaviour. </b>
- */
- LEFT("b"),
-
- /**
- * Center column alignment.
- */
- CENTER("c"),
-
- /**
- * Right column alignment.
- */
- RIGHT("e");
-
- private String alignment;
-
- private Align(String alignment) {
- this.alignment = alignment;
- }
-
- @Override
- public String toString() {
- return alignment;
- }
-
- public Align convertStringToAlign(String string) {
- if (string == null) {
- return null;
- }
- if (string.equals("b")) {
- return Align.LEFT;
- } else if (string.equals("c")) {
- return Align.CENTER;
- } else if (string.equals("e")) {
- return Align.RIGHT;
- } else {
- return null;
- }
- }
- }
-
- /**
- * @deprecated from 7.0, use {@link Align#LEFT} instead
- */
- @Deprecated
- public static final Align ALIGN_LEFT = Align.LEFT;
-
- /**
- * @deprecated from 7.0, use {@link Align#CENTER} instead
- */
- @Deprecated
- public static final Align ALIGN_CENTER = Align.CENTER;
-
- /**
- * @deprecated from 7.0, use {@link Align#RIGHT} instead
- */
- @Deprecated
- public static final Align ALIGN_RIGHT = Align.RIGHT;
-
- public enum ColumnHeaderMode {
- /**
- * Column headers are hidden.
- */
- HIDDEN,
- /**
- * Property ID:s are used as column headers.
- */
- ID,
- /**
- * Column headers are explicitly specified with
- * {@link #setColumnHeaders(String[])}.
- */
- EXPLICIT,
- /**
- * Column headers are explicitly specified with
- * {@link #setColumnHeaders(String[])}. If a header is not specified for
- * a given property, its property id is used instead.
- * <p>
- * <b>This is the default behavior. </b>
- */
- EXPLICIT_DEFAULTS_ID
- }
-
- /**
- * @deprecated from 7.0, use {@link ColumnHeaderMode#HIDDEN} instead
- */
- @Deprecated
- public static final ColumnHeaderMode COLUMN_HEADER_MODE_HIDDEN = ColumnHeaderMode.HIDDEN;
-
- /**
- * @deprecated from 7.0, use {@link ColumnHeaderMode#ID} instead
- */
- @Deprecated
- public static final ColumnHeaderMode COLUMN_HEADER_MODE_ID = ColumnHeaderMode.ID;
-
- /**
- * @deprecated from 7.0, use {@link ColumnHeaderMode#EXPLICIT} instead
- */
- @Deprecated
- public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT = ColumnHeaderMode.EXPLICIT;
-
- /**
- * @deprecated from 7.0, use {@link ColumnHeaderMode#EXPLICIT_DEFAULTS_ID}
- * instead
- */
- @Deprecated
- public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID;
-
- public enum RowHeaderMode {
- /**
- * Row caption mode: The row headers are hidden. <b>This is the default
- * mode. </b>
- */
- HIDDEN(null),
- /**
- * Row caption mode: Items Id-objects toString is used as row caption.
- */
- ID(ItemCaptionMode.ID),
- /**
- * Row caption mode: Item-objects toString is used as row caption.
- */
- ITEM(ItemCaptionMode.ITEM),
- /**
- * Row caption mode: Index of the item is used as item caption. The
- * index mode can only be used with the containers implementing the
- * {@link com.vaadin.data.Container.Indexed} interface.
- */
- INDEX(ItemCaptionMode.INDEX),
- /**
- * Row caption mode: Item captions are explicitly specified, but if the
- * caption is missing, the item id objects <code>toString()</code> is
- * used instead.
- */
- EXPLICIT_DEFAULTS_ID(ItemCaptionMode.EXPLICIT_DEFAULTS_ID),
- /**
- * Row caption mode: Item captions are explicitly specified.
- */
- EXPLICIT(ItemCaptionMode.EXPLICIT),
- /**
- * Row caption mode: Only icons are shown, the captions are hidden.
- */
- ICON_ONLY(ItemCaptionMode.ICON_ONLY),
- /**
- * Row caption mode: Item captions are read from property specified with
- * {@link #setItemCaptionPropertyId(Object)}.
- */
- PROPERTY(ItemCaptionMode.PROPERTY);
-
- ItemCaptionMode mode;
-
- private RowHeaderMode(ItemCaptionMode mode) {
- this.mode = mode;
- }
-
- public ItemCaptionMode getItemCaptionMode() {
- return mode;
- }
- }
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#HIDDEN} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_HIDDEN = RowHeaderMode.HIDDEN;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#ID} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_ID = RowHeaderMode.ID;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#ITEM} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_ITEM = RowHeaderMode.ITEM;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#INDEX} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_INDEX = RowHeaderMode.INDEX;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#EXPLICIT_DEFAULTS_ID}
- * instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID = RowHeaderMode.EXPLICIT_DEFAULTS_ID;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#EXPLICIT} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT = RowHeaderMode.EXPLICIT;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#ICON_ONLY} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_ICON_ONLY = RowHeaderMode.ICON_ONLY;
-
- /**
- * @deprecated from 7.0, use {@link RowHeaderMode#PROPERTY} instead
- */
- @Deprecated
- public static final RowHeaderMode ROW_HEADER_MODE_PROPERTY = RowHeaderMode.PROPERTY;
-
- /**
- * The default rate that table caches rows for smooth scrolling.
- */
- private static final double CACHE_RATE_DEFAULT = 2;
-
- private static final String ROW_HEADER_COLUMN_KEY = "0";
- private static final Object ROW_HEADER_FAKE_PROPERTY_ID = new UniqueSerializable() {
- };
-
- /* Private table extensions to Select */
-
- /**
- * True if column collapsing is allowed.
- */
- private boolean columnCollapsingAllowed = false;
-
- /**
- * True if reordering of columns is allowed on the client side.
- */
- private boolean columnReorderingAllowed = false;
-
- /**
- * Keymapper for column ids.
- */
- private final KeyMapper<Object> columnIdMap = new KeyMapper<Object>();
-
- /**
- * Holds visible column propertyIds - in order.
- */
- private LinkedList<Object> visibleColumns = new LinkedList<Object>();
-
- /**
- * Holds noncollapsible columns.
- */
- private HashSet<Object> noncollapsibleColumns = new HashSet<Object>();
-
- /**
- * Holds propertyIds of currently collapsed columns.
- */
- private final HashSet<Object> collapsedColumns = new HashSet<Object>();
-
- /**
- * Holds headers for visible columns (by propertyId).
- */
- private final HashMap<Object, String> columnHeaders = new HashMap<Object, String>();
-
- /**
- * Holds footers for visible columns (by propertyId).
- */
- private final HashMap<Object, String> columnFooters = new HashMap<Object, String>();
-
- /**
- * Holds icons for visible columns (by propertyId).
- */
- private final HashMap<Object, Resource> columnIcons = new HashMap<Object, Resource>();
-
- /**
- * Holds alignments for visible columns (by propertyId).
- */
- private HashMap<Object, Align> columnAlignments = new HashMap<Object, Align>();
-
- /**
- * Holds column widths in pixels (Integer) or expand ratios (Float) for
- * visible columns (by propertyId).
- */
- private final HashMap<Object, Object> columnWidths = new HashMap<Object, Object>();
-
- /**
- * Holds column generators
- */
- private final HashMap<Object, ColumnGenerator> columnGenerators = new LinkedHashMap<Object, ColumnGenerator>();
-
- /**
- * Holds value of property pageLength. 0 disables paging.
- */
- private int pageLength = 15;
-
- /**
- * Id the first item on the current page.
- */
- private Object currentPageFirstItemId = null;
-
- /**
- * Index of the first item on the current page.
- */
- private int currentPageFirstItemIndex = 0;
-
- /**
- * Holds value of property selectable.
- */
- private boolean selectable = false;
-
- /**
- * Holds value of property columnHeaderMode.
- */
- private ColumnHeaderMode columnHeaderMode = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID;
-
- /**
- * Holds value of property rowHeaderMode.
- */
- private RowHeaderMode rowHeaderMode = RowHeaderMode.EXPLICIT_DEFAULTS_ID;
-
- /**
- * Should the Table footer be visible?
- */
- private boolean columnFootersVisible = false;
-
- /**
- * Page contents buffer used in buffered mode.
- */
- private Object[][] pageBuffer = null;
-
- /**
- * Set of properties listened - the list is kept to release the listeners
- * later.
- */
- private HashSet<Property<?>> listenedProperties = null;
-
- /**
- * Set of visible components - the is used for needsRepaint calculation.
- */
- private HashSet<Component> visibleComponents = null;
-
- /**
- * List of action handlers.
- */
- private LinkedList<Handler> actionHandlers = null;
-
- /**
- * Action mapper.
- */
- private KeyMapper<Action> actionMapper = null;
-
- /**
- * Table cell editor factory.
- */
- private TableFieldFactory fieldFactory = DefaultFieldFactory.get();
-
- /**
- * Is table editable.
- */
- private boolean editable = false;
-
- /**
- * Current sorting direction.
- */
- private boolean sortAscending = true;
-
- /**
- * Currently table is sorted on this propertyId.
- */
- private Object sortContainerPropertyId = null;
-
- /**
- * Is table sorting by the user enabled.
- */
- private boolean sortEnabled = true;
-
- /**
- * Number of rows explicitly requested by the client to be painted on next
- * paint. This is -1 if no request by the client is made. Painting the
- * component will automatically reset this to -1.
- */
- private int reqRowsToPaint = -1;
-
- /**
- * Index of the first rows explicitly requested by the client to be painted.
- * This is -1 if no request by the client is made. Painting the component
- * will automatically reset this to -1.
- */
- private int reqFirstRowToPaint = -1;
-
- private int firstToBeRenderedInClient = -1;
-
- private int lastToBeRenderedInClient = -1;
-
- private boolean isContentRefreshesEnabled = true;
-
- private int pageBufferFirstIndex;
-
- private boolean containerChangeToBeRendered = false;
-
- /**
- * Table cell specific style generator
- */
- private CellStyleGenerator cellStyleGenerator = null;
-
- /**
- * Table cell specific tooltip generator
- */
- private ItemDescriptionGenerator itemDescriptionGenerator;
-
- /*
- * EXPERIMENTAL feature: will tell the client to re-calculate column widths
- * if set to true. Currently no setter: extend to enable.
- */
- protected boolean alwaysRecalculateColumnWidths = false;
-
- private double cacheRate = CACHE_RATE_DEFAULT;
-
- private TableDragMode dragMode = TableDragMode.NONE;
-
- private DropHandler dropHandler;
-
- private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT;
-
- private boolean rowCacheInvalidated;
-
- private RowGenerator rowGenerator = null;
-
- private final Map<Field<?>, Property<?>> associatedProperties = new HashMap<Field<?>, Property<?>>();
-
- private boolean painted = false;
-
- private HashMap<Object, Converter<String, Object>> propertyValueConverters = new HashMap<Object, Converter<String, Object>>();
-
- /**
- * Set to true if the client-side should be informed that the key mapper has
- * been reset so it can avoid sending back references to keys that are no
- * longer present.
- */
- private boolean keyMapperReset;
-
- /* Table constructors */
-
- /**
- * Creates a new empty table.
- */
- public Table() {
- setRowHeaderMode(ROW_HEADER_MODE_HIDDEN);
- }
-
- /**
- * Creates a new empty table with caption.
- *
- * @param caption
- */
- public Table(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Creates a new table with caption and connect it to a Container.
- *
- * @param caption
- * @param dataSource
- */
- public Table(String caption, Container dataSource) {
- this();
- setCaption(caption);
- setContainerDataSource(dataSource);
- }
-
- /* Table functionality */
-
- /**
- * Gets the array of visible column id:s, including generated columns.
- *
- * <p>
- * The columns are show in the order of their appearance in this array.
- * </p>
- *
- * @return an array of currently visible propertyIds and generated column
- * ids.
- */
- public Object[] getVisibleColumns() {
- if (visibleColumns == null) {
- return null;
- }
- return visibleColumns.toArray();
- }
-
- /**
- * Sets the array of visible column property id:s.
- *
- * <p>
- * The columns are show in the order of their appearance in this array.
- * </p>
- *
- * @param visibleColumns
- * the Array of shown property id:s.
- */
- public void setVisibleColumns(Object[] visibleColumns) {
-
- // Visible columns must exist
- if (visibleColumns == null) {
- throw new NullPointerException(
- "Can not set visible columns to null value");
- }
-
- // TODO add error check that no duplicate identifiers exist
-
- // Checks that the new visible columns contains no nulls and properties
- // exist
- final Collection<?> properties = getContainerPropertyIds();
- for (int i = 0; i < visibleColumns.length; i++) {
- if (visibleColumns[i] == null) {
- throw new NullPointerException("Ids must be non-nulls");
- } else if (!properties.contains(visibleColumns[i])
- && !columnGenerators.containsKey(visibleColumns[i])) {
- throw new IllegalArgumentException(
- "Ids must exist in the Container or as a generated column , missing id: "
- + visibleColumns[i]);
- }
- }
-
- // If this is called before the constructor is finished, it might be
- // uninitialized
- final LinkedList<Object> newVC = new LinkedList<Object>();
- for (int i = 0; i < visibleColumns.length; i++) {
- newVC.add(visibleColumns[i]);
- }
-
- // Removes alignments, icons and headers from hidden columns
- if (this.visibleColumns != null) {
- boolean disabledHere = disableContentRefreshing();
- try {
- for (final Iterator<Object> i = this.visibleColumns.iterator(); i
- .hasNext();) {
- final Object col = i.next();
- if (!newVC.contains(col)) {
- setColumnHeader(col, null);
- setColumnAlignment(col, (Align) null);
- setColumnIcon(col, null);
- }
- }
- } finally {
- if (disabledHere) {
- enableContentRefreshing(false);
- }
- }
- }
-
- this.visibleColumns = newVC;
-
- // Assures visual refresh
- refreshRowCache();
- }
-
- /**
- * Gets the headers of the columns.
- *
- * <p>
- * The headers match the property id:s given my the set visible column
- * headers. The table must be set in either
- * {@link #COLUMN_HEADER_MODE_EXPLICIT} or
- * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the
- * headers. In the defaults mode any nulls in the headers array are replaced
- * with id.toString().
- * </p>
- *
- * @return the Array of column headers.
- */
- public String[] getColumnHeaders() {
- if (columnHeaders == null) {
- return null;
- }
- final String[] headers = new String[visibleColumns.size()];
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext(); i++) {
- headers[i] = getColumnHeader(it.next());
- }
- return headers;
- }
-
- /**
- * Sets the headers of the columns.
- *
- * <p>
- * The headers match the property id:s given my the set visible column
- * headers. The table must be set in either
- * {@link #COLUMN_HEADER_MODE_EXPLICIT} or
- * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the
- * headers. In the defaults mode any nulls in the headers array are replaced
- * with id.toString() outputs when rendering.
- * </p>
- *
- * @param columnHeaders
- * the Array of column headers that match the
- * {@link #getVisibleColumns()} method.
- */
- public void setColumnHeaders(String[] columnHeaders) {
-
- if (columnHeaders.length != visibleColumns.size()) {
- throw new IllegalArgumentException(
- "The length of the headers array must match the number of visible columns");
- }
-
- this.columnHeaders.clear();
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext() && i < columnHeaders.length; i++) {
- this.columnHeaders.put(it.next(), columnHeaders[i]);
- }
-
- requestRepaint();
- }
-
- /**
- * Gets the icons of the columns.
- *
- * <p>
- * The icons in headers match the property id:s given my the set visible
- * column headers. The table must be set in either
- * {@link #COLUMN_HEADER_MODE_EXPLICIT} or
- * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers
- * with icons.
- * </p>
- *
- * @return the Array of icons that match the {@link #getVisibleColumns()}.
- */
- public Resource[] getColumnIcons() {
- if (columnIcons == null) {
- return null;
- }
- final Resource[] icons = new Resource[visibleColumns.size()];
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext(); i++) {
- icons[i] = columnIcons.get(it.next());
- }
-
- return icons;
- }
-
- /**
- * Sets the icons of the columns.
- *
- * <p>
- * The icons in headers match the property id:s given my the set visible
- * column headers. The table must be set in either
- * {@link #COLUMN_HEADER_MODE_EXPLICIT} or
- * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers
- * with icons.
- * </p>
- *
- * @param columnIcons
- * the Array of icons that match the {@link #getVisibleColumns()}
- * .
- */
- public void setColumnIcons(Resource[] columnIcons) {
-
- if (columnIcons.length != visibleColumns.size()) {
- throw new IllegalArgumentException(
- "The length of the icons array must match the number of visible columns");
- }
-
- this.columnIcons.clear();
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext() && i < columnIcons.length; i++) {
- this.columnIcons.put(it.next(), columnIcons[i]);
- }
-
- requestRepaint();
- }
-
- /**
- * Gets the array of column alignments.
- *
- * <p>
- * The items in the array must match the properties identified by
- * {@link #getVisibleColumns()}. The possible values for the alignments
- * include:
- * <ul>
- * <li>{@link Align#LEFT}: Left alignment</li>
- * <li>{@link Align#CENTER}: Centered</li>
- * <li>{@link Align#RIGHT}: Right alignment</li>
- * </ul>
- * The alignments default to {@link Align#LEFT}: any null values are
- * rendered as align lefts.
- * </p>
- *
- * @return the Column alignments array.
- */
- public Align[] getColumnAlignments() {
- if (columnAlignments == null) {
- return null;
- }
- final Align[] alignments = new Align[visibleColumns.size()];
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext(); i++) {
- alignments[i] = getColumnAlignment(it.next());
- }
-
- return alignments;
- }
-
- /**
- * Sets the column alignments.
- *
- * <p>
- * The amount of items in the array must match the amount of properties
- * identified by {@link #getVisibleColumns()}. The possible values for the
- * alignments include:
- * <ul>
- * <li>{@link Align#LEFT}: Left alignment</li>
- * <li>{@link Align#CENTER}: Centered</li>
- * <li>{@link Align#RIGHT}: Right alignment</li>
- * </ul>
- * The alignments default to {@link Align#LEFT}
- * </p>
- *
- * @param columnAlignments
- * the Column alignments array.
- */
- public void setColumnAlignments(Align... columnAlignments) {
-
- if (columnAlignments.length != visibleColumns.size()) {
- throw new IllegalArgumentException(
- "The length of the alignments array must match the number of visible columns");
- }
-
- // Resets the alignments
- final HashMap<Object, Align> newCA = new HashMap<Object, Align>();
- int i = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext() && i < columnAlignments.length; i++) {
- newCA.put(it.next(), columnAlignments[i]);
- }
- this.columnAlignments = newCA;
-
- // Assures the visual refresh. No need to reset the page buffer before
- // as the content has not changed, only the alignments.
- refreshRenderedCells();
- }
-
- /**
- * Sets columns width (in pixels). Theme may not necessary respect very
- * small or very big values. Setting width to -1 (default) means that theme
- * will make decision of width.
- *
- * <p>
- * Column can either have a fixed width or expand ratio. The latter one set
- * is used. See @link {@link #setColumnExpandRatio(Object, float)}.
- *
- * @param propertyId
- * colunmns property id
- * @param width
- * width to be reserved for colunmns content
- * @since 4.0.3
- */
- public void setColumnWidth(Object propertyId, int width) {
- if (propertyId == null) {
- // Since propertyId is null, this is the row header. Use the magic
- // id to store the width of the row header.
- propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
- }
- if (width < 0) {
- columnWidths.remove(propertyId);
- } else {
- columnWidths.put(propertyId, Integer.valueOf(width));
- }
- requestRepaint();
- }
-
- /**
- * Sets the column expand ratio for given column.
- * <p>
- * Expand ratios can be defined to customize the way how excess space is
- * divided among columns. Table can have excess space if it has its width
- * defined and there is horizontally more space than columns consume
- * naturally. Excess space is the space that is not used by columns with
- * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural
- * width (no width nor expand ratio).
- *
- * <p>
- * By default (without expand ratios) the excess space is divided
- * proportionally to columns natural widths.
- *
- * <p>
- * Only expand ratios of visible columns are used in final calculations.
- *
- * <p>
- * Column can either have a fixed width or expand ratio. The latter one set
- * is used.
- *
- * <p>
- * A column with expand ratio is considered to be minimum width by default
- * (if no excess space exists). The minimum width is defined by terminal
- * implementation.
- *
- * <p>
- * If terminal implementation supports re-sizable columns the column becomes
- * fixed width column if users resizes the column.
- *
- * @param propertyId
- * columns property id
- * @param expandRatio
- * the expandRatio used to divide excess space for this column
- */
- public void setColumnExpandRatio(Object propertyId, float expandRatio) {
- if (expandRatio < 0) {
- columnWidths.remove(propertyId);
- } else {
- columnWidths.put(propertyId, new Float(expandRatio));
- }
- }
-
- public float getColumnExpandRatio(Object propertyId) {
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Float)) {
- return -1;
- }
- final Float value = (Float) width;
- return value.floatValue();
-
- }
-
- /**
- * Gets the pixel width of column
- *
- * @param propertyId
- * @return width of column or -1 when value not set
- */
- public int getColumnWidth(Object propertyId) {
- if (propertyId == null) {
- // Since propertyId is null, this is the row header. Use the magic
- // id to retrieve the width of the row header.
- propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
- }
- final Object width = columnWidths.get(propertyId);
- if (width == null || !(width instanceof Integer)) {
- return -1;
- }
- final Integer value = (Integer) width;
- return value.intValue();
- }
-
- /**
- * Gets the page length.
- *
- * <p>
- * Setting page length 0 disables paging.
- * </p>
- *
- * @return the Length of one page.
- */
- public int getPageLength() {
- return pageLength;
- }
-
- /**
- * Sets the page length.
- *
- * <p>
- * Setting page length 0 disables paging. The page length defaults to 15.
- * </p>
- *
- * <p>
- * If Table has width set ({@link #setWidth(float, int)} ) the client side
- * may update the page length automatically the correct value.
- * </p>
- *
- * @param pageLength
- * the length of one page.
- */
- public void setPageLength(int pageLength) {
- if (pageLength >= 0 && this.pageLength != pageLength) {
- this.pageLength = pageLength;
- // Assures the visual refresh
- refreshRowCache();
- }
- }
-
- /**
- * This method adjusts a possible caching mechanism of table implementation.
- *
- * <p>
- * Table component may fetch and render some rows outside visible area. With
- * complex tables (for example containing layouts and components), the
- * client side may become unresponsive. Setting the value lower, UI will
- * become more responsive. With higher values scrolling in client will hit
- * server less frequently.
- *
- * <p>
- * The amount of cached rows will be cacheRate multiplied with pageLength (
- * {@link #setPageLength(int)} both below and above visible area..
- *
- * @param cacheRate
- * a value over 0 (fastest rendering time). Higher value will
- * cache more rows on server (smoother scrolling). Default value
- * is 2.
- */
- public void setCacheRate(double cacheRate) {
- if (cacheRate < 0) {
- throw new IllegalArgumentException(
- "cacheRate cannot be less than zero");
- }
- if (this.cacheRate != cacheRate) {
- this.cacheRate = cacheRate;
- requestRepaint();
- }
- }
-
- /**
- * @see #setCacheRate(double)
- *
- * @return the current cache rate value
- */
- public double getCacheRate() {
- return cacheRate;
- }
-
- /**
- * Getter for property currentPageFirstItem.
- *
- * @return the Value of property currentPageFirstItem.
- */
- public Object getCurrentPageFirstItemId() {
-
- // Priorise index over id if indexes are supported
- if (items instanceof Container.Indexed) {
- final int index = getCurrentPageFirstItemIndex();
- Object id = null;
- if (index >= 0 && index < size()) {
- id = getIdByIndex(index);
- }
- if (id != null && !id.equals(currentPageFirstItemId)) {
- currentPageFirstItemId = id;
- }
- }
-
- // If there is no item id at all, use the first one
- if (currentPageFirstItemId == null) {
- currentPageFirstItemId = firstItemId();
- }
-
- return currentPageFirstItemId;
- }
-
- protected Object getIdByIndex(int index) {
- return ((Container.Indexed) items).getIdByIndex(index);
- }
-
- /**
- * Setter for property currentPageFirstItemId.
- *
- * @param currentPageFirstItemId
- * the New value of property currentPageFirstItemId.
- */
- public void setCurrentPageFirstItemId(Object currentPageFirstItemId) {
-
- // Gets the corresponding index
- int index = -1;
- if (items instanceof Container.Indexed) {
- index = indexOfId(currentPageFirstItemId);
- } else {
- // If the table item container does not have index, we have to
- // calculates the index by hand
- Object id = firstItemId();
- while (id != null && !id.equals(currentPageFirstItemId)) {
- index++;
- id = nextItemId(id);
- }
- if (id == null) {
- index = -1;
- }
- }
-
- // If the search for item index was successful
- if (index >= 0) {
- /*
- * The table is not capable of displaying an item in the container
- * as the first if there are not enough items following the selected
- * item so the whole table (pagelength) is filled.
- */
- int maxIndex = size() - pageLength;
- if (maxIndex < 0) {
- maxIndex = 0;
- }
-
- if (index > maxIndex) {
- // Note that we pass index, not maxIndex, letting
- // setCurrentPageFirstItemIndex handle the situation.
- setCurrentPageFirstItemIndex(index);
- return;
- }
-
- this.currentPageFirstItemId = currentPageFirstItemId;
- currentPageFirstItemIndex = index;
- }
-
- // Assures the visual refresh
- refreshRowCache();
-
- }
-
- protected int indexOfId(Object itemId) {
- return ((Container.Indexed) items).indexOfId(itemId);
- }
-
- /**
- * Gets the icon Resource for the specified column.
- *
- * @param propertyId
- * the propertyId indentifying the column.
- * @return the icon for the specified column; null if the column has no icon
- * set, or if the column is not visible.
- */
- public Resource getColumnIcon(Object propertyId) {
- return columnIcons.get(propertyId);
- }
-
- /**
- * Sets the icon Resource for the specified column.
- * <p>
- * Throws IllegalArgumentException if the specified column is not visible.
- * </p>
- *
- * @param propertyId
- * the propertyId identifying the column.
- * @param icon
- * the icon Resource to set.
- */
- public void setColumnIcon(Object propertyId, Resource icon) {
-
- if (icon == null) {
- columnIcons.remove(propertyId);
- } else {
- columnIcons.put(propertyId, icon);
- }
-
- requestRepaint();
- }
-
- /**
- * Gets the header for the specified column.
- *
- * @param propertyId
- * the propertyId identifying the column.
- * @return the header for the specified column if it has one.
- */
- public String getColumnHeader(Object propertyId) {
- if (getColumnHeaderMode() == ColumnHeaderMode.HIDDEN) {
- return null;
- }
-
- String header = columnHeaders.get(propertyId);
- if ((header == null && getColumnHeaderMode() == ColumnHeaderMode.EXPLICIT_DEFAULTS_ID)
- || getColumnHeaderMode() == ColumnHeaderMode.ID) {
- header = propertyId.toString();
- }
-
- return header;
- }
-
- /**
- * Sets the column header for the specified column;
- *
- * @param propertyId
- * the propertyId identifying the column.
- * @param header
- * the header to set.
- */
- public void setColumnHeader(Object propertyId, String header) {
-
- if (header == null) {
- columnHeaders.remove(propertyId);
- } else {
- columnHeaders.put(propertyId, header);
- }
-
- requestRepaint();
- }
-
- /**
- * Gets the specified column's alignment.
- *
- * @param propertyId
- * the propertyID identifying the column.
- * @return the specified column's alignment if it as one; null otherwise.
- */
- public Align getColumnAlignment(Object propertyId) {
- final Align a = columnAlignments.get(propertyId);
- return a == null ? Align.LEFT : a;
- }
-
- /**
- * Sets the specified column's alignment.
- *
- * <p>
- * Throws IllegalArgumentException if the alignment is not one of the
- * following: {@link Align#LEFT}, {@link Align#CENTER} or
- * {@link Align#RIGHT}
- * </p>
- *
- * @param propertyId
- * the propertyID identifying the column.
- * @param alignment
- * the desired alignment.
- */
- public void setColumnAlignment(Object propertyId, Align alignment) {
- if (alignment == null || alignment == Align.LEFT) {
- columnAlignments.remove(propertyId);
- } else {
- columnAlignments.put(propertyId, alignment);
- }
-
- // Assures the visual refresh. No need to reset the page buffer before
- // as the content has not changed, only the alignments.
- refreshRenderedCells();
- }
-
- /**
- * Checks if the specified column is collapsed.
- *
- * @param propertyId
- * the propertyID identifying the column.
- * @return true if the column is collapsed; false otherwise;
- */
- public boolean isColumnCollapsed(Object propertyId) {
- return collapsedColumns != null
- && collapsedColumns.contains(propertyId);
- }
-
- /**
- * Sets whether the specified column is collapsed or not.
- *
- *
- * @param propertyId
- * the propertyID identifying the column.
- * @param collapsed
- * the desired collapsedness.
- * @throws IllegalStateException
- * if column collapsing is not allowed
- */
- public void setColumnCollapsed(Object propertyId, boolean collapsed)
- throws IllegalStateException {
- if (!isColumnCollapsingAllowed()) {
- throw new IllegalStateException("Column collapsing not allowed!");
- }
- if (collapsed && noncollapsibleColumns.contains(propertyId)) {
- throw new IllegalStateException("The column is noncollapsible!");
- }
-
- if (collapsed) {
- collapsedColumns.add(propertyId);
- } else {
- collapsedColumns.remove(propertyId);
- }
-
- // Assures the visual refresh
- refreshRowCache();
- }
-
- /**
- * Checks if column collapsing is allowed.
- *
- * @return true if columns can be collapsed; false otherwise.
- */
- public boolean isColumnCollapsingAllowed() {
- return columnCollapsingAllowed;
- }
-
- /**
- * Sets whether column collapsing is allowed or not.
- *
- * @param collapsingAllowed
- * specifies whether column collapsing is allowed.
- */
- public void setColumnCollapsingAllowed(boolean collapsingAllowed) {
- columnCollapsingAllowed = collapsingAllowed;
-
- if (!collapsingAllowed) {
- collapsedColumns.clear();
- }
-
- // Assures the visual refresh. No need to reset the page buffer before
- // as the content has not changed, only the alignments.
- refreshRenderedCells();
- }
-
- /**
- * Sets whether the given column is collapsible. Note that collapsible
- * columns can only be actually collapsed (via UI or with
- * {@link #setColumnCollapsed(Object, boolean) setColumnCollapsed()}) if
- * {@link #isColumnCollapsingAllowed()} is true. By default all columns are
- * collapsible.
- *
- * @param propertyId
- * the propertyID identifying the column.
- * @param collapsible
- * true if the column should be collapsible, false otherwise.
- */
- public void setColumnCollapsible(Object propertyId, boolean collapsible) {
- if (collapsible) {
- noncollapsibleColumns.remove(propertyId);
- } else {
- noncollapsibleColumns.add(propertyId);
- collapsedColumns.remove(propertyId);
- }
- refreshRowCache();
- }
-
- /**
- * Checks if the given column is collapsible. Note that even if this method
- * returns <code>true</code>, the column can only be actually collapsed (via
- * UI or with {@link #setColumnCollapsed(Object, boolean)
- * setColumnCollapsed()}) if {@link #isColumnCollapsingAllowed()} is also
- * true.
- *
- * @return true if the column can be collapsed; false otherwise.
- */
- public boolean isColumnCollapsible(Object propertyId) {
- return !noncollapsibleColumns.contains(propertyId);
- }
-
- /**
- * Checks if column reordering is allowed.
- *
- * @return true if columns can be reordered; false otherwise.
- */
- public boolean isColumnReorderingAllowed() {
- return columnReorderingAllowed;
- }
-
- /**
- * Sets whether column reordering is allowed or not.
- *
- * @param columnReorderingAllowed
- * specifies whether column reordering is allowed.
- */
- public void setColumnReorderingAllowed(boolean columnReorderingAllowed) {
- if (columnReorderingAllowed != this.columnReorderingAllowed) {
- this.columnReorderingAllowed = columnReorderingAllowed;
- requestRepaint();
- }
- }
-
- /*
- * Arranges visible columns according to given columnOrder. Silently ignores
- * colimnId:s that are not visible columns, and keeps the internal order of
- * visible columns left out of the ordering (trailing). Silently does
- * nothing if columnReordering is not allowed.
- */
- private void setColumnOrder(Object[] columnOrder) {
- if (columnOrder == null || !isColumnReorderingAllowed()) {
- return;
- }
- final LinkedList<Object> newOrder = new LinkedList<Object>();
- for (int i = 0; i < columnOrder.length; i++) {
- if (columnOrder[i] != null
- && visibleColumns.contains(columnOrder[i])) {
- visibleColumns.remove(columnOrder[i]);
- newOrder.add(columnOrder[i]);
- }
- }
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext();) {
- final Object columnId = it.next();
- if (!newOrder.contains(columnId)) {
- newOrder.add(columnId);
- }
- }
- visibleColumns = newOrder;
-
- // Assure visual refresh
- refreshRowCache();
- }
-
- /**
- * Getter for property currentPageFirstItem.
- *
- * @return the Value of property currentPageFirstItem.
- */
- public int getCurrentPageFirstItemIndex() {
- return currentPageFirstItemIndex;
- }
-
- void setCurrentPageFirstItemIndex(int newIndex, boolean needsPageBufferReset) {
-
- if (newIndex < 0) {
- newIndex = 0;
- }
-
- /*
- * minimize Container.size() calls which may be expensive. For example
- * it may cause sql query.
- */
- final int size = size();
-
- /*
- * The table is not capable of displaying an item in the container as
- * the first if there are not enough items following the selected item
- * so the whole table (pagelength) is filled.
- */
- int maxIndex = size - pageLength;
- if (maxIndex < 0) {
- maxIndex = 0;
- }
-
- /*
- * FIXME #7607 Take somehow into account the case where we want to
- * scroll to the bottom so that the last row is completely visible even
- * if (table height) / (row height) is not an integer. Reverted the
- * original fix because of #8662 regression.
- */
- if (newIndex > maxIndex) {
- newIndex = maxIndex;
- }
-
- // Refresh first item id
- if (items instanceof Container.Indexed) {
- try {
- currentPageFirstItemId = getIdByIndex(newIndex);
- } catch (final IndexOutOfBoundsException e) {
- currentPageFirstItemId = null;
- }
- currentPageFirstItemIndex = newIndex;
- } else {
-
- // For containers not supporting indexes, we must iterate the
- // container forwards / backwards
- // next available item forward or backward
-
- currentPageFirstItemId = firstItemId();
-
- // Go forwards in the middle of the list (respect borders)
- while (currentPageFirstItemIndex < newIndex
- && !isLastId(currentPageFirstItemId)) {
- currentPageFirstItemIndex++;
- currentPageFirstItemId = nextItemId(currentPageFirstItemId);
- }
-
- // If we did hit the border
- if (isLastId(currentPageFirstItemId)) {
- currentPageFirstItemIndex = size - 1;
- }
-
- // Go backwards in the middle of the list (respect borders)
- while (currentPageFirstItemIndex > newIndex
- && !isFirstId(currentPageFirstItemId)) {
- currentPageFirstItemIndex--;
- currentPageFirstItemId = prevItemId(currentPageFirstItemId);
- }
-
- // If we did hit the border
- if (isFirstId(currentPageFirstItemId)) {
- currentPageFirstItemIndex = 0;
- }
-
- // Go forwards once more
- while (currentPageFirstItemIndex < newIndex
- && !isLastId(currentPageFirstItemId)) {
- currentPageFirstItemIndex++;
- currentPageFirstItemId = nextItemId(currentPageFirstItemId);
- }
-
- // If for some reason we do hit border again, override
- // the user index request
- if (isLastId(currentPageFirstItemId)) {
- newIndex = currentPageFirstItemIndex = size - 1;
- }
- }
- if (needsPageBufferReset) {
- // Assures the visual refresh
- refreshRowCache();
- }
- }
-
- /**
- * Setter for property currentPageFirstItem.
- *
- * @param newIndex
- * the New value of property currentPageFirstItem.
- */
- public void setCurrentPageFirstItemIndex(int newIndex) {
- setCurrentPageFirstItemIndex(newIndex, true);
- }
-
- /**
- * Getter for property pageBuffering.
- *
- * @deprecated functionality is not needed in ajax rendering model
- *
- * @return the Value of property pageBuffering.
- */
- @Deprecated
- public boolean isPageBufferingEnabled() {
- return true;
- }
-
- /**
- * Setter for property pageBuffering.
- *
- * @deprecated functionality is not needed in ajax rendering model
- *
- * @param pageBuffering
- * the New value of property pageBuffering.
- */
- @Deprecated
- public void setPageBufferingEnabled(boolean pageBuffering) {
-
- }
-
- /**
- * Getter for property selectable.
- *
- * <p>
- * The table is not selectable by default.
- * </p>
- *
- * @return the Value of property selectable.
- */
- public boolean isSelectable() {
- return selectable;
- }
-
- /**
- * Setter for property selectable.
- *
- * <p>
- * The table is not selectable by default.
- * </p>
- *
- * @param selectable
- * the New value of property selectable.
- */
- public void setSelectable(boolean selectable) {
- if (this.selectable != selectable) {
- this.selectable = selectable;
- requestRepaint();
- }
- }
-
- /**
- * Getter for property columnHeaderMode.
- *
- * @return the Value of property columnHeaderMode.
- */
- public ColumnHeaderMode getColumnHeaderMode() {
- return columnHeaderMode;
- }
-
- /**
- * Setter for property columnHeaderMode.
- *
- * @param columnHeaderMode
- * the New value of property columnHeaderMode.
- */
- public void setColumnHeaderMode(ColumnHeaderMode columnHeaderMode) {
- if (columnHeaderMode == null) {
- throw new IllegalArgumentException(
- "Column header mode can not be null");
- }
- if (columnHeaderMode != this.columnHeaderMode) {
- this.columnHeaderMode = columnHeaderMode;
- requestRepaint();
- }
-
- }
-
- /**
- * Refreshes the rows in the internal cache. Only if
- * {@link #resetPageBuffer()} is called before this then all values are
- * guaranteed to be recreated.
- */
- protected void refreshRenderedCells() {
- if (getParent() == null) {
- return;
- }
-
- if (!isContentRefreshesEnabled) {
- return;
- }
-
- // Collects the basic facts about the table page
- final int pagelen = getPageLength();
- int rows, totalRows;
- rows = totalRows = size();
- int firstIndex = Math
- .min(getCurrentPageFirstItemIndex(), totalRows - 1);
- if (rows > 0 && firstIndex >= 0) {
- rows -= firstIndex;
- }
- if (pagelen > 0 && pagelen < rows) {
- rows = pagelen;
- }
-
- // If "to be painted next" variables are set, use them
- if (lastToBeRenderedInClient - firstToBeRenderedInClient > 0) {
- rows = lastToBeRenderedInClient - firstToBeRenderedInClient + 1;
- }
- if (firstToBeRenderedInClient >= 0) {
- if (firstToBeRenderedInClient < totalRows) {
- firstIndex = firstToBeRenderedInClient;
- } else {
- firstIndex = totalRows - 1;
- }
- } else {
- // initial load
-
- // #8805 send one extra row in the beginning in case a partial
- // row is shown on the UI
- if (firstIndex > 0) {
- firstIndex = firstIndex - 1;
- rows = rows + 1;
- }
- firstToBeRenderedInClient = firstIndex;
- }
- if (totalRows > 0) {
- if (rows + firstIndex > totalRows) {
- rows = totalRows - firstIndex;
- }
- } else {
- rows = 0;
- }
-
- // Saves the results to internal buffer
- pageBuffer = getVisibleCellsNoCache(firstIndex, rows, true);
-
- if (rows > 0) {
- pageBufferFirstIndex = firstIndex;
- }
-
- setRowCacheInvalidated(true);
- requestRepaint();
- }
-
- /**
- * Requests that the Table should be repainted as soon as possible.
- *
- * Note that a {@code Table} does not necessarily repaint its contents when
- * this method has been called. See {@link #refreshRowCache()} for forcing
- * an update of the contents.
- */
-
- @Override
- public void requestRepaint() {
- // Overridden only for javadoc
- super.requestRepaint();
- }
-
- @Override
- public void requestRepaintAll() {
- super.requestRepaintAll();
-
- // Avoid sending a partial repaint (#8714)
- refreshRowCache();
- }
-
- private void removeRowsFromCacheAndFillBottom(int firstIndex, int rows) {
- int totalCachedRows = pageBuffer[CELL_ITEMID].length;
- int totalRows = size();
- int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex;
-
- /*
- * firstIndexInPageBuffer is the first row to be removed. "rows" rows
- * after that should be removed. If the page buffer does not contain
- * that many rows, we only remove the rows that actually are in the page
- * buffer.
- */
- if (firstIndexInPageBuffer + rows > totalCachedRows) {
- rows = totalCachedRows - firstIndexInPageBuffer;
- }
-
- /*
- * Unregister components that will no longer be in the page buffer to
- * make sure that no components leak.
- */
- unregisterComponentsAndPropertiesInRows(firstIndex, rows);
-
- /*
- * The number of rows that should be in the cache after this operation
- * is done (pageBuffer currently contains the expanded items).
- */
- int newCachedRowCount = totalCachedRows;
- if (newCachedRowCount + pageBufferFirstIndex > totalRows) {
- newCachedRowCount = totalRows - pageBufferFirstIndex;
- }
-
- /*
- * The index at which we should render the first row that does not come
- * from the previous page buffer.
- */
- int firstAppendedRowInPageBuffer = totalCachedRows - rows;
- int firstAppendedRow = firstAppendedRowInPageBuffer
- + pageBufferFirstIndex;
-
- /*
- * Calculate the maximum number of new rows that we can add to the page
- * buffer. Less than the rows we removed if the container does not
- * contain that many items afterwards.
- */
- int maxRowsToRender = (totalRows - firstAppendedRow);
- int rowsToAdd = rows;
- if (rowsToAdd > maxRowsToRender) {
- rowsToAdd = maxRowsToRender;
- }
-
- Object[][] cells = null;
- if (rowsToAdd > 0) {
- cells = getVisibleCellsNoCache(firstAppendedRow, rowsToAdd, false);
- }
- /*
- * Create the new cache buffer by copying the first rows from the old
- * buffer, moving the following rows upwards and appending more rows if
- * applicable.
- */
- Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount];
-
- for (int i = 0; i < pageBuffer.length; i++) {
- for (int row = 0; row < firstIndexInPageBuffer; row++) {
- // Copy the first rows
- newPageBuffer[i][row] = pageBuffer[i][row];
- }
- for (int row = firstIndexInPageBuffer; row < firstAppendedRowInPageBuffer; row++) {
- // Move the rows that were after the expanded rows
- newPageBuffer[i][row] = pageBuffer[i][row + rows];
- }
- for (int row = firstAppendedRowInPageBuffer; row < newCachedRowCount; row++) {
- // Add the newly rendered rows. Only used if rowsToAdd > 0
- // (cells != null)
- newPageBuffer[i][row] = cells[i][row
- - firstAppendedRowInPageBuffer];
- }
- }
- pageBuffer = newPageBuffer;
- }
-
- private Object[][] getVisibleCellsUpdateCacheRows(int firstIndex, int rows) {
- Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false);
- int cacheIx = firstIndex - pageBufferFirstIndex;
- // update the new rows in the cache.
- int totalCachedRows = pageBuffer[CELL_ITEMID].length;
- int end = Math.min(cacheIx + rows, totalCachedRows);
- for (int ix = cacheIx; ix < end; ix++) {
- for (int i = 0; i < pageBuffer.length; i++) {
- pageBuffer[i][ix] = cells[i][ix - cacheIx];
- }
- }
- return cells;
- }
-
- /**
- * @param firstIndex
- * The position where new rows should be inserted
- * @param rows
- * The maximum number of rows that should be inserted at position
- * firstIndex. Less rows will be inserted if the page buffer is
- * too small.
- * @return
- */
- private Object[][] getVisibleCellsInsertIntoCache(int firstIndex, int rows) {
- getLogger().finest(
- "Insert " + rows + " rows at index " + firstIndex
- + " to existing page buffer requested");
-
- // Page buffer must not become larger than pageLength*cacheRate before
- // or after the current page
- int minPageBufferIndex = getCurrentPageFirstItemIndex()
- - (int) (getPageLength() * getCacheRate());
- if (minPageBufferIndex < 0) {
- minPageBufferIndex = 0;
- }
-
- int maxPageBufferIndex = getCurrentPageFirstItemIndex()
- + (int) (getPageLength() * (1 + getCacheRate()));
- int maxBufferSize = maxPageBufferIndex - minPageBufferIndex;
-
- if (getPageLength() == 0) {
- // If pageLength == 0 then all rows should be rendered
- maxBufferSize = pageBuffer[0].length + rows;
- }
- /*
- * Number of rows that were previously cached. This is not necessarily
- * the same as pageLength if we do not have enough rows in the
- * container.
- */
- int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length;
-
- /*
- * firstIndexInPageBuffer is the offset in pageBuffer where the new rows
- * will be inserted (firstIndex is the index in the whole table).
- *
- * E.g. scrolled down to row 1000: firstIndex==1010,
- * pageBufferFirstIndex==1000 -> cacheIx==10
- */
- int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex;
-
- /* If rows > size available in page buffer */
- if (firstIndexInPageBuffer + rows > maxBufferSize) {
- rows = maxBufferSize - firstIndexInPageBuffer;
- }
-
- /*
- * "rows" rows will be inserted at firstIndex. Find out how many old
- * rows fall outside the new buffer so we can unregister components in
- * the cache.
- */
-
- /* All rows until the insertion point remain, always. */
- int firstCacheRowToRemoveInPageBuffer = firstIndexInPageBuffer;
-
- /*
- * IF there is space remaining in the buffer after the rows have been
- * inserted, we can keep more rows.
- */
- int numberOfOldRowsAfterInsertedRows = maxBufferSize
- - firstIndexInPageBuffer - rows;
- if (numberOfOldRowsAfterInsertedRows > 0) {
- firstCacheRowToRemoveInPageBuffer += numberOfOldRowsAfterInsertedRows;
- }
-
- if (firstCacheRowToRemoveInPageBuffer <= currentlyCachedRowCount) {
- /*
- * Unregister all components that fall beyond the cache limits after
- * inserting the new rows.
- */
- unregisterComponentsAndPropertiesInRows(
- firstCacheRowToRemoveInPageBuffer + pageBufferFirstIndex,
- currentlyCachedRowCount - firstCacheRowToRemoveInPageBuffer
- + pageBufferFirstIndex);
- }
-
- // Calculate the new cache size
- int newCachedRowCount = currentlyCachedRowCount;
- if (maxBufferSize == 0 || currentlyCachedRowCount < maxBufferSize) {
- newCachedRowCount = currentlyCachedRowCount + rows;
- if (maxBufferSize > 0 && newCachedRowCount > maxBufferSize) {
- newCachedRowCount = maxBufferSize;
- }
- }
-
- /* Paint the new rows into a separate buffer */
- Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false);
-
- /*
- * Create the new cache buffer and fill it with the data from the old
- * buffer as well as the inserted rows.
- */
- Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount];
-
- for (int i = 0; i < pageBuffer.length; i++) {
- for (int row = 0; row < firstIndexInPageBuffer; row++) {
- // Copy the first rows
- newPageBuffer[i][row] = pageBuffer[i][row];
- }
- for (int row = firstIndexInPageBuffer; row < firstIndexInPageBuffer
- + rows; row++) {
- // Copy the newly created rows
- newPageBuffer[i][row] = cells[i][row - firstIndexInPageBuffer];
- }
- for (int row = firstIndexInPageBuffer + rows; row < newCachedRowCount; row++) {
- // Move the old rows down below the newly inserted rows
- newPageBuffer[i][row] = pageBuffer[i][row - rows];
- }
- }
- pageBuffer = newPageBuffer;
- getLogger().finest(
- "Page Buffer now contains "
- + pageBuffer[CELL_ITEMID].length
- + " rows ("
- + pageBufferFirstIndex
- + "-"
- + (pageBufferFirstIndex
- + pageBuffer[CELL_ITEMID].length - 1) + ")");
- return cells;
- }
-
- /**
- * Render rows with index "firstIndex" to "firstIndex+rows-1" to a new
- * buffer.
- *
- * Reuses values from the current page buffer if the rows are found there.
- *
- * @param firstIndex
- * @param rows
- * @param replaceListeners
- * @return
- */
- private Object[][] getVisibleCellsNoCache(int firstIndex, int rows,
- boolean replaceListeners) {
- getLogger().finest(
- "Render visible cells for rows " + firstIndex + "-"
- + (firstIndex + rows - 1));
- final Object[] colids = getVisibleColumns();
- final int cols = colids.length;
-
- HashSet<Property<?>> oldListenedProperties = listenedProperties;
- HashSet<Component> oldVisibleComponents = visibleComponents;
-
- if (replaceListeners) {
- // initialize the listener collections, this should only be done if
- // the entire cache is refreshed (through refreshRenderedCells)
- listenedProperties = new HashSet<Property<?>>();
- visibleComponents = new HashSet<Component>();
- }
-
- Object[][] cells = new Object[cols + CELL_FIRSTCOL][rows];
- if (rows == 0) {
- unregisterPropertiesAndComponents(oldListenedProperties,
- oldVisibleComponents);
- return cells;
- }
-
- // Gets the first item id
- Object id;
- if (items instanceof Container.Indexed) {
- id = getIdByIndex(firstIndex);
- } else {
- id = firstItemId();
- for (int i = 0; i < firstIndex; i++) {
- id = nextItemId(id);
- }
- }
-
- final RowHeaderMode headmode = getRowHeaderMode();
- final boolean[] iscomponent = new boolean[cols];
- for (int i = 0; i < cols; i++) {
- iscomponent[i] = columnGenerators.containsKey(colids[i])
- || Component.class.isAssignableFrom(getType(colids[i]));
- }
- int firstIndexNotInCache;
- if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) {
- firstIndexNotInCache = pageBufferFirstIndex
- + pageBuffer[CELL_ITEMID].length;
- } else {
- firstIndexNotInCache = -1;
- }
-
- // Creates the page contents
- int filledRows = 0;
- for (int i = 0; i < rows && id != null; i++) {
- cells[CELL_ITEMID][i] = id;
- cells[CELL_KEY][i] = itemIdMapper.key(id);
- if (headmode != ROW_HEADER_MODE_HIDDEN) {
- switch (headmode) {
- case INDEX:
- cells[CELL_HEADER][i] = String.valueOf(i + firstIndex + 1);
- break;
- default:
- cells[CELL_HEADER][i] = getItemCaption(id);
- }
- cells[CELL_ICON][i] = getItemIcon(id);
- }
-
- GeneratedRow generatedRow = rowGenerator != null ? rowGenerator
- .generateRow(this, id) : null;
- cells[CELL_GENERATED_ROW][i] = generatedRow;
-
- for (int j = 0; j < cols; j++) {
- if (isColumnCollapsed(colids[j])) {
- continue;
- }
- Property<?> p = null;
- Object value = "";
- boolean isGeneratedRow = generatedRow != null;
- boolean isGeneratedColumn = columnGenerators
- .containsKey(colids[j]);
- boolean isGenerated = isGeneratedRow || isGeneratedColumn;
-
- if (!isGenerated) {
- p = getContainerProperty(id, colids[j]);
- }
-
- if (isGeneratedRow) {
- if (generatedRow.isSpanColumns() && j > 0) {
- value = null;
- } else if (generatedRow.isSpanColumns() && j == 0
- && generatedRow.getValue() instanceof Component) {
- value = generatedRow.getValue();
- } else if (generatedRow.getText().length > j) {
- value = generatedRow.getText()[j];
- }
- } else {
- // check in current pageBuffer already has row
- int index = firstIndex + i;
- if (p != null || isGenerated) {
- int indexInOldBuffer = index - pageBufferFirstIndex;
- if (index < firstIndexNotInCache
- && index >= pageBufferFirstIndex
- && pageBuffer[CELL_GENERATED_ROW][indexInOldBuffer] == null
- && id.equals(pageBuffer[CELL_ITEMID][indexInOldBuffer])) {
- // we already have data in our cache,
- // recycle it instead of fetching it via
- // getValue/getPropertyValue
- value = pageBuffer[CELL_FIRSTCOL + j][indexInOldBuffer];
- if (!isGeneratedColumn && iscomponent[j]
- || !(value instanceof Component)) {
- listenProperty(p, oldListenedProperties);
- }
- } else {
- if (isGeneratedColumn) {
- ColumnGenerator cg = columnGenerators
- .get(colids[j]);
- value = cg.generateCell(this, id, colids[j]);
- if (value != null
- && !(value instanceof Component)
- && !(value instanceof String)) {
- // Avoid errors if a generator returns
- // something
- // other than a Component or a String
- value = value.toString();
- }
- } else if (iscomponent[j]) {
- value = p.getValue();
- listenProperty(p, oldListenedProperties);
- } else if (p != null) {
- value = getPropertyValue(id, colids[j], p);
- /*
- * If returned value is Component (via
- * fieldfactory or overridden getPropertyValue)
- * we excpect it to listen property value
- * changes. Otherwise if property emits value
- * change events, table will start to listen
- * them and refresh content when needed.
- */
- if (!(value instanceof Component)) {
- listenProperty(p, oldListenedProperties);
- }
- } else {
- value = getPropertyValue(id, colids[j], null);
- }
- }
- }
- }
-
- if (value instanceof Component) {
- registerComponent((Component) value);
- }
- cells[CELL_FIRSTCOL + j][i] = value;
- }
-
- // Gets the next item id
- if (items instanceof Container.Indexed) {
- int index = firstIndex + i + 1;
- if (index < size()) {
- id = getIdByIndex(index);
- } else {
- id = null;
- }
- } else {
- id = nextItemId(id);
- }
-
- filledRows++;
- }
-
- // Assures that all the rows of the cell-buffer are valid
- if (filledRows != cells[0].length) {
- final Object[][] temp = new Object[cells.length][filledRows];
- for (int i = 0; i < cells.length; i++) {
- for (int j = 0; j < filledRows; j++) {
- temp[i][j] = cells[i][j];
- }
- }
- cells = temp;
- }
-
- unregisterPropertiesAndComponents(oldListenedProperties,
- oldVisibleComponents);
-
- return cells;
- }
-
- protected void registerComponent(Component component) {
- getLogger().finest(
- "Registered " + component.getClass().getSimpleName() + ": "
- + component.getCaption());
- if (component.getParent() != this) {
- component.setParent(this);
- }
- visibleComponents.add(component);
- }
-
- private void listenProperty(Property<?> p,
- HashSet<Property<?>> oldListenedProperties) {
- if (p instanceof Property.ValueChangeNotifier) {
- if (oldListenedProperties == null
- || !oldListenedProperties.contains(p)) {
- ((Property.ValueChangeNotifier) p).addListener(this);
- }
- /*
- * register listened properties, so we can do proper cleanup to free
- * memory. Essential if table has loads of data and it is used for a
- * long time.
- */
- listenedProperties.add(p);
-
- }
- }
-
- /**
- * @param firstIx
- * Index of the first row to process. Global index, not relative
- * to page buffer.
- * @param count
- */
- private void unregisterComponentsAndPropertiesInRows(int firstIx, int count) {
- getLogger().finest(
- "Unregistering components in rows " + firstIx + "-"
- + (firstIx + count - 1));
- Object[] colids = getVisibleColumns();
- if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) {
- int bufSize = pageBuffer[CELL_ITEMID].length;
- int ix = firstIx - pageBufferFirstIndex;
- ix = ix < 0 ? 0 : ix;
- if (ix < bufSize) {
- count = count > bufSize - ix ? bufSize - ix : count;
- for (int i = 0; i < count; i++) {
- for (int c = 0; c < colids.length; c++) {
- Object cellVal = pageBuffer[CELL_FIRSTCOL + c][i + ix];
- if (cellVal instanceof Component
- && visibleComponents.contains(cellVal)) {
- visibleComponents.remove(cellVal);
- unregisterComponent((Component) cellVal);
- } else {
- Property<?> p = getContainerProperty(
- pageBuffer[CELL_ITEMID][i + ix], colids[c]);
- if (p instanceof ValueChangeNotifier
- && listenedProperties.contains(p)) {
- listenedProperties.remove(p);
- ((ValueChangeNotifier) p).removeListener(this);
- }
- }
- }
- }
- }
- }
- }
-
- /**
- * Helper method to remove listeners and maintain correct component
- * hierarchy. Detaches properties and components if those are no more
- * rendered in client.
- *
- * @param oldListenedProperties
- * set of properties that where listened in last render
- * @param oldVisibleComponents
- * set of components that where attached in last render
- */
- private void unregisterPropertiesAndComponents(
- HashSet<Property<?>> oldListenedProperties,
- HashSet<Component> oldVisibleComponents) {
- if (oldVisibleComponents != null) {
- for (final Iterator<Component> i = oldVisibleComponents.iterator(); i
- .hasNext();) {
- Component c = i.next();
- if (!visibleComponents.contains(c)) {
- unregisterComponent(c);
- }
- }
- }
-
- if (oldListenedProperties != null) {
- for (final Iterator<Property<?>> i = oldListenedProperties
- .iterator(); i.hasNext();) {
- Property.ValueChangeNotifier o = (ValueChangeNotifier) i.next();
- if (!listenedProperties.contains(o)) {
- o.removeListener(this);
- }
- }
- }
- }
-
- /**
- * This method cleans up a Component that has been generated when Table is
- * in editable mode. The component needs to be detached from its parent and
- * if it is a field, it needs to be detached from its property data source
- * in order to allow garbage collection to take care of removing the unused
- * component from memory.
- *
- * Override this method and getPropertyValue(Object, Object, Property) with
- * custom logic if you need to deal with buffered fields.
- *
- * @see #getPropertyValue(Object, Object, Property)
- *
- * @param oldVisibleComponents
- * a set of components that should be unregistered.
- */
- protected void unregisterComponent(Component component) {
- getLogger().finest(
- "Unregistered " + component.getClass().getSimpleName() + ": "
- + component.getCaption());
- component.setParent(null);
- /*
- * Also remove property data sources to unregister listeners keeping the
- * fields in memory.
- */
- if (component instanceof Field) {
- Field<?> field = (Field<?>) component;
- Property<?> associatedProperty = associatedProperties
- .remove(component);
- if (associatedProperty != null
- && field.getPropertyDataSource() == associatedProperty) {
- // Remove the property data source only if it's the one we
- // added in getPropertyValue
- field.setPropertyDataSource(null);
- }
- }
- }
-
- /**
- * Refreshes the current page contents.
- *
- * @deprecated should not need to be used
- */
- @Deprecated
- public void refreshCurrentPage() {
-
- }
-
- /**
- * Sets the row header mode.
- * <p>
- * The mode can be one of the following ones:
- * <ul>
- * <li>{@link #ROW_HEADER_MODE_HIDDEN}: The row captions are hidden.</li>
- * <li>{@link #ROW_HEADER_MODE_ID}: Items Id-objects <code>toString()</code>
- * is used as row caption.
- * <li>{@link #ROW_HEADER_MODE_ITEM}: Item-objects <code>toString()</code>
- * is used as row caption.
- * <li>{@link #ROW_HEADER_MODE_PROPERTY}: Property set with
- * {@link #setItemCaptionPropertyId(Object)} is used as row header.
- * <li>{@link #ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID}: Items Id-objects
- * <code>toString()</code> is used as row header. If caption is explicitly
- * specified, it overrides the id-caption.
- * <li>{@link #ROW_HEADER_MODE_EXPLICIT}: The row headers must be explicitly
- * specified.</li>
- * <li>{@link #ROW_HEADER_MODE_INDEX}: The index of the item is used as row
- * caption. The index mode can only be used with the containers implementing
- * <code>Container.Indexed</code> interface.</li>
- * </ul>
- * The default value is {@link #ROW_HEADER_MODE_HIDDEN}
- * </p>
- *
- * @param mode
- * the One of the modes listed above.
- */
- public void setRowHeaderMode(RowHeaderMode mode) {
- if (mode != null) {
- rowHeaderMode = mode;
- if (mode != RowHeaderMode.HIDDEN) {
- setItemCaptionMode(mode.getItemCaptionMode());
- }
- // Assures the visual refresh. No need to reset the page buffer
- // before
- // as the content has not changed, only the alignments.
- refreshRenderedCells();
- }
- }
-
- /**
- * Gets the row header mode.
- *
- * @return the Row header mode.
- * @see #setRowHeaderMode(int)
- */
- public RowHeaderMode getRowHeaderMode() {
- return rowHeaderMode;
- }
-
- /**
- * Adds the new row to table and fill the visible cells (except generated
- * columns) with given values.
- *
- * @param cells
- * the Object array that is used for filling the visible cells
- * new row. The types must be settable to visible column property
- * types.
- * @param itemId
- * the Id the new row. If null, a new id is automatically
- * assigned. If given, the table cant already have a item with
- * given id.
- * @return Returns item id for the new row. Returns null if operation fails.
- */
- public Object addItem(Object[] cells, Object itemId)
- throws UnsupportedOperationException {
-
- // remove generated columns from the list of columns being assigned
- final LinkedList<Object> availableCols = new LinkedList<Object>();
- for (Iterator<Object> it = visibleColumns.iterator(); it.hasNext();) {
- Object id = it.next();
- if (!columnGenerators.containsKey(id)) {
- availableCols.add(id);
- }
- }
- // Checks that a correct number of cells are given
- if (cells.length != availableCols.size()) {
- return null;
- }
-
- // Creates new item
- Item item;
- if (itemId == null) {
- itemId = items.addItem();
- if (itemId == null) {
- return null;
- }
- item = items.getItem(itemId);
- } else {
- item = items.addItem(itemId);
- }
- if (item == null) {
- return null;
- }
-
- // Fills the item properties
- for (int i = 0; i < availableCols.size(); i++) {
- item.getItemProperty(availableCols.get(i)).setValue(cells[i]);
- }
-
- if (!(items instanceof Container.ItemSetChangeNotifier)) {
- refreshRowCache();
- }
-
- return itemId;
- }
-
- /**
- * Discards and recreates the internal row cache. Call this if you make
- * changes that affect the rows but the information about the changes are
- * not automatically propagated to the Table.
- * <p>
- * Do not call this e.g. if you have updated the data model through a
- * Property. These types of changes are automatically propagated to the
- * Table.
- * <p>
- * A typical case when this is needed is if you update a generator (e.g.
- * CellStyleGenerator) and want to ensure that the rows are redrawn with new
- * styles.
- * <p>
- * <i>Note that calling this method is not cheap so avoid calling it
- * unnecessarily.</i>
- *
- * @since 6.7.2
- */
- public void refreshRowCache() {
- resetPageBuffer();
- refreshRenderedCells();
- }
-
- @Override
- public void setContainerDataSource(Container newDataSource) {
-
- disableContentRefreshing();
-
- if (newDataSource == null) {
- newDataSource = new IndexedContainer();
- }
-
- // Assures that the data source is ordered by making unordered
- // containers ordered by wrapping them
- if (newDataSource instanceof Container.Ordered) {
- super.setContainerDataSource(newDataSource);
- } else {
- super.setContainerDataSource(new ContainerOrderedWrapper(
- newDataSource));
- }
-
- // Resets page position
- currentPageFirstItemId = null;
- currentPageFirstItemIndex = 0;
-
- // Resets column properties
- if (collapsedColumns != null) {
- collapsedColumns.clear();
- }
-
- // columnGenerators 'override' properties, don't add the same id twice
- Collection<Object> col = new LinkedList<Object>();
- for (Iterator<?> it = getContainerPropertyIds().iterator(); it
- .hasNext();) {
- Object id = it.next();
- if (columnGenerators == null || !columnGenerators.containsKey(id)) {
- col.add(id);
- }
- }
- // generators added last
- if (columnGenerators != null && columnGenerators.size() > 0) {
- col.addAll(columnGenerators.keySet());
- }
-
- setVisibleColumns(col.toArray());
-
- // Assure visual refresh
- resetPageBuffer();
-
- enableContentRefreshing(true);
- }
-
- /**
- * Gets items ids from a range of key values
- *
- * @param startRowKey
- * The start key
- * @param endRowKey
- * The end key
- * @return
- */
- private LinkedHashSet<Object> getItemIdsInRange(Object itemId,
- final int length) {
- LinkedHashSet<Object> ids = new LinkedHashSet<Object>();
- for (int i = 0; i < length; i++) {
- assert itemId != null; // should not be null unless client-server
- // are out of sync
- ids.add(itemId);
- itemId = nextItemId(itemId);
- }
- return ids;
- }
-
- /**
- * Handles selection if selection is a multiselection
- *
- * @param variables
- * The variables
- */
- private void handleSelectedItems(Map<String, Object> variables) {
- final String[] ka = (String[]) variables.get("selected");
- final String[] ranges = (String[]) variables.get("selectedRanges");
-
- Set<Object> renderedButNotSelectedItemIds = getCurrentlyRenderedItemIds();
-
- @SuppressWarnings("unchecked")
- HashSet<Object> newValue = new LinkedHashSet<Object>(
- (Collection<Object>) getValue());
-
- if (variables.containsKey("clearSelections")) {
- // the client side has instructed to swipe all previous selections
- newValue.clear();
- }
-
- /*
- * Then add (possibly some of them back) rows that are currently
- * selected on the client side (the ones that the client side is aware
- * of).
- */
- for (int i = 0; i < ka.length; i++) {
- // key to id
- final Object id = itemIdMapper.get(ka[i]);
- if (!isNullSelectionAllowed()
- && (id == null || id == getNullSelectionItemId())) {
- // skip empty selection if nullselection is not allowed
- requestRepaint();
- } else if (id != null && containsId(id)) {
- newValue.add(id);
- renderedButNotSelectedItemIds.remove(id);
- }
- }
-
- /* Add range items aka shift clicked multiselection areas */
- if (ranges != null) {
- for (String range : ranges) {
- String[] split = range.split("-");
- Object startItemId = itemIdMapper.get(split[0]);
- int length = Integer.valueOf(split[1]);
- LinkedHashSet<Object> itemIdsInRange = getItemIdsInRange(
- startItemId, length);
- newValue.addAll(itemIdsInRange);
- renderedButNotSelectedItemIds.removeAll(itemIdsInRange);
- }
- }
- /*
- * finally clear all currently rendered rows (the ones that the client
- * side counterpart is aware of) that the client didn't send as selected
- */
- newValue.removeAll(renderedButNotSelectedItemIds);
-
- if (!isNullSelectionAllowed() && newValue.isEmpty()) {
- // empty selection not allowed, keep old value
- requestRepaint();
- return;
- }
-
- setValue(newValue, true);
-
- }
-
- private Set<Object> getCurrentlyRenderedItemIds() {
- HashSet<Object> ids = new HashSet<Object>();
- if (pageBuffer != null) {
- for (int i = 0; i < pageBuffer[CELL_ITEMID].length; i++) {
- ids.add(pageBuffer[CELL_ITEMID][i]);
- }
- }
- return ids;
- }
-
- /* Component basics */
-
- /**
- * Invoked when the value of a variable has changed.
- *
- * @see com.vaadin.ui.Select#changeVariables(java.lang.Object,
- * java.util.Map)
- */
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
-
- boolean clientNeedsContentRefresh = false;
-
- handleClickEvent(variables);
-
- handleColumnResizeEvent(variables);
-
- handleColumnWidthUpdates(variables);
-
- disableContentRefreshing();
-
- if (!isSelectable() && variables.containsKey("selected")) {
- // Not-selectable is a special case, AbstractSelect does not support
- // TODO could be optimized.
- variables = new HashMap<String, Object>(variables);
- variables.remove("selected");
- }
-
- /*
- * The AbstractSelect cannot handle the multiselection properly, instead
- * we handle it ourself
- */
- else if (isSelectable() && isMultiSelect()
- && variables.containsKey("selected")
- && multiSelectMode == MultiSelectMode.DEFAULT) {
- handleSelectedItems(variables);
- variables = new HashMap<String, Object>(variables);
- variables.remove("selected");
- }
-
- super.changeVariables(source, variables);
-
- // Client might update the pagelength if Table height is fixed
- if (variables.containsKey("pagelength")) {
- // Sets pageLength directly to avoid repaint that setter causes
- pageLength = (Integer) variables.get("pagelength");
- }
-
- // Page start index
- if (variables.containsKey("firstvisible")) {
- final Integer value = (Integer) variables.get("firstvisible");
- if (value != null) {
- setCurrentPageFirstItemIndex(value.intValue(), false);
- }
- }
-
- // Sets requested firstrow and rows for the next paint
- if (variables.containsKey("reqfirstrow")
- || variables.containsKey("reqrows")) {
-
- try {
- firstToBeRenderedInClient = ((Integer) variables
- .get("firstToBeRendered")).intValue();
- lastToBeRenderedInClient = ((Integer) variables
- .get("lastToBeRendered")).intValue();
- } catch (Exception e) {
- // FIXME: Handle exception
- getLogger().log(Level.FINER,
- "Could not parse the first and/or last rows.", e);
- }
-
- // respect suggested rows only if table is not otherwise updated
- // (row caches emptied by other event)
- if (!containerChangeToBeRendered) {
- Integer value = (Integer) variables.get("reqfirstrow");
- if (value != null) {
- reqFirstRowToPaint = value.intValue();
- }
- value = (Integer) variables.get("reqrows");
- if (value != null) {
- reqRowsToPaint = value.intValue();
- // sanity check
- if (reqFirstRowToPaint + reqRowsToPaint > size()) {
- reqRowsToPaint = size() - reqFirstRowToPaint;
- }
- }
- }
- getLogger().finest(
- "Client wants rows " + reqFirstRowToPaint + "-"
- + (reqFirstRowToPaint + reqRowsToPaint - 1));
- clientNeedsContentRefresh = true;
- }
-
- if (isSortEnabled()) {
- // Sorting
- boolean doSort = false;
- if (variables.containsKey("sortcolumn")) {
- final String colId = (String) variables.get("sortcolumn");
- if (colId != null && !"".equals(colId) && !"null".equals(colId)) {
- final Object id = columnIdMap.get(colId);
- setSortContainerPropertyId(id, false);
- doSort = true;
- }
- }
- if (variables.containsKey("sortascending")) {
- final boolean state = ((Boolean) variables.get("sortascending"))
- .booleanValue();
- if (state != sortAscending) {
- setSortAscending(state, false);
- doSort = true;
- }
- }
- if (doSort) {
- this.sort();
- resetPageBuffer();
- }
- }
-
- // Dynamic column hide/show and order
- // Update visible columns
- if (isColumnCollapsingAllowed()) {
- if (variables.containsKey("collapsedcolumns")) {
- try {
- final Object[] ids = (Object[]) variables
- .get("collapsedcolumns");
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext();) {
- setColumnCollapsed(it.next(), false);
- }
- for (int i = 0; i < ids.length; i++) {
- setColumnCollapsed(columnIdMap.get(ids[i].toString()),
- true);
- }
- } catch (final Exception e) {
- // FIXME: Handle exception
- getLogger().log(Level.FINER,
- "Could not determine column collapsing state", e);
- }
- clientNeedsContentRefresh = true;
- }
- }
- if (isColumnReorderingAllowed()) {
- if (variables.containsKey("columnorder")) {
- try {
- final Object[] ids = (Object[]) variables
- .get("columnorder");
- // need a real Object[], ids can be a String[]
- final Object[] idsTemp = new Object[ids.length];
- for (int i = 0; i < ids.length; i++) {
- idsTemp[i] = columnIdMap.get(ids[i].toString());
- }
- setColumnOrder(idsTemp);
- if (hasListeners(ColumnReorderEvent.class)) {
- fireEvent(new ColumnReorderEvent(this));
- }
- } catch (final Exception e) {
- // FIXME: Handle exception
- getLogger().log(Level.FINER,
- "Could not determine column reordering state", e);
- }
- clientNeedsContentRefresh = true;
- }
- }
-
- enableContentRefreshing(clientNeedsContentRefresh);
-
- // Actions
- if (variables.containsKey("action")) {
- final StringTokenizer st = new StringTokenizer(
- (String) variables.get("action"), ",");
- if (st.countTokens() == 2) {
- final Object itemId = itemIdMapper.get(st.nextToken());
- final Action action = actionMapper.get(st.nextToken());
-
- if (action != null && (itemId == null || containsId(itemId))
- && actionHandlers != null) {
- for (Handler ah : actionHandlers) {
- ah.handleAction(action, this, itemId);
- }
- }
- }
- }
-
- }
-
- /**
- * Handles click event
- *
- * @param variables
- */
- private void handleClickEvent(Map<String, Object> variables) {
-
- // Item click event
- if (variables.containsKey("clickEvent")) {
- String key = (String) variables.get("clickedKey");
- Object itemId = itemIdMapper.get(key);
- Object propertyId = null;
- String colkey = (String) variables.get("clickedColKey");
- // click is not necessary on a property
- if (colkey != null) {
- propertyId = columnIdMap.get(colkey);
- }
- MouseEventDetails evt = MouseEventDetails
- .deSerialize((String) variables.get("clickEvent"));
- Item item = getItem(itemId);
- if (item != null) {
- fireEvent(new ItemClickEvent(this, item, itemId, propertyId,
- evt));
- }
- }
-
- // Header click event
- else if (variables.containsKey("headerClickEvent")) {
-
- MouseEventDetails details = MouseEventDetails
- .deSerialize((String) variables.get("headerClickEvent"));
-
- Object cid = variables.get("headerClickCID");
- Object propertyId = null;
- if (cid != null) {
- propertyId = columnIdMap.get(cid.toString());
- }
- fireEvent(new HeaderClickEvent(this, propertyId, details));
- }
-
- // Footer click event
- else if (variables.containsKey("footerClickEvent")) {
- MouseEventDetails details = MouseEventDetails
- .deSerialize((String) variables.get("footerClickEvent"));
-
- Object cid = variables.get("footerClickCID");
- Object propertyId = null;
- if (cid != null) {
- propertyId = columnIdMap.get(cid.toString());
- }
- fireEvent(new FooterClickEvent(this, propertyId, details));
- }
- }
-
- /**
- * Handles the column resize event sent by the client.
- *
- * @param variables
- */
- private void handleColumnResizeEvent(Map<String, Object> variables) {
- if (variables.containsKey("columnResizeEventColumn")) {
- Object cid = variables.get("columnResizeEventColumn");
- Object propertyId = null;
- if (cid != null) {
- propertyId = columnIdMap.get(cid.toString());
-
- Object prev = variables.get("columnResizeEventPrev");
- int previousWidth = -1;
- if (prev != null) {
- previousWidth = Integer.valueOf(prev.toString());
- }
-
- Object curr = variables.get("columnResizeEventCurr");
- int currentWidth = -1;
- if (curr != null) {
- currentWidth = Integer.valueOf(curr.toString());
- }
-
- fireColumnResizeEvent(propertyId, previousWidth, currentWidth);
- }
- }
- }
-
- private void fireColumnResizeEvent(Object propertyId, int previousWidth,
- int currentWidth) {
- /*
- * Update the sizes on the server side. If a column previously had a
- * expand ratio and the user resized the column then the expand ratio
- * will be turned into a static pixel size.
- */
- setColumnWidth(propertyId, currentWidth);
-
- fireEvent(new ColumnResizeEvent(this, propertyId, previousWidth,
- currentWidth));
- }
-
- private void handleColumnWidthUpdates(Map<String, Object> variables) {
- if (variables.containsKey("columnWidthUpdates")) {
- String[] events = (String[]) variables.get("columnWidthUpdates");
- for (String str : events) {
- String[] eventDetails = str.split(":");
- Object propertyId = columnIdMap.get(eventDetails[0]);
- if (propertyId == null) {
- propertyId = ROW_HEADER_FAKE_PROPERTY_ID;
- }
- int width = Integer.valueOf(eventDetails[1]);
- setColumnWidth(propertyId, width);
- }
- }
- }
-
- /**
- * Go to mode where content updates are not done. This is due we want to
- * bypass expensive content for some reason (like when we know we may have
- * other content changes on their way).
- *
- * @return true if content refresh flag was enabled prior this call
- */
- protected boolean disableContentRefreshing() {
- boolean wasDisabled = isContentRefreshesEnabled;
- isContentRefreshesEnabled = false;
- return wasDisabled;
- }
-
- /**
- * Go to mode where content content refreshing has effect.
- *
- * @param refreshContent
- * true if content refresh needs to be done
- */
- protected void enableContentRefreshing(boolean refreshContent) {
- isContentRefreshesEnabled = true;
- if (refreshContent) {
- refreshRenderedCells();
- // Ensure that client gets a response
- requestRepaint();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractSelect#paintContent(com.vaadin.
- * terminal.PaintTarget)
- */
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- /*
- * Body actions - Actions which has the target null and can be invoked
- * by right clicking on the table body.
- */
- final Set<Action> actionSet = findAndPaintBodyActions(target);
-
- final Object[][] cells = getVisibleCells();
- int rows = findNumRowsToPaint(target, cells);
-
- int total = size();
- if (shouldHideNullSelectionItem()) {
- total--;
- rows--;
- }
-
- // Table attributes
- paintTableAttributes(target, rows, total);
-
- paintVisibleColumnOrder(target);
-
- // Rows
- if (isPartialRowUpdate() && painted && !target.isFullRepaint()) {
- paintPartialRowUpdate(target, actionSet);
- /*
- * Send the page buffer indexes to ensure that the client side stays
- * in sync. Otherwise we _might_ have the situation where the client
- * side discards too few or too many rows, causing out of sync
- * issues.
- *
- * This could probably be done for full repaints also to simplify
- * the client side.
- */
- int pageBufferLastIndex = pageBufferFirstIndex
- + pageBuffer[CELL_ITEMID].length - 1;
- target.addAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST,
- pageBufferFirstIndex);
- target.addAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST,
- pageBufferLastIndex);
- } else if (target.isFullRepaint() || isRowCacheInvalidated()) {
- paintRows(target, cells, actionSet);
- setRowCacheInvalidated(false);
- }
-
- paintSorting(target);
-
- resetVariablesAndPageBuffer(target);
-
- // Actions
- paintActions(target, actionSet);
-
- paintColumnOrder(target);
-
- // Available columns
- paintAvailableColumns(target);
-
- paintVisibleColumns(target);
-
- if (keyMapperReset) {
- keyMapperReset = false;
- target.addAttribute(VScrollTable.ATTRIBUTE_KEY_MAPPER_RESET, true);
- }
-
- if (dropHandler != null) {
- dropHandler.getAcceptCriterion().paint(target);
- }
-
- painted = true;
- }
-
- private void setRowCacheInvalidated(boolean invalidated) {
- rowCacheInvalidated = invalidated;
- }
-
- protected boolean isRowCacheInvalidated() {
- return rowCacheInvalidated;
- }
-
- private void paintPartialRowUpdate(PaintTarget target, Set<Action> actionSet)
- throws PaintException {
- paintPartialRowUpdates(target, actionSet);
- paintPartialRowAdditions(target, actionSet);
- }
-
- private void paintPartialRowUpdates(PaintTarget target,
- Set<Action> actionSet) throws PaintException {
- final boolean[] iscomponent = findCellsWithComponents();
-
- int firstIx = getFirstUpdatedItemIndex();
- int count = getUpdatedRowCount();
-
- target.startTag("urows");
- target.addAttribute("firsturowix", firstIx);
- target.addAttribute("numurows", count);
-
- // Partial row updates bypass the normal caching mechanism.
- Object[][] cells = getVisibleCellsUpdateCacheRows(firstIx, count);
- for (int indexInRowbuffer = 0; indexInRowbuffer < count; indexInRowbuffer++) {
- final Object itemId = cells[CELL_ITEMID][indexInRowbuffer];
-
- if (shouldHideNullSelectionItem()) {
- // Remove null selection item if null selection is not allowed
- continue;
- }
-
- paintRow(target, cells, isEditable(), actionSet, iscomponent,
- indexInRowbuffer, itemId);
- }
- target.endTag("urows");
- }
-
- private void paintPartialRowAdditions(PaintTarget target,
- Set<Action> actionSet) throws PaintException {
- final boolean[] iscomponent = findCellsWithComponents();
-
- int firstIx = getFirstAddedItemIndex();
- int count = getAddedRowCount();
-
- target.startTag("prows");
-
- if (!shouldHideAddedRows()) {
- getLogger().finest(
- "Paint rows for add. Index: " + firstIx + ", count: "
- + count + ".");
-
- // Partial row additions bypass the normal caching mechanism.
- Object[][] cells = getVisibleCellsInsertIntoCache(firstIx, count);
- if (cells[0].length < count) {
- // delete the rows below, since they will fall beyond the cache
- // page.
- target.addAttribute("delbelow", true);
- count = cells[0].length;
- }
-
- for (int indexInRowbuffer = 0; indexInRowbuffer < count; indexInRowbuffer++) {
- final Object itemId = cells[CELL_ITEMID][indexInRowbuffer];
- if (shouldHideNullSelectionItem()) {
- // Remove null selection item if null selection is not
- // allowed
- continue;
- }
-
- paintRow(target, cells, isEditable(), actionSet, iscomponent,
- indexInRowbuffer, itemId);
- }
- } else {
- getLogger().finest(
- "Paint rows for remove. Index: " + firstIx + ", count: "
- + count + ".");
- removeRowsFromCacheAndFillBottom(firstIx, count);
- target.addAttribute("hide", true);
- }
-
- target.addAttribute("firstprowix", firstIx);
- target.addAttribute("numprows", count);
- target.endTag("prows");
- }
-
- /**
- * Subclass and override this to enable partial row updates and additions,
- * which bypass the normal caching mechanism. This is useful for e.g.
- * TreeTable.
- *
- * @return true if this update is a partial row update, false if not. For
- * plain Table it is always false.
- */
- protected boolean isPartialRowUpdate() {
- return false;
- }
-
- /**
- * Subclass and override this to enable partial row additions, bypassing the
- * normal caching mechanism. This is useful for e.g. TreeTable, where
- * expanding a node should only fetch and add the items inside of that node.
- *
- * @return The index of the first added item. For plain Table it is always
- * 0.
- */
- protected int getFirstAddedItemIndex() {
- return 0;
- }
-
- /**
- * Subclass and override this to enable partial row additions, bypassing the
- * normal caching mechanism. This is useful for e.g. TreeTable, where
- * expanding a node should only fetch and add the items inside of that node.
- *
- * @return the number of rows to be added, starting at the index returned by
- * {@link #getFirstAddedItemIndex()}. For plain Table it is always
- * 0.
- */
- protected int getAddedRowCount() {
- return 0;
- }
-
- /**
- * Subclass and override this to enable removing of rows, bypassing the
- * normal caching and lazy loading mechanism. This is useful for e.g.
- * TreeTable, when you need to hide certain rows as a node is collapsed.
- *
- * This should return true if the rows pointed to by
- * {@link #getFirstAddedItemIndex()} and {@link #getAddedRowCount()} should
- * be hidden instead of added.
- *
- * @return whether the rows to add (see {@link #getFirstAddedItemIndex()}
- * and {@link #getAddedRowCount()}) should be added or hidden. For
- * plain Table it is always false.
- */
- protected boolean shouldHideAddedRows() {
- return false;
- }
-
- /**
- * Subclass and override this to enable partial row updates, bypassing the
- * normal caching and lazy loading mechanism. This is useful for updating
- * the state of certain rows, e.g. in the TreeTable the collapsed state of a
- * single node is updated using this mechanism.
- *
- * @return the index of the first item to be updated. For plain Table it is
- * always 0.
- */
- protected int getFirstUpdatedItemIndex() {
- return 0;
- }
-
- /**
- * Subclass and override this to enable partial row updates, bypassing the
- * normal caching and lazy loading mechanism. This is useful for updating
- * the state of certain rows, e.g. in the TreeTable the collapsed state of a
- * single node is updated using this mechanism.
- *
- * @return the number of rows to update, starting at the index returned by
- * {@link #getFirstUpdatedItemIndex()}. For plain table it is always
- * 0.
- */
- protected int getUpdatedRowCount() {
- return 0;
- }
-
- private void paintTableAttributes(PaintTarget target, int rows, int total)
- throws PaintException {
- paintTabIndex(target);
- paintDragMode(target);
- paintSelectMode(target);
-
- if (cacheRate != CACHE_RATE_DEFAULT) {
- target.addAttribute("cr", cacheRate);
- }
-
- target.addAttribute("cols", getVisibleColumns().length);
- target.addAttribute("rows", rows);
-
- target.addAttribute("firstrow",
- (reqFirstRowToPaint >= 0 ? reqFirstRowToPaint
- : firstToBeRenderedInClient));
- target.addAttribute("totalrows", total);
- if (getPageLength() != 0) {
- target.addAttribute("pagelength", getPageLength());
- }
- if (areColumnHeadersEnabled()) {
- target.addAttribute("colheaders", true);
- }
- if (rowHeadersAreEnabled()) {
- target.addAttribute("rowheaders", true);
- }
-
- target.addAttribute("colfooters", columnFootersVisible);
-
- // The cursors are only shown on pageable table
- if (getCurrentPageFirstItemIndex() != 0 || getPageLength() > 0) {
- target.addVariable(this, "firstvisible",
- getCurrentPageFirstItemIndex());
- }
- }
-
- /**
- * Resets and paints "to be painted next" variables. Also reset pageBuffer
- */
- private void resetVariablesAndPageBuffer(PaintTarget target)
- throws PaintException {
- reqFirstRowToPaint = -1;
- reqRowsToPaint = -1;
- containerChangeToBeRendered = false;
- target.addVariable(this, "reqrows", reqRowsToPaint);
- target.addVariable(this, "reqfirstrow", reqFirstRowToPaint);
- }
-
- private boolean areColumnHeadersEnabled() {
- return getColumnHeaderMode() != ColumnHeaderMode.HIDDEN;
- }
-
- private void paintVisibleColumns(PaintTarget target) throws PaintException {
- target.startTag("visiblecolumns");
- if (rowHeadersAreEnabled()) {
- target.startTag("column");
- target.addAttribute("cid", ROW_HEADER_COLUMN_KEY);
- paintColumnWidth(target, ROW_HEADER_FAKE_PROPERTY_ID);
- target.endTag("column");
- }
- final Collection<?> sortables = getSortableContainerPropertyIds();
- for (Object colId : visibleColumns) {
- if (colId != null) {
- target.startTag("column");
- target.addAttribute("cid", columnIdMap.key(colId));
- final String head = getColumnHeader(colId);
- target.addAttribute("caption", (head != null ? head : ""));
- final String foot = getColumnFooter(colId);
- target.addAttribute("fcaption", (foot != null ? foot : ""));
- if (isColumnCollapsed(colId)) {
- target.addAttribute("collapsed", true);
- }
- if (areColumnHeadersEnabled()) {
- if (getColumnIcon(colId) != null) {
- target.addAttribute("icon", getColumnIcon(colId));
- }
- if (sortables.contains(colId)) {
- target.addAttribute("sortable", true);
- }
- }
- if (!Align.LEFT.equals(getColumnAlignment(colId))) {
- target.addAttribute("align", getColumnAlignment(colId)
- .toString());
- }
- paintColumnWidth(target, colId);
- target.endTag("column");
- }
- }
- target.endTag("visiblecolumns");
- }
-
- private void paintAvailableColumns(PaintTarget target)
- throws PaintException {
- if (columnCollapsingAllowed) {
- final HashSet<Object> collapsedCols = new HashSet<Object>();
- for (Object colId : visibleColumns) {
- if (isColumnCollapsed(colId)) {
- collapsedCols.add(colId);
- }
- }
- final String[] collapsedKeys = new String[collapsedCols.size()];
- int nextColumn = 0;
- for (Object colId : visibleColumns) {
- if (isColumnCollapsed(colId)) {
- collapsedKeys[nextColumn++] = columnIdMap.key(colId);
- }
- }
- target.addVariable(this, "collapsedcolumns", collapsedKeys);
-
- final String[] noncollapsibleKeys = new String[noncollapsibleColumns
- .size()];
- nextColumn = 0;
- for (Object colId : noncollapsibleColumns) {
- noncollapsibleKeys[nextColumn++] = columnIdMap.key(colId);
- }
- target.addVariable(this, "noncollapsiblecolumns",
- noncollapsibleKeys);
- }
-
- }
-
- private void paintActions(PaintTarget target, final Set<Action> actionSet)
- throws PaintException {
- if (!actionSet.isEmpty()) {
- target.addVariable(this, "action", "");
- target.startTag("actions");
- for (Action a : actionSet) {
- target.startTag("action");
- if (a.getCaption() != null) {
- target.addAttribute("caption", a.getCaption());
- }
- if (a.getIcon() != null) {
- target.addAttribute("icon", a.getIcon());
- }
- target.addAttribute("key", actionMapper.key(a));
- target.endTag("action");
- }
- target.endTag("actions");
- }
- }
-
- private void paintColumnOrder(PaintTarget target) throws PaintException {
- if (columnReorderingAllowed) {
- final String[] colorder = new String[visibleColumns.size()];
- int i = 0;
- for (Object colId : visibleColumns) {
- colorder[i++] = columnIdMap.key(colId);
- }
- target.addVariable(this, "columnorder", colorder);
- }
- }
-
- private void paintSorting(PaintTarget target) throws PaintException {
- // Sorting
- if (getContainerDataSource() instanceof Container.Sortable) {
- target.addVariable(this, "sortcolumn",
- columnIdMap.key(sortContainerPropertyId));
- target.addVariable(this, "sortascending", sortAscending);
- }
- }
-
- private void paintRows(PaintTarget target, final Object[][] cells,
- final Set<Action> actionSet) throws PaintException {
- final boolean[] iscomponent = findCellsWithComponents();
-
- target.startTag("rows");
- // cells array contains all that are supposed to be visible on client,
- // but we'll start from the one requested by client
- int start = 0;
- if (reqFirstRowToPaint != -1 && firstToBeRenderedInClient != -1) {
- start = reqFirstRowToPaint - firstToBeRenderedInClient;
- }
- int end = cells[0].length;
- if (reqRowsToPaint != -1) {
- end = start + reqRowsToPaint;
- }
- // sanity check
- if (lastToBeRenderedInClient != -1 && lastToBeRenderedInClient < end) {
- end = lastToBeRenderedInClient + 1;
- }
- if (start > cells[CELL_ITEMID].length || start < 0) {
- start = 0;
- }
- if (end > cells[CELL_ITEMID].length) {
- end = cells[CELL_ITEMID].length;
- }
-
- for (int indexInRowbuffer = start; indexInRowbuffer < end; indexInRowbuffer++) {
- final Object itemId = cells[CELL_ITEMID][indexInRowbuffer];
-
- if (shouldHideNullSelectionItem()) {
- // Remove null selection item if null selection is not allowed
- continue;
- }
-
- paintRow(target, cells, isEditable(), actionSet, iscomponent,
- indexInRowbuffer, itemId);
- }
- target.endTag("rows");
- }
-
- private boolean[] findCellsWithComponents() {
- final boolean[] isComponent = new boolean[visibleColumns.size()];
- int ix = 0;
- for (Object columnId : visibleColumns) {
- if (columnGenerators.containsKey(columnId)) {
- isComponent[ix++] = true;
- } else {
- final Class<?> colType = getType(columnId);
- isComponent[ix++] = colType != null
- && Component.class.isAssignableFrom(colType);
- }
- }
- return isComponent;
- }
-
- private void paintVisibleColumnOrder(PaintTarget target) {
- // Visible column order
- final ArrayList<String> visibleColOrder = new ArrayList<String>();
- for (Object columnId : visibleColumns) {
- if (!isColumnCollapsed(columnId)) {
- visibleColOrder.add(columnIdMap.key(columnId));
- }
- }
- target.addAttribute("vcolorder", visibleColOrder.toArray());
- }
-
- private Set<Action> findAndPaintBodyActions(PaintTarget target) {
- Set<Action> actionSet = new LinkedHashSet<Action>();
- if (actionHandlers != null) {
- final ArrayList<String> keys = new ArrayList<String>();
- for (Handler ah : actionHandlers) {
- // Getting actions for the null item, which in this case means
- // the body item
- final Action[] actions = ah.getActions(null, this);
- if (actions != null) {
- for (Action action : actions) {
- actionSet.add(action);
- keys.add(actionMapper.key(action));
- }
- }
- }
- target.addAttribute("alb", keys.toArray());
- }
- return actionSet;
- }
-
- private boolean shouldHideNullSelectionItem() {
- return !isNullSelectionAllowed() && getNullSelectionItemId() != null
- && containsId(getNullSelectionItemId());
- }
-
- private int findNumRowsToPaint(PaintTarget target, final Object[][] cells)
- throws PaintException {
- int rows;
- if (reqRowsToPaint >= 0) {
- rows = reqRowsToPaint;
- } else {
- rows = cells[0].length;
- if (alwaysRecalculateColumnWidths) {
- // TODO experimental feature for now: tell the client to
- // recalculate column widths.
- // We'll only do this for paints that do not originate from
- // table scroll/cache requests (i.e when reqRowsToPaint<0)
- target.addAttribute("recalcWidths", true);
- }
- }
- return rows;
- }
-
- private void paintSelectMode(PaintTarget target) throws PaintException {
- if (multiSelectMode != MultiSelectMode.DEFAULT) {
- target.addAttribute("multiselectmode", multiSelectMode.ordinal());
- }
- if (isSelectable()) {
- target.addAttribute("selectmode", (isMultiSelect() ? "multi"
- : "single"));
- } else {
- target.addAttribute("selectmode", "none");
- }
- if (!isNullSelectionAllowed()) {
- target.addAttribute("nsa", false);
- }
-
- // selection support
- // The select variable is only enabled if selectable
- if (isSelectable()) {
- target.addVariable(this, "selected", findSelectedKeys());
- }
- }
-
- private String[] findSelectedKeys() {
- LinkedList<String> selectedKeys = new LinkedList<String>();
- if (isMultiSelect()) {
- HashSet<?> sel = new HashSet<Object>((Set<?>) getValue());
- Collection<?> vids = getVisibleItemIds();
- for (Iterator<?> it = vids.iterator(); it.hasNext();) {
- Object id = it.next();
- if (sel.contains(id)) {
- selectedKeys.add(itemIdMapper.key(id));
- }
- }
- } else {
- Object value = getValue();
- if (value == null) {
- value = getNullSelectionItemId();
- }
- if (value != null) {
- selectedKeys.add(itemIdMapper.key(value));
- }
- }
- return selectedKeys.toArray(new String[selectedKeys.size()]);
- }
-
- private void paintDragMode(PaintTarget target) throws PaintException {
- if (dragMode != TableDragMode.NONE) {
- target.addAttribute("dragmode", dragMode.ordinal());
- }
- }
-
- private void paintTabIndex(PaintTarget target) throws PaintException {
- // The tab ordering number
- if (getTabIndex() > 0) {
- target.addAttribute("tabindex", getTabIndex());
- }
- }
-
- private void paintColumnWidth(PaintTarget target, final Object columnId)
- throws PaintException {
- if (columnWidths.containsKey(columnId)) {
- if (getColumnWidth(columnId) > -1) {
- target.addAttribute("width",
- String.valueOf(getColumnWidth(columnId)));
- } else {
- target.addAttribute("er", getColumnExpandRatio(columnId));
- }
- }
- }
-
- private boolean rowHeadersAreEnabled() {
- return getRowHeaderMode() != ROW_HEADER_MODE_HIDDEN;
- }
-
- private void paintRow(PaintTarget target, final Object[][] cells,
- final boolean iseditable, final Set<Action> actionSet,
- final boolean[] iscomponent, int indexInRowbuffer,
- final Object itemId) throws PaintException {
- target.startTag("tr");
-
- paintRowAttributes(target, cells, actionSet, indexInRowbuffer, itemId);
-
- // cells
- int currentColumn = 0;
- for (final Iterator<Object> it = visibleColumns.iterator(); it
- .hasNext(); currentColumn++) {
- final Object columnId = it.next();
- if (columnId == null || isColumnCollapsed(columnId)) {
- continue;
- }
- /*
- * For each cell, if a cellStyleGenerator is specified, get the
- * specific style for the cell. If there is any, add it to the
- * target.
- */
- if (cellStyleGenerator != null) {
- String cellStyle = cellStyleGenerator
- .getStyle(itemId, columnId);
- if (cellStyle != null && !cellStyle.equals("")) {
- target.addAttribute("style-" + columnIdMap.key(columnId),
- cellStyle);
- }
- }
-
- if ((iscomponent[currentColumn] || iseditable || cells[CELL_GENERATED_ROW][indexInRowbuffer] != null)
- && Component.class.isInstance(cells[CELL_FIRSTCOL
- + currentColumn][indexInRowbuffer])) {
- final Component c = (Component) cells[CELL_FIRSTCOL
- + currentColumn][indexInRowbuffer];
- if (c == null) {
- target.addText("");
- paintCellTooltips(target, itemId, columnId);
- } else {
- LegacyPaint.paint(c, target);
- }
- } else {
- target.addText((String) cells[CELL_FIRSTCOL + currentColumn][indexInRowbuffer]);
- paintCellTooltips(target, itemId, columnId);
- }
- }
-
- target.endTag("tr");
- }
-
- private void paintCellTooltips(PaintTarget target, Object itemId,
- Object columnId) throws PaintException {
- if (itemDescriptionGenerator != null) {
- String itemDescription = itemDescriptionGenerator
- .generateDescription(this, itemId, columnId);
- if (itemDescription != null && !itemDescription.equals("")) {
- target.addAttribute("descr-" + columnIdMap.key(columnId),
- itemDescription);
- }
- }
- }
-
- private void paintRowTooltips(PaintTarget target, Object itemId)
- throws PaintException {
- if (itemDescriptionGenerator != null) {
- String rowDescription = itemDescriptionGenerator
- .generateDescription(this, itemId, null);
- if (rowDescription != null && !rowDescription.equals("")) {
- target.addAttribute("rowdescr", rowDescription);
- }
- }
- }
-
- private void paintRowAttributes(PaintTarget target, final Object[][] cells,
- final Set<Action> actionSet, int indexInRowbuffer,
- final Object itemId) throws PaintException {
- // tr attributes
-
- paintRowIcon(target, cells, indexInRowbuffer);
- paintRowHeader(target, cells, indexInRowbuffer);
- paintGeneratedRowInfo(target, cells, indexInRowbuffer);
- target.addAttribute("key",
- Integer.parseInt(cells[CELL_KEY][indexInRowbuffer].toString()));
-
- if (isSelected(itemId)) {
- target.addAttribute("selected", true);
- }
-
- // Actions
- if (actionHandlers != null) {
- final ArrayList<String> keys = new ArrayList<String>();
- for (Handler ah : actionHandlers) {
- final Action[] aa = ah.getActions(itemId, this);
- if (aa != null) {
- for (int ai = 0; ai < aa.length; ai++) {
- final String key = actionMapper.key(aa[ai]);
- actionSet.add(aa[ai]);
- keys.add(key);
- }
- }
- }
- target.addAttribute("al", keys.toArray());
- }
-
- /*
- * For each row, if a cellStyleGenerator is specified, get the specific
- * style for the cell, using null as propertyId. If there is any, add it
- * to the target.
- */
- if (cellStyleGenerator != null) {
- String rowStyle = cellStyleGenerator.getStyle(itemId, null);
- if (rowStyle != null && !rowStyle.equals("")) {
- target.addAttribute("rowstyle", rowStyle);
- }
- }
-
- paintRowTooltips(target, itemId);
-
- paintRowAttributes(target, itemId);
- }
-
- private void paintGeneratedRowInfo(PaintTarget target, Object[][] cells,
- int indexInRowBuffer) throws PaintException {
- GeneratedRow generatedRow = (GeneratedRow) cells[CELL_GENERATED_ROW][indexInRowBuffer];
- if (generatedRow != null) {
- target.addAttribute("gen_html", generatedRow.isHtmlContentAllowed());
- target.addAttribute("gen_span", generatedRow.isSpanColumns());
- target.addAttribute("gen_widget",
- generatedRow.getValue() instanceof Component);
- }
- }
-
- protected void paintRowHeader(PaintTarget target, Object[][] cells,
- int indexInRowbuffer) throws PaintException {
- if (rowHeadersAreEnabled()) {
- if (cells[CELL_HEADER][indexInRowbuffer] != null) {
- target.addAttribute("caption",
- (String) cells[CELL_HEADER][indexInRowbuffer]);
- }
- }
-
- }
-
- protected void paintRowIcon(PaintTarget target, final Object[][] cells,
- int indexInRowbuffer) throws PaintException {
- if (rowHeadersAreEnabled()
- && cells[CELL_ICON][indexInRowbuffer] != null) {
- target.addAttribute("icon",
- (Resource) cells[CELL_ICON][indexInRowbuffer]);
- }
- }
-
- /**
- * A method where extended Table implementations may add their custom
- * attributes for rows.
- *
- * @param target
- * @param itemId
- */
- protected void paintRowAttributes(PaintTarget target, Object itemId)
- throws PaintException {
-
- }
-
- /**
- * Gets the cached visible table contents.
- *
- * @return the cached visible table contents.
- */
- private Object[][] getVisibleCells() {
- if (pageBuffer == null) {
- refreshRenderedCells();
- }
- return pageBuffer;
- }
-
- /**
- * Gets the value of property.
- *
- * By default if the table is editable the fieldFactory is used to create
- * editors for table cells. Otherwise formatPropertyValue is used to format
- * the value representation.
- *
- * @param rowId
- * the Id of the row (same as item Id).
- * @param colId
- * the Id of the column.
- * @param property
- * the Property to be presented.
- * @return Object Either formatted value or Component for field.
- * @see #setTableFieldFactory(TableFieldFactory)
- */
- protected Object getPropertyValue(Object rowId, Object colId,
- Property property) {
- if (isEditable() && fieldFactory != null) {
- final Field<?> f = fieldFactory.createField(
- getContainerDataSource(), rowId, colId, this);
- if (f != null) {
- // Remember that we have made this association so we can remove
- // it when the component is removed
- associatedProperties.put(f, property);
- bindPropertyToField(rowId, colId, property, f);
- return f;
- }
- }
-
- return formatPropertyValue(rowId, colId, property);
- }
-
- /**
- * Binds an item property to a field generated by TableFieldFactory. The
- * default behavior is to bind property straight to Field. If
- * Property.Viewer type property (e.g. PropertyFormatter) is already set for
- * field, the property is bound to that Property.Viewer.
- *
- * @param rowId
- * @param colId
- * @param property
- * @param field
- * @since 6.7.3
- */
- protected void bindPropertyToField(Object rowId, Object colId,
- Property property, Field field) {
- // check if field has a property that is Viewer set. In that case we
- // expect developer has e.g. PropertyFormatter that he wishes to use and
- // assign the property to the Viewer instead.
- boolean hasFilterProperty = field.getPropertyDataSource() != null
- && (field.getPropertyDataSource() instanceof Property.Viewer);
- if (hasFilterProperty) {
- ((Property.Viewer) field.getPropertyDataSource())
- .setPropertyDataSource(property);
- } else {
- field.setPropertyDataSource(property);
- }
- }
-
- /**
- * Formats table cell property values. By default the property.toString()
- * and return a empty string for null properties.
- *
- * @param rowId
- * the Id of the row (same as item Id).
- * @param colId
- * the Id of the column.
- * @param property
- * the Property to be formatted.
- * @return the String representation of property and its value.
- * @since 3.1
- */
- protected String formatPropertyValue(Object rowId, Object colId,
- Property<?> property) {
- if (property == null) {
- return "";
- }
- Converter<String, Object> converter = null;
-
- if (hasConverter(colId)) {
- converter = getConverter(colId);
- } else {
- ConverterUtil.getConverter(String.class, property.getType(),
- getApplication());
- }
- Object value = property.getValue();
- if (converter != null) {
- return converter.convertToPresentation(value, getLocale());
- }
- return (null != value) ? value.toString() : "";
- }
-
- /* Action container */
-
- /**
- * Registers a new action handler for this container
- *
- * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler)
- */
-
- @Override
- public void addActionHandler(Action.Handler actionHandler) {
-
- if (actionHandler != null) {
-
- if (actionHandlers == null) {
- actionHandlers = new LinkedList<Handler>();
- actionMapper = new KeyMapper<Action>();
- }
-
- if (!actionHandlers.contains(actionHandler)) {
- actionHandlers.add(actionHandler);
- // Assures the visual refresh. No need to reset the page buffer
- // before as the content has not changed, only the action
- // handlers.
- refreshRenderedCells();
- }
-
- }
- }
-
- /**
- * Removes a previously registered action handler for the contents of this
- * container.
- *
- * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler)
- */
-
- @Override
- public void removeActionHandler(Action.Handler actionHandler) {
-
- if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
-
- actionHandlers.remove(actionHandler);
-
- if (actionHandlers.isEmpty()) {
- actionHandlers = null;
- actionMapper = null;
- }
-
- // Assures the visual refresh. No need to reset the page buffer
- // before as the content has not changed, only the action
- // handlers.
- refreshRenderedCells();
- }
- }
-
- /**
- * Removes all action handlers
- */
- public void removeAllActionHandlers() {
- actionHandlers = null;
- actionMapper = null;
- // Assures the visual refresh. No need to reset the page buffer
- // before as the content has not changed, only the action
- // handlers.
- refreshRenderedCells();
- }
-
- /* Property value change listening support */
-
- /**
- * Notifies this listener that the Property's value has changed.
- *
- * Also listens changes in rendered items to refresh content area.
- *
- * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent)
- */
-
- @Override
- public void valueChange(Property.ValueChangeEvent event) {
- if (event.getProperty() == this
- || event.getProperty() == getPropertyDataSource()) {
- super.valueChange(event);
- } else {
- refreshRowCache();
- containerChangeToBeRendered = true;
- }
- requestRepaint();
- }
-
- /**
- * Clears the current page buffer. Call this before
- * {@link #refreshRenderedCells()} to ensure that all content is updated
- * from the properties.
- */
- protected void resetPageBuffer() {
- firstToBeRenderedInClient = -1;
- lastToBeRenderedInClient = -1;
- reqFirstRowToPaint = -1;
- reqRowsToPaint = -1;
- pageBuffer = null;
- }
-
- /**
- * Notifies the component that it is connected to an application.
- *
- * @see com.vaadin.ui.Component#attach()
- */
-
- @Override
- public void attach() {
- super.attach();
-
- refreshRenderedCells();
- }
-
- /**
- * Notifies the component that it is detached from the application
- *
- * @see com.vaadin.ui.Component#detach()
- */
-
- @Override
- public void detach() {
- super.detach();
- }
-
- /**
- * Removes all Items from the Container.
- *
- * @see com.vaadin.data.Container#removeAllItems()
- */
-
- @Override
- public boolean removeAllItems() {
- currentPageFirstItemId = null;
- currentPageFirstItemIndex = 0;
- return super.removeAllItems();
- }
-
- /**
- * Removes the Item identified by <code>ItemId</code> from the Container.
- *
- * @see com.vaadin.data.Container#removeItem(Object)
- */
-
- @Override
- public boolean removeItem(Object itemId) {
- final Object nextItemId = nextItemId(itemId);
- final boolean ret = super.removeItem(itemId);
- if (ret && (itemId != null) && (itemId.equals(currentPageFirstItemId))) {
- currentPageFirstItemId = nextItemId;
- }
- if (!(items instanceof Container.ItemSetChangeNotifier)) {
- refreshRowCache();
- }
- return ret;
- }
-
- /**
- * Removes a Property specified by the given Property ID from the Container.
- *
- * @see com.vaadin.data.Container#removeContainerProperty(Object)
- */
-
- @Override
- public boolean removeContainerProperty(Object propertyId)
- throws UnsupportedOperationException {
-
- // If a visible property is removed, remove the corresponding column
- visibleColumns.remove(propertyId);
- columnAlignments.remove(propertyId);
- columnIcons.remove(propertyId);
- columnHeaders.remove(propertyId);
- columnFooters.remove(propertyId);
-
- return super.removeContainerProperty(propertyId);
- }
-
- /**
- * Adds a new property to the table and show it as a visible column.
- *
- * @param propertyId
- * the Id of the proprty.
- * @param type
- * the class of the property.
- * @param defaultValue
- * the default value given for all existing items.
- * @see com.vaadin.data.Container#addContainerProperty(Object, Class,
- * Object)
- */
-
- @Override
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue) throws UnsupportedOperationException {
-
- boolean visibleColAdded = false;
- if (!visibleColumns.contains(propertyId)) {
- visibleColumns.add(propertyId);
- visibleColAdded = true;
- }
-
- if (!super.addContainerProperty(propertyId, type, defaultValue)) {
- if (visibleColAdded) {
- visibleColumns.remove(propertyId);
- }
- return false;
- }
- if (!(items instanceof Container.PropertySetChangeNotifier)) {
- refreshRowCache();
- }
- return true;
- }
-
- /**
- * Adds a new property to the table and show it as a visible column.
- *
- * @param propertyId
- * the Id of the proprty
- * @param type
- * the class of the property
- * @param defaultValue
- * the default value given for all existing items
- * @param columnHeader
- * the Explicit header of the column. If explicit header is not
- * needed, this should be set null.
- * @param columnIcon
- * the Icon of the column. If icon is not needed, this should be
- * set null.
- * @param columnAlignment
- * the Alignment of the column. Null implies align left.
- * @throws UnsupportedOperationException
- * if the operation is not supported.
- * @see com.vaadin.data.Container#addContainerProperty(Object, Class,
- * Object)
- */
- public boolean addContainerProperty(Object propertyId, Class<?> type,
- Object defaultValue, String columnHeader, Resource columnIcon,
- Align columnAlignment) throws UnsupportedOperationException {
- if (!this.addContainerProperty(propertyId, type, defaultValue)) {
- return false;
- }
- setColumnAlignment(propertyId, columnAlignment);
- setColumnHeader(propertyId, columnHeader);
- setColumnIcon(propertyId, columnIcon);
- return true;
- }
-
- /**
- * Adds a generated column to the Table.
- * <p>
- * A generated column is a column that exists only in the Table, not as a
- * property in the underlying Container. It shows up just as a regular
- * column.
- * </p>
- * <p>
- * A generated column will override a property with the same id, so that the
- * generated column is shown instead of the column representing the
- * property. Note that getContainerProperty() will still get the real
- * property.
- * </p>
- * <p>
- * Table will not listen to value change events from properties overridden
- * by generated columns. If the content of your generated column depends on
- * properties that are not directly visible in the table, attach value
- * change listener to update the content on all depended properties.
- * Otherwise your UI might not get updated as expected.
- * </p>
- * <p>
- * Also note that getVisibleColumns() will return the generated columns,
- * while getContainerPropertyIds() will not.
- * </p>
- *
- * @param id
- * the id of the column to be added
- * @param generatedColumn
- * the {@link ColumnGenerator} to use for this column
- */
- public void addGeneratedColumn(Object id, ColumnGenerator generatedColumn) {
- if (generatedColumn == null) {
- throw new IllegalArgumentException(
- "Can not add null as a GeneratedColumn");
- }
- if (columnGenerators.containsKey(id)) {
- throw new IllegalArgumentException(
- "Can not add the same GeneratedColumn twice, id:" + id);
- } else {
- columnGenerators.put(id, generatedColumn);
- /*
- * add to visible column list unless already there (overriding
- * column from DS)
- */
- if (!visibleColumns.contains(id)) {
- visibleColumns.add(id);
- }
- refreshRowCache();
- }
- }
-
- /**
- * Returns the ColumnGenerator used to generate the given column.
- *
- * @param columnId
- * The id of the generated column
- * @return The ColumnGenerator used for the given columnId or null.
- */
- public ColumnGenerator getColumnGenerator(Object columnId)
- throws IllegalArgumentException {
- return columnGenerators.get(columnId);
- }
-
- /**
- * Removes a generated column previously added with addGeneratedColumn.
- *
- * @param columnId
- * id of the generated column to remove
- * @return true if the column could be removed (existed in the Table)
- */
- public boolean removeGeneratedColumn(Object columnId) {
- if (columnGenerators.containsKey(columnId)) {
- columnGenerators.remove(columnId);
- // remove column from visibleColumns list unless it exists in
- // container (generator previously overrode this column)
- if (!items.getContainerPropertyIds().contains(columnId)) {
- visibleColumns.remove(columnId);
- }
- refreshRowCache();
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Returns item identifiers of the items which are currently rendered on the
- * client.
- * <p>
- * Note, that some due to historical reasons the name of the method is bit
- * misleading. Some items may be partly or totally out of the viewport of
- * the table's scrollable area. Actually detecting rows which can be
- * actually seen by the end user may be problematic due to the client server
- * architecture. Using {@link #getCurrentPageFirstItemId()} combined with
- * {@link #getPageLength()} may produce good enough estimates in some
- * situations.
- *
- * @see com.vaadin.ui.Select#getVisibleItemIds()
- */
-
- @Override
- public Collection<?> getVisibleItemIds() {
-
- final LinkedList<Object> visible = new LinkedList<Object>();
-
- final Object[][] cells = getVisibleCells();
- // may be null if the table has not been rendered yet (e.g. not attached
- // to a layout)
- if (null != cells) {
- for (int i = 0; i < cells[CELL_ITEMID].length; i++) {
- visible.add(cells[CELL_ITEMID][i]);
- }
- }
-
- return visible;
- }
-
- /**
- * Container datasource item set change. Table must flush its buffers on
- * change.
- *
- * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent)
- */
-
- @Override
- public void containerItemSetChange(Container.ItemSetChangeEvent event) {
- super.containerItemSetChange(event);
-
- // super method clears the key map, must inform client about this to
- // avoid getting invalid keys back (#8584)
- keyMapperReset = true;
-
- // ensure that page still has first item in page, ignore buffer refresh
- // (forced in this method)
- setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);
- refreshRowCache();
- }
-
- /**
- * Container datasource property set change. Table must flush its buffers on
- * change.
- *
- * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent)
- */
-
- @Override
- public void containerPropertySetChange(
- Container.PropertySetChangeEvent event) {
- disableContentRefreshing();
- super.containerPropertySetChange(event);
-
- // sanitetize visibleColumns. note that we are not adding previously
- // non-existing properties as columns
- Collection<?> containerPropertyIds = getContainerDataSource()
- .getContainerPropertyIds();
-
- LinkedList<Object> newVisibleColumns = new LinkedList<Object>(
- visibleColumns);
- for (Iterator<Object> iterator = newVisibleColumns.iterator(); iterator
- .hasNext();) {
- Object id = iterator.next();
- if (!(containerPropertyIds.contains(id) || columnGenerators
- .containsKey(id))) {
- iterator.remove();
- }
- }
- setVisibleColumns(newVisibleColumns.toArray());
- // same for collapsed columns
- for (Iterator<Object> iterator = collapsedColumns.iterator(); iterator
- .hasNext();) {
- Object id = iterator.next();
- if (!(containerPropertyIds.contains(id) || columnGenerators
- .containsKey(id))) {
- iterator.remove();
- }
- }
-
- resetPageBuffer();
- enableContentRefreshing(true);
- }
-
- /**
- * Adding new items is not supported.
- *
- * @throws UnsupportedOperationException
- * if set to true.
- * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean)
- */
-
- @Override
- public void setNewItemsAllowed(boolean allowNewOptions)
- throws UnsupportedOperationException {
- if (allowNewOptions) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Gets the ID of the Item following the Item that corresponds to itemId.
- *
- * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object)
- */
-
- @Override
- public Object nextItemId(Object itemId) {
- return ((Container.Ordered) items).nextItemId(itemId);
- }
-
- /**
- * Gets the ID of the Item preceding the Item that corresponds to the
- * itemId.
- *
- * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object)
- */
-
- @Override
- public Object prevItemId(Object itemId) {
- return ((Container.Ordered) items).prevItemId(itemId);
- }
-
- /**
- * Gets the ID of the first Item in the Container.
- *
- * @see com.vaadin.data.Container.Ordered#firstItemId()
- */
-
- @Override
- public Object firstItemId() {
- return ((Container.Ordered) items).firstItemId();
- }
-
- /**
- * Gets the ID of the last Item in the Container.
- *
- * @see com.vaadin.data.Container.Ordered#lastItemId()
- */
-
- @Override
- public Object lastItemId() {
- return ((Container.Ordered) items).lastItemId();
- }
-
- /**
- * Tests if the Item corresponding to the given Item ID is the first Item in
- * the Container.
- *
- * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object)
- */
-
- @Override
- public boolean isFirstId(Object itemId) {
- return ((Container.Ordered) items).isFirstId(itemId);
- }
-
- /**
- * Tests if the Item corresponding to the given Item ID is the last Item in
- * the Container.
- *
- * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object)
- */
-
- @Override
- public boolean isLastId(Object itemId) {
- return ((Container.Ordered) items).isLastId(itemId);
- }
-
- /**
- * Adds new item after the given item.
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object)
- */
-
- @Override
- public Object addItemAfter(Object previousItemId)
- throws UnsupportedOperationException {
- Object itemId = ((Container.Ordered) items)
- .addItemAfter(previousItemId);
- if (!(items instanceof Container.ItemSetChangeNotifier)) {
- refreshRowCache();
- }
- return itemId;
- }
-
- /**
- * Adds new item after the given item.
- *
- * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object,
- * java.lang.Object)
- */
-
- @Override
- public Item addItemAfter(Object previousItemId, Object newItemId)
- throws UnsupportedOperationException {
- Item item = ((Container.Ordered) items).addItemAfter(previousItemId,
- newItemId);
- if (!(items instanceof Container.ItemSetChangeNotifier)) {
- refreshRowCache();
- }
- return item;
- }
-
- /**
- * Sets the TableFieldFactory that is used to create editor for table cells.
- *
- * The TableFieldFactory is only used if the Table is editable. By default
- * the DefaultFieldFactory is used.
- *
- * @param fieldFactory
- * the field factory to set.
- * @see #isEditable
- * @see DefaultFieldFactory
- */
- public void setTableFieldFactory(TableFieldFactory fieldFactory) {
- this.fieldFactory = fieldFactory;
-
- // Assure visual refresh
- refreshRowCache();
- }
-
- /**
- * Gets the TableFieldFactory that is used to create editor for table cells.
- *
- * The FieldFactory is only used if the Table is editable.
- *
- * @return TableFieldFactory used to create the Field instances.
- * @see #isEditable
- */
- public TableFieldFactory getTableFieldFactory() {
- return fieldFactory;
- }
-
- /**
- * Is table editable.
- *
- * If table is editable a editor of type Field is created for each table
- * cell. The assigned FieldFactory is used to create the instances.
- *
- * To provide custom editors for table cells create a class implementins the
- * FieldFactory interface, and assign it to table, and set the editable
- * property to true.
- *
- * @return true if table is editable, false oterwise.
- * @see Field
- * @see FieldFactory
- *
- */
- public boolean isEditable() {
- return editable;
- }
-
- /**
- * Sets the editable property.
- *
- * If table is editable a editor of type Field is created for each table
- * cell. The assigned FieldFactory is used to create the instances.
- *
- * To provide custom editors for table cells create a class implementins the
- * FieldFactory interface, and assign it to table, and set the editable
- * property to true.
- *
- * @param editable
- * true if table should be editable by user.
- * @see Field
- * @see FieldFactory
- *
- */
- public void setEditable(boolean editable) {
- this.editable = editable;
-
- // Assure visual refresh
- refreshRowCache();
- }
-
- /**
- * Sorts the table.
- *
- * @throws UnsupportedOperationException
- * if the container data source does not implement
- * Container.Sortable
- * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[],
- * boolean[])
- *
- */
-
- @Override
- public void sort(Object[] propertyId, boolean[] ascending)
- throws UnsupportedOperationException {
- final Container c = getContainerDataSource();
- if (c instanceof Container.Sortable) {
- final int pageIndex = getCurrentPageFirstItemIndex();
- ((Container.Sortable) c).sort(propertyId, ascending);
- setCurrentPageFirstItemIndex(pageIndex);
- refreshRowCache();
-
- } else if (c != null) {
- throw new UnsupportedOperationException(
- "Underlying Data does not allow sorting");
- }
- }
-
- /**
- * Sorts the table by currently selected sorting column.
- *
- * @throws UnsupportedOperationException
- * if the container data source does not implement
- * Container.Sortable
- */
- public void sort() {
- if (getSortContainerPropertyId() == null) {
- return;
- }
- sort(new Object[] { sortContainerPropertyId },
- new boolean[] { sortAscending });
- }
-
- /**
- * Gets the container property IDs, which can be used to sort the item.
- * <p>
- * Note that the {@link #isSortEnabled()} state affects what this method
- * returns. Disabling sorting causes this method to always return an empty
- * collection.
- * </p>
- *
- * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds()
- */
-
- @Override
- public Collection<?> getSortableContainerPropertyIds() {
- final Container c = getContainerDataSource();
- if (c instanceof Container.Sortable && isSortEnabled()) {
- return ((Container.Sortable) c).getSortableContainerPropertyIds();
- } else {
- return Collections.EMPTY_LIST;
- }
- }
-
- /**
- * Gets the currently sorted column property ID.
- *
- * @return the Container property id of the currently sorted column.
- */
- public Object getSortContainerPropertyId() {
- return sortContainerPropertyId;
- }
-
- /**
- * Sets the currently sorted column property id.
- *
- * @param propertyId
- * the Container property id of the currently sorted column.
- */
- public void setSortContainerPropertyId(Object propertyId) {
- setSortContainerPropertyId(propertyId, true);
- }
-
- /**
- * Internal method to set currently sorted column property id. With doSort
- * flag actual sorting may be bypassed.
- *
- * @param propertyId
- * @param doSort
- */
- private void setSortContainerPropertyId(Object propertyId, boolean doSort) {
- if ((sortContainerPropertyId != null && !sortContainerPropertyId
- .equals(propertyId))
- || (sortContainerPropertyId == null && propertyId != null)) {
- sortContainerPropertyId = propertyId;
-
- if (doSort) {
- sort();
- // Assures the visual refresh. This should not be necessary as
- // sort() calls refreshRowCache
- refreshRenderedCells();
- }
- }
- }
-
- /**
- * Is the table currently sorted in ascending order.
- *
- * @return <code>true</code> if ascending, <code>false</code> if descending.
- */
- public boolean isSortAscending() {
- return sortAscending;
- }
-
- /**
- * Sets the table in ascending order.
- *
- * @param ascending
- * <code>true</code> if ascending, <code>false</code> if
- * descending.
- */
- public void setSortAscending(boolean ascending) {
- setSortAscending(ascending, true);
- }
-
- /**
- * Internal method to set sort ascending. With doSort flag actual sort can
- * be bypassed.
- *
- * @param ascending
- * @param doSort
- */
- private void setSortAscending(boolean ascending, boolean doSort) {
- if (sortAscending != ascending) {
- sortAscending = ascending;
- if (doSort) {
- sort();
- // Assures the visual refresh. This should not be necessary as
- // sort() calls refreshRowCache
- refreshRenderedCells();
- }
- }
- }
-
- /**
- * Is sorting disabled altogether.
- *
- * True iff no sortable columns are given even in the case where data source
- * would support this.
- *
- * @return True iff sorting is disabled.
- * @deprecated Use {@link #isSortEnabled()} instead
- */
- @Deprecated
- public boolean isSortDisabled() {
- return !isSortEnabled();
- }
-
- /**
- * Checks if sorting is enabled.
- *
- * @return true if sorting by the user is allowed, false otherwise
- */
- public boolean isSortEnabled() {
- return sortEnabled;
- }
-
- /**
- * Disables the sorting by the user altogether.
- *
- * @param sortDisabled
- * True iff sorting is disabled.
- * @deprecated Use {@link #setSortEnabled(boolean)} instead
- */
- @Deprecated
- public void setSortDisabled(boolean sortDisabled) {
- setSortEnabled(!sortDisabled);
- }
-
- /**
- * Enables or disables sorting.
- * <p>
- * Setting this to false disallows sorting by the user. It is still possible
- * to call {@link #sort()}.
- * </p>
- *
- * @param sortEnabled
- * true to allow the user to sort the table, false to disallow it
- */
- public void setSortEnabled(boolean sortEnabled) {
- if (this.sortEnabled != sortEnabled) {
- this.sortEnabled = sortEnabled;
- requestRepaint();
- }
- }
-
- /**
- * Used to create "generated columns"; columns that exist only in the Table,
- * not in the underlying Container. Implement this interface and pass it to
- * Table.addGeneratedColumn along with an id for the column to be generated.
- *
- */
- public interface ColumnGenerator extends Serializable {
-
- /**
- * Called by Table when a cell in a generated column needs to be
- * generated.
- *
- * @param source
- * the source Table
- * @param itemId
- * the itemId (aka rowId) for the of the cell to be generated
- * @param columnId
- * the id for the generated column (as specified in
- * addGeneratedColumn)
- * @return A {@link Component} that should be rendered in the cell or a
- * {@link String} that should be displayed in the cell. Other
- * return values are not supported.
- */
- public abstract Object generateCell(Table source, Object itemId,
- Object columnId);
- }
-
- /**
- * Set cell style generator for Table.
- *
- * @param cellStyleGenerator
- * New cell style generator or null to remove generator.
- */
- public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) {
- this.cellStyleGenerator = cellStyleGenerator;
- // Assures the visual refresh. No need to reset the page buffer
- // before as the content has not changed, only the style generators
- refreshRenderedCells();
-
- }
-
- /**
- * Get the current cell style generator.
- *
- */
- public CellStyleGenerator getCellStyleGenerator() {
- return cellStyleGenerator;
- }
-
- /**
- * Allow to define specific style on cells (and rows) contents. Implements
- * this interface and pass it to Table.setCellStyleGenerator. Row styles are
- * generated when porpertyId is null. The CSS class name that will be added
- * to the cell content is <tt>v-table-cell-content-[style name]</tt>, and
- * the row style will be <tt>v-table-row-[style name]</tt>.
- */
- public interface CellStyleGenerator extends Serializable {
-
- /**
- * Called by Table when a cell (and row) is painted.
- *
- * @param itemId
- * The itemId of the painted cell
- * @param propertyId
- * The propertyId of the cell, null when getting row style
- * @return The style name to add to this cell or row. (the CSS class
- * name will be v-table-cell-content-[style name], or
- * v-table-row-[style name] for rows)
- */
- public abstract String getStyle(Object itemId, Object propertyId);
- }
-
- @Override
- public void addListener(ItemClickListener listener) {
- addListener(VScrollTable.ITEM_CLICK_EVENT_ID, ItemClickEvent.class,
- listener, ItemClickEvent.ITEM_CLICK_METHOD);
- }
-
- @Override
- public void removeListener(ItemClickListener listener) {
- removeListener(VScrollTable.ITEM_CLICK_EVENT_ID, ItemClickEvent.class,
- listener);
- }
-
- // Identical to AbstractCompoenentContainer.setEnabled();
-
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- if (getParent() != null && !getParent().isEnabled()) {
- // some ancestor still disabled, don't update children
- return;
- } else {
- requestRepaintAll();
- }
- }
-
- /**
- * Sets the drag start mode of the Table. Drag start mode controls how Table
- * behaves as a drag source.
- *
- * @param newDragMode
- */
- public void setDragMode(TableDragMode newDragMode) {
- dragMode = newDragMode;
- requestRepaint();
- }
-
- /**
- * @return the current start mode of the Table. Drag start mode controls how
- * Table behaves as a drag source.
- */
- public TableDragMode getDragMode() {
- return dragMode;
- }
-
- /**
- * Concrete implementation of {@link DataBoundTransferable} for data
- * transferred from a table.
- *
- * @see {@link DataBoundTransferable}.
- *
- * @since 6.3
- */
- public class TableTransferable extends DataBoundTransferable {
-
- protected TableTransferable(Map<String, Object> rawVariables) {
- super(Table.this, rawVariables);
- Object object = rawVariables.get("itemId");
- if (object != null) {
- setData("itemId", itemIdMapper.get((String) object));
- }
- object = rawVariables.get("propertyId");
- if (object != null) {
- setData("propertyId", columnIdMap.get((String) object));
- }
- }
-
- @Override
- public Object getItemId() {
- return getData("itemId");
- }
-
- @Override
- public Object getPropertyId() {
- return getData("propertyId");
- }
-
- @Override
- public Table getSourceComponent() {
- return (Table) super.getSourceComponent();
- }
-
- }
-
- @Override
- public TableTransferable getTransferable(Map<String, Object> rawVariables) {
- TableTransferable transferable = new TableTransferable(rawVariables);
- return transferable;
- }
-
- @Override
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- }
-
- @Override
- public AbstractSelectTargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables) {
- return new AbstractSelectTargetDetails(clientVariables);
- }
-
- /**
- * Sets the behavior of how the multi-select mode should behave when the
- * table is both selectable and in multi-select mode.
- * <p>
- * Note, that on some clients the mode may not be respected. E.g. on touch
- * based devices CTRL/SHIFT base selection method is invalid, so touch based
- * browsers always use the {@link MultiSelectMode#SIMPLE}.
- *
- * @param mode
- * The select mode of the table
- */
- public void setMultiSelectMode(MultiSelectMode mode) {
- multiSelectMode = mode;
- requestRepaint();
- }
-
- /**
- * Returns the select mode in which multi-select is used.
- *
- * @return The multi select mode
- */
- public MultiSelectMode getMultiSelectMode() {
- return multiSelectMode;
- }
-
- /**
- * Lazy loading accept criterion for Table. Accepted target rows are loaded
- * from server once per drag and drop operation. Developer must override one
- * method that decides on which rows the currently dragged data can be
- * dropped.
- *
- * <p>
- * Initially pretty much no data is sent to client. On first required
- * criterion check (per drag request) the client side data structure is
- * initialized from server and no subsequent requests requests are needed
- * during that drag and drop operation.
- */
- public static abstract class TableDropCriterion extends ServerSideCriterion {
-
- private Table table;
-
- private Set<Object> allowedItemIds;
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptcriteria.ServerSideCriterion#getIdentifier
- * ()
- */
-
- @Override
- protected String getIdentifier() {
- return TableDropCriterion.class.getCanonicalName();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptcriteria.AcceptCriterion#accepts(com.vaadin
- * .event.dd.DragAndDropEvent)
- */
- @Override
- @SuppressWarnings("unchecked")
- public boolean accept(DragAndDropEvent dragEvent) {
- AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent
- .getTargetDetails();
- table = (Table) dragEvent.getTargetDetails().getTarget();
- Collection<?> visibleItemIds = table.getVisibleItemIds();
- allowedItemIds = getAllowedItemIds(dragEvent, table,
- (Collection<Object>) visibleItemIds);
-
- return allowedItemIds.contains(dropTargetData.getItemIdOver());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptcriteria.AcceptCriterion#paintResponse(
- * com.vaadin.terminal.PaintTarget)
- */
-
- @Override
- public void paintResponse(PaintTarget target) throws PaintException {
- /*
- * send allowed nodes to client so subsequent requests can be
- * avoided
- */
- Object[] array = allowedItemIds.toArray();
- for (int i = 0; i < array.length; i++) {
- String key = table.itemIdMapper.key(array[i]);
- array[i] = key;
- }
- target.addAttribute("allowedIds", array);
- }
-
- /**
- * @param dragEvent
- * @param table
- * the table for which the allowed item identifiers are
- * defined
- * @param visibleItemIds
- * the list of currently rendered item identifiers, accepted
- * item id's need to be detected only for these visible items
- * @return the set of identifiers for items on which the dragEvent will
- * be accepted
- */
- protected abstract Set<Object> getAllowedItemIds(
- DragAndDropEvent dragEvent, Table table,
- Collection<Object> visibleItemIds);
-
- }
-
- /**
- * Click event fired when clicking on the Table headers. The event includes
- * a reference the the Table the event originated from, the property id of
- * the column which header was pressed and details about the mouse event
- * itself.
- */
- public static class HeaderClickEvent extends ClickEvent {
- public static final Method HEADER_CLICK_METHOD;
-
- static {
- try {
- // Set the header click method
- HEADER_CLICK_METHOD = HeaderClickListener.class
- .getDeclaredMethod("headerClick",
- new Class[] { HeaderClickEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(e);
- }
- }
-
- // The property id of the column which header was pressed
- private final Object columnPropertyId;
-
- public HeaderClickEvent(Component source, Object propertyId,
- MouseEventDetails details) {
- super(source, details);
- columnPropertyId = propertyId;
- }
-
- /**
- * Gets the property id of the column which header was pressed
- *
- * @return The column propety id
- */
- public Object getPropertyId() {
- return columnPropertyId;
- }
- }
-
- /**
- * Click event fired when clicking on the Table footers. The event includes
- * a reference the the Table the event originated from, the property id of
- * the column which header was pressed and details about the mouse event
- * itself.
- */
- public static class FooterClickEvent extends ClickEvent {
- public static final Method FOOTER_CLICK_METHOD;
-
- static {
- try {
- // Set the header click method
- FOOTER_CLICK_METHOD = FooterClickListener.class
- .getDeclaredMethod("footerClick",
- new Class[] { FooterClickEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(e);
- }
- }
-
- // The property id of the column which header was pressed
- private final Object columnPropertyId;
-
- /**
- * Constructor
- *
- * @param source
- * The source of the component
- * @param propertyId
- * The propertyId of the column
- * @param details
- * The mouse details of the click
- */
- public FooterClickEvent(Component source, Object propertyId,
- MouseEventDetails details) {
- super(source, details);
- columnPropertyId = propertyId;
- }
-
- /**
- * Gets the property id of the column which header was pressed
- *
- * @return The column propety id
- */
- public Object getPropertyId() {
- return columnPropertyId;
- }
- }
-
- /**
- * Interface for the listener for column header mouse click events. The
- * headerClick method is called when the user presses a header column cell.
- */
- public interface HeaderClickListener extends Serializable {
-
- /**
- * Called when a user clicks a header column cell
- *
- * @param event
- * The event which contains information about the column and
- * the mouse click event
- */
- public void headerClick(HeaderClickEvent event);
- }
-
- /**
- * Interface for the listener for column footer mouse click events. The
- * footerClick method is called when the user presses a footer column cell.
- */
- public interface FooterClickListener extends Serializable {
-
- /**
- * Called when a user clicks a footer column cell
- *
- * @param event
- * The event which contains information about the column and
- * the mouse click event
- */
- public void footerClick(FooterClickEvent event);
- }
-
- /**
- * Adds a header click listener which handles the click events when the user
- * clicks on a column header cell in the Table.
- * <p>
- * The listener will receive events which contain information about which
- * column was clicked and some details about the mouse event.
- * </p>
- *
- * @param listener
- * The handler which should handle the header click events.
- */
- public void addListener(HeaderClickListener listener) {
- addListener(VScrollTable.HEADER_CLICK_EVENT_ID, HeaderClickEvent.class,
- listener, HeaderClickEvent.HEADER_CLICK_METHOD);
- }
-
- /**
- * Removes a header click listener
- *
- * @param listener
- * The listener to remove.
- */
- public void removeListener(HeaderClickListener listener) {
- removeListener(VScrollTable.HEADER_CLICK_EVENT_ID,
- HeaderClickEvent.class, listener);
- }
-
- /**
- * Adds a footer click listener which handles the click events when the user
- * clicks on a column footer cell in the Table.
- * <p>
- * The listener will receive events which contain information about which
- * column was clicked and some details about the mouse event.
- * </p>
- *
- * @param listener
- * The handler which should handle the footer click events.
- */
- public void addListener(FooterClickListener listener) {
- addListener(VScrollTable.FOOTER_CLICK_EVENT_ID, FooterClickEvent.class,
- listener, FooterClickEvent.FOOTER_CLICK_METHOD);
- }
-
- /**
- * Removes a footer click listener
- *
- * @param listener
- * The listener to remove.
- */
- public void removeListener(FooterClickListener listener) {
- removeListener(VScrollTable.FOOTER_CLICK_EVENT_ID,
- FooterClickEvent.class, listener);
- }
-
- /**
- * Gets the footer caption beneath the rows
- *
- * @param propertyId
- * The propertyId of the column *
- * @return The caption of the footer or NULL if not set
- */
- public String getColumnFooter(Object propertyId) {
- return columnFooters.get(propertyId);
- }
-
- /**
- * Sets the column footer caption. The column footer caption is the text
- * displayed beneath the column if footers have been set visible.
- *
- * @param propertyId
- * The properyId of the column
- *
- * @param footer
- * The caption of the footer
- */
- public void setColumnFooter(Object propertyId, String footer) {
- if (footer == null) {
- columnFooters.remove(propertyId);
- } else {
- columnFooters.put(propertyId, footer);
- }
-
- requestRepaint();
- }
-
- /**
- * Sets the footer visible in the bottom of the table.
- * <p>
- * The footer can be used to add column related data like sums to the bottom
- * of the Table using setColumnFooter(Object propertyId, String footer).
- * </p>
- *
- * @param visible
- * Should the footer be visible
- */
- public void setFooterVisible(boolean visible) {
- if (visible != columnFootersVisible) {
- columnFootersVisible = visible;
- requestRepaint();
- }
- }
-
- /**
- * Is the footer currently visible?
- *
- * @return Returns true if visible else false
- */
- public boolean isFooterVisible() {
- return columnFootersVisible;
- }
-
- /**
- * This event is fired when a column is resized. The event contains the
- * columns property id which was fired, the previous width of the column and
- * the width of the column after the resize.
- */
- public static class ColumnResizeEvent extends Component.Event {
- public static final Method COLUMN_RESIZE_METHOD;
-
- static {
- try {
- COLUMN_RESIZE_METHOD = ColumnResizeListener.class
- .getDeclaredMethod("columnResize",
- new Class[] { ColumnResizeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(e);
- }
- }
-
- private final int previousWidth;
- private final int currentWidth;
- private final Object columnPropertyId;
-
- /**
- * Constructor
- *
- * @param source
- * The source of the event
- * @param propertyId
- * The columns property id
- * @param previous
- * The width in pixels of the column before the resize event
- * @param current
- * The width in pixels of the column after the resize event
- */
- public ColumnResizeEvent(Component source, Object propertyId,
- int previous, int current) {
- super(source);
- previousWidth = previous;
- currentWidth = current;
- columnPropertyId = propertyId;
- }
-
- /**
- * Get the column property id of the column that was resized.
- *
- * @return The column property id
- */
- public Object getPropertyId() {
- return columnPropertyId;
- }
-
- /**
- * Get the width in pixels of the column before the resize event
- *
- * @return Width in pixels
- */
- public int getPreviousWidth() {
- return previousWidth;
- }
-
- /**
- * Get the width in pixels of the column after the resize event
- *
- * @return Width in pixels
- */
- public int getCurrentWidth() {
- return currentWidth;
- }
- }
-
- /**
- * Interface for listening to column resize events.
- */
- public interface ColumnResizeListener extends Serializable {
-
- /**
- * This method is triggered when the column has been resized
- *
- * @param event
- * The event which contains the column property id, the
- * previous width of the column and the current width of the
- * column
- */
- public void columnResize(ColumnResizeEvent event);
- }
-
- /**
- * Adds a column resize listener to the Table. A column resize listener is
- * called when a user resizes a columns width.
- *
- * @param listener
- * The listener to attach to the Table
- */
- public void addListener(ColumnResizeListener listener) {
- addListener(VScrollTable.COLUMN_RESIZE_EVENT_ID,
- ColumnResizeEvent.class, listener,
- ColumnResizeEvent.COLUMN_RESIZE_METHOD);
- }
-
- /**
- * Removes a column resize listener from the Table.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(ColumnResizeListener listener) {
- removeListener(VScrollTable.COLUMN_RESIZE_EVENT_ID,
- ColumnResizeEvent.class, listener);
- }
-
- /**
- * This event is fired when a columns are reordered by the end user user.
- */
- public static class ColumnReorderEvent extends Component.Event {
- public static final Method METHOD;
-
- static {
- try {
- METHOD = ColumnReorderListener.class.getDeclaredMethod(
- "columnReorder",
- new Class[] { ColumnReorderEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(e);
- }
- }
-
- /**
- * Constructor
- *
- * @param source
- * The source of the event
- */
- public ColumnReorderEvent(Component source) {
- super(source);
- }
-
- }
-
- /**
- * Interface for listening to column reorder events.
- */
- public interface ColumnReorderListener extends Serializable {
-
- /**
- * This method is triggered when the column has been reordered
- *
- * @param event
- */
- public void columnReorder(ColumnReorderEvent event);
- }
-
- /**
- * Adds a column reorder listener to the Table. A column reorder listener is
- * called when a user reorders columns.
- *
- * @param listener
- * The listener to attach to the Table
- */
- public void addListener(ColumnReorderListener listener) {
- addListener(VScrollTable.COLUMN_REORDER_EVENT_ID,
- ColumnReorderEvent.class, listener, ColumnReorderEvent.METHOD);
- }
-
- /**
- * Removes a column reorder listener from the Table.
- *
- * @param listener
- * The listener to remove
- */
- public void removeListener(ColumnReorderListener listener) {
- removeListener(VScrollTable.COLUMN_REORDER_EVENT_ID,
- ColumnReorderEvent.class, listener);
- }
-
- /**
- * Set the item description generator which generates tooltips for cells and
- * rows in the Table
- *
- * @param generator
- * The generator to use or null to disable
- */
- public void setItemDescriptionGenerator(ItemDescriptionGenerator generator) {
- if (generator != itemDescriptionGenerator) {
- itemDescriptionGenerator = generator;
- // Assures the visual refresh. No need to reset the page buffer
- // before as the content has not changed, only the descriptions
- refreshRenderedCells();
- }
- }
-
- /**
- * Get the item description generator which generates tooltips for cells and
- * rows in the Table.
- */
- public ItemDescriptionGenerator getItemDescriptionGenerator() {
- return itemDescriptionGenerator;
- }
-
- /**
- * Row generators can be used to replace certain items in a table with a
- * generated string. The generator is called each time the table is
- * rendered, which means that new strings can be generated each time.
- *
- * Row generators can be used for e.g. summary rows or grouping of items.
- */
- public interface RowGenerator extends Serializable {
- /**
- * Called for every row that is painted in the Table. Returning a
- * GeneratedRow object will cause the row to be painted based on the
- * contents of the GeneratedRow. A generated row is by default styled
- * similarly to a header or footer row.
- * <p>
- * The GeneratedRow data object contains the text that should be
- * rendered in the row. The itemId in the container thus works only as a
- * placeholder.
- * <p>
- * If GeneratedRow.setSpanColumns(true) is used, there will be one
- * String spanning all columns (use setText("Spanning text")). Otherwise
- * you can define one String per visible column.
- * <p>
- * If GeneratedRow.setRenderAsHtml(true) is used, the strings can
- * contain HTML markup, otherwise all strings will be rendered as text
- * (the default).
- * <p>
- * A "v-table-generated-row" CSS class is added to all generated rows.
- * For custom styling of a generated row you can combine a RowGenerator
- * with a CellStyleGenerator.
- * <p>
- *
- * @param table
- * The Table that is being painted
- * @param itemId
- * The itemId for the row
- * @return A GeneratedRow describing how the row should be painted or
- * null to paint the row with the contents from the container
- */
- public GeneratedRow generateRow(Table table, Object itemId);
- }
-
- public static class GeneratedRow implements Serializable {
- private boolean htmlContentAllowed = false;
- private boolean spanColumns = false;
- private String[] text = null;
-
- /**
- * Creates a new generated row. If only one string is passed in, columns
- * are automatically spanned.
- *
- * @param text
- */
- public GeneratedRow(String... text) {
- setHtmlContentAllowed(false);
- setSpanColumns(text == null || text.length == 1);
- setText(text);
- }
-
- /**
- * Pass one String if spanColumns is used, one String for each visible
- * column otherwise
- */
- public void setText(String... text) {
- if (text == null || (text.length == 1 && text[0] == null)) {
- text = new String[] { "" };
- }
- this.text = text;
- }
-
- protected String[] getText() {
- return text;
- }
-
- protected Object getValue() {
- return getText();
- }
-
- protected boolean isHtmlContentAllowed() {
- return htmlContentAllowed;
- }
-
- /**
- * If set to true, all strings passed to {@link #setText(String...)}
- * will be rendered as HTML.
- *
- * @param htmlContentAllowed
- */
- public void setHtmlContentAllowed(boolean htmlContentAllowed) {
- this.htmlContentAllowed = htmlContentAllowed;
- }
-
- protected boolean isSpanColumns() {
- return spanColumns;
- }
-
- /**
- * If set to true, only one string will be rendered, spanning the entire
- * row.
- *
- * @param spanColumns
- */
- public void setSpanColumns(boolean spanColumns) {
- this.spanColumns = spanColumns;
- }
- }
-
- /**
- * Assigns a row generator to the table. The row generator will be able to
- * replace rows in the table when it is rendered.
- *
- * @param generator
- * the new row generator
- */
- public void setRowGenerator(RowGenerator generator) {
- rowGenerator = generator;
- refreshRowCache();
- }
-
- /**
- * @return the current row generator
- */
- public RowGenerator getRowGenerator() {
- return rowGenerator;
- }
-
- /**
- * Sets a converter for a property id.
- * <p>
- * The converter is used to format the the data for the given property id
- * before displaying it in the table.
- * </p>
- *
- * @param propertyId
- * The propertyId to format using the converter
- * @param converter
- * The converter to use for the property id
- */
- public void setConverter(Object propertyId, Converter<String, ?> converter) {
- if (!getContainerPropertyIds().contains(propertyId)) {
- throw new IllegalArgumentException("PropertyId " + propertyId
- + " must be in the container");
- }
- // FIXME: This check should be here but primitive types like Boolean
- // formatter for boolean property must be handled
-
- // if (!converter.getSourceType().isAssignableFrom(getType(propertyId)))
- // {
- // throw new IllegalArgumentException("Property type ("
- // + getType(propertyId)
- // + ") must match converter source type ("
- // + converter.getSourceType() + ")");
- // }
- propertyValueConverters.put(propertyId,
- (Converter<String, Object>) converter);
- refreshRowCache();
- }
-
- /**
- * Checks if there is a converter set explicitly for the given property id.
- *
- * @param propertyId
- * The propertyId to check
- * @return true if a converter has been set for the property id, false
- * otherwise
- */
- protected boolean hasConverter(Object propertyId) {
- return propertyValueConverters.containsKey(propertyId);
- }
-
- /**
- * Returns the converter used to format the given propertyId.
- *
- * @param propertyId
- * The propertyId to check
- * @return The converter used to format the propertyId or null if no
- * converter has been set
- */
- public Converter<String, Object> getConverter(Object propertyId) {
- return propertyValueConverters.get(propertyId);
- }
-
- @Override
- public void setVisible(boolean visible) {
- if (visible) {
- // We need to ensure that the rows are sent to the client when the
- // Table is made visible if it has been rendered as invisible.
- setRowCacheInvalidated(true);
- }
- super.setVisible(visible);
- }
-
- @Override
- public Iterator<Component> iterator() {
- return getComponentIterator();
- }
-
- @Override
- public Iterator<Component> getComponentIterator() {
- if (visibleComponents == null) {
- Collection<Component> empty = Collections.emptyList();
- return empty.iterator();
- }
-
- return visibleComponents.iterator();
- }
-
- @Override
- public boolean isComponentVisible(Component childComponent) {
- return true;
- }
-
- private final Logger getLogger() {
- if (logger == null) {
- logger = Logger.getLogger(Table.class.getName());
- }
- return logger;
- }
-}
diff --git a/src/com/vaadin/ui/TableFieldFactory.java b/src/com/vaadin/ui/TableFieldFactory.java
deleted file mode 100644
index 6c9a641aa8..0000000000
--- a/src/com/vaadin/ui/TableFieldFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-import com.vaadin.data.Container;
-
-/**
- * Factory interface for creating new Field-instances based on Container
- * (datasource), item id, property id and uiContext (the component responsible
- * for displaying fields). Currently this interface is used by {@link Table},
- * but might later be used by some other components for {@link Field}
- * generation.
- *
- * <p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 6.0
- * @see FormFieldFactory
- */
-public interface TableFieldFactory extends Serializable {
- /**
- * Creates a field based on the Container, item id, property id and the
- * component responsible for displaying the field (most commonly
- * {@link Table}).
- *
- * @param container
- * the Container where the property belongs to.
- * @param itemId
- * the item Id.
- * @param propertyId
- * the Id of the property.
- * @param uiContext
- * the component where the field is presented.
- * @return A field suitable for editing the specified data or null if the
- * property should not be editable.
- */
- Field<?> createField(Container container, Object itemId, Object propertyId,
- Component uiContext);
-
-}
diff --git a/src/com/vaadin/ui/TextArea.java b/src/com/vaadin/ui/TextArea.java
deleted file mode 100644
index d7837dd33f..0000000000
--- a/src/com/vaadin/ui/TextArea.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.data.Property;
-import com.vaadin.shared.ui.textarea.TextAreaState;
-
-/**
- * A text field that supports multi line editing.
- */
-public class TextArea extends AbstractTextField {
-
- /**
- * Constructs an empty TextArea.
- */
- public TextArea() {
- setValue("");
- }
-
- /**
- * Constructs an empty TextArea with given caption.
- *
- * @param caption
- * the caption for the field.
- */
- public TextArea(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Constructs a TextArea with given property data source.
- *
- * @param dataSource
- * the data source for the field
- */
- public TextArea(Property dataSource) {
- this();
- setPropertyDataSource(dataSource);
- }
-
- /**
- * Constructs a TextArea with given caption and property data source.
- *
- * @param caption
- * the caption for the field
- * @param dataSource
- * the data source for the field
- */
- public TextArea(String caption, Property dataSource) {
- this(dataSource);
- setCaption(caption);
- }
-
- /**
- * Constructs a TextArea with given caption and value.
- *
- * @param caption
- * the caption for the field
- * @param value
- * the value for the field
- */
- public TextArea(String caption, String value) {
- this(caption);
- setValue(value);
-
- }
-
- @Override
- public TextAreaState getState() {
- return (TextAreaState) super.getState();
- }
-
- /**
- * Sets the number of rows in the text area.
- *
- * @param rows
- * the number of rows for this text area.
- */
- public void setRows(int rows) {
- if (rows < 0) {
- rows = 0;
- }
- getState().setRows(rows);
- requestRepaint();
- }
-
- /**
- * Gets the number of rows in the text area.
- *
- * @return number of explicitly set rows.
- */
- public int getRows() {
- return getState().getRows();
- }
-
- /**
- * Sets the text area's word-wrap mode on or off.
- *
- * @param wordwrap
- * the boolean value specifying if the text area should be in
- * word-wrap mode.
- */
- public void setWordwrap(boolean wordwrap) {
- getState().setWordwrap(wordwrap);
- requestRepaint();
- }
-
- /**
- * Tests if the text area is in word-wrap mode.
- *
- * @return <code>true</code> if the component is in word-wrap mode,
- * <code>false</code> if not.
- */
- public boolean isWordwrap() {
- return getState().isWordwrap();
- }
-
-}
diff --git a/src/com/vaadin/ui/TextField.java b/src/com/vaadin/ui/TextField.java
deleted file mode 100644
index 567e9c1c10..0000000000
--- a/src/com/vaadin/ui/TextField.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.data.Property;
-
-/**
- * <p>
- * A text editor component that can be bound to any bindable Property. The text
- * editor supports both multiline and single line modes, default is one-line
- * mode.
- * </p>
- *
- * <p>
- * Since <code>TextField</code> extends <code>AbstractField</code> it implements
- * the {@link com.vaadin.data.Buffered} interface. A <code>TextField</code> is
- * in write-through mode by default, so
- * {@link com.vaadin.ui.AbstractField#setWriteThrough(boolean)} must be called
- * to enable buffering.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class TextField extends AbstractTextField {
-
- /**
- * Constructs an empty <code>TextField</code> with no caption.
- */
- public TextField() {
- setValue("");
- }
-
- /**
- * Constructs an empty <code>TextField</code> with given caption.
- *
- * @param caption
- * the caption <code>String</code> for the editor.
- */
- public TextField(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>TextField</code> that's bound to the specified
- * <code>Property</code> and has no caption.
- *
- * @param dataSource
- * the Property to be edited with this editor.
- */
- public TextField(Property dataSource) {
- setPropertyDataSource(dataSource);
- }
-
- /**
- * Constructs a new <code>TextField</code> that's bound to the specified
- * <code>Property</code> and has the given caption <code>String</code>.
- *
- * @param caption
- * the caption <code>String</code> for the editor.
- * @param dataSource
- * the Property to be edited with this editor.
- */
- public TextField(String caption, Property dataSource) {
- this(dataSource);
- setCaption(caption);
- }
-
- /**
- * Constructs a new <code>TextField</code> with the given caption and
- * initial text contents. The editor constructed this way will not be bound
- * to a Property unless
- * {@link com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)}
- * is called to bind it.
- *
- * @param caption
- * the caption <code>String</code> for the editor.
- * @param value
- * the initial text content of the editor.
- */
- public TextField(String caption, String value) {
- setValue(value);
- setCaption(caption);
- }
-
-}
diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java
deleted file mode 100644
index c15975d879..0000000000
--- a/src/com/vaadin/ui/Tree.java
+++ /dev/null
@@ -1,1615 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.StringTokenizer;
-
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.util.ContainerHierarchicalWrapper;
-import com.vaadin.data.util.IndexedContainer;
-import com.vaadin.event.Action;
-import com.vaadin.event.Action.Handler;
-import com.vaadin.event.DataBoundTransferable;
-import com.vaadin.event.ItemClickEvent;
-import com.vaadin.event.ItemClickEvent.ItemClickListener;
-import com.vaadin.event.ItemClickEvent.ItemClickNotifier;
-import com.vaadin.event.Transferable;
-import com.vaadin.event.dd.DragAndDropEvent;
-import com.vaadin.event.dd.DragSource;
-import com.vaadin.event.dd.DropHandler;
-import com.vaadin.event.dd.DropTarget;
-import com.vaadin.event.dd.TargetDetails;
-import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion;
-import com.vaadin.event.dd.acceptcriteria.ServerSideCriterion;
-import com.vaadin.event.dd.acceptcriteria.TargetDetailIs;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.dd.VerticalDropLocation;
-import com.vaadin.terminal.KeyMapper;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.tree.TreeConnector;
-import com.vaadin.terminal.gwt.client.ui.tree.VTree;
-import com.vaadin.tools.ReflectTools;
-
-/**
- * Tree component. A Tree can be used to select an item (or multiple items) from
- * a hierarchical set of items.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings({ "serial", "deprecation" })
-public class Tree extends AbstractSelect implements Container.Hierarchical,
- Action.Container, ItemClickNotifier, DragSource, DropTarget {
-
- /* Private members */
-
- /**
- * Set of expanded nodes.
- */
- private final HashSet<Object> expanded = new HashSet<Object>();
-
- /**
- * List of action handlers.
- */
- private LinkedList<Action.Handler> actionHandlers = null;
-
- /**
- * Action mapper.
- */
- private KeyMapper<Action> actionMapper = null;
-
- /**
- * Is the tree selectable on the client side.
- */
- private boolean selectable = true;
-
- /**
- * Flag to indicate sub-tree loading
- */
- private boolean partialUpdate = false;
-
- /**
- * Holds a itemId which was recently expanded
- */
- private Object expandedItemId;
-
- /**
- * a flag which indicates initial paint. After this flag set true partial
- * updates are allowed.
- */
- private boolean initialPaint = true;
-
- /**
- * Item tooltip generator
- */
- private ItemDescriptionGenerator itemDescriptionGenerator;
-
- /**
- * Supported drag modes for Tree.
- */
- public enum TreeDragMode {
- /**
- * When drag mode is NONE, dragging from Tree is not supported. Browsers
- * may still support selecting text/icons from Tree which can initiate
- * HTML 5 style drag and drop operation.
- */
- NONE,
- /**
- * When drag mode is NODE, users can initiate drag from Tree nodes that
- * represent {@link Item}s in from the backed {@link Container}.
- */
- NODE
- // , SUBTREE
- }
-
- private TreeDragMode dragMode = TreeDragMode.NONE;
-
- private MultiSelectMode multiSelectMode = MultiSelectMode.DEFAULT;
-
- /* Tree constructors */
-
- /**
- * Creates a new empty tree.
- */
- public Tree() {
- }
-
- /**
- * Creates a new empty tree with caption.
- *
- * @param caption
- */
- public Tree(String caption) {
- setCaption(caption);
- }
-
- /**
- * Creates a new tree with caption and connect it to a Container.
- *
- * @param caption
- * @param dataSource
- */
- public Tree(String caption, Container dataSource) {
- setCaption(caption);
- setContainerDataSource(dataSource);
- }
-
- /* Expanding and collapsing */
-
- /**
- * Check is an item is expanded
- *
- * @param itemId
- * the item id.
- * @return true iff the item is expanded.
- */
- public boolean isExpanded(Object itemId) {
- return expanded.contains(itemId);
- }
-
- /**
- * Expands an item.
- *
- * @param itemId
- * the item id.
- * @return True iff the expand operation succeeded
- */
- public boolean expandItem(Object itemId) {
- boolean success = expandItem(itemId, true);
- requestRepaint();
- return success;
- }
-
- /**
- * Expands an item.
- *
- * @param itemId
- * the item id.
- * @param sendChildTree
- * flag to indicate if client needs subtree or not (may be
- * cached)
- * @return True iff the expand operation succeeded
- */
- private boolean expandItem(Object itemId, boolean sendChildTree) {
-
- // Succeeds if the node is already expanded
- if (isExpanded(itemId)) {
- return true;
- }
-
- // Nodes that can not have children are not expandable
- if (!areChildrenAllowed(itemId)) {
- return false;
- }
-
- // Expands
- expanded.add(itemId);
-
- expandedItemId = itemId;
- if (initialPaint) {
- requestRepaint();
- } else if (sendChildTree) {
- requestPartialRepaint();
- }
- fireExpandEvent(itemId);
-
- return true;
- }
-
- @Override
- public void requestRepaint() {
- super.requestRepaint();
- partialUpdate = false;
- }
-
- private void requestPartialRepaint() {
- super.requestRepaint();
- partialUpdate = true;
- }
-
- /**
- * Expands the items recursively
- *
- * Expands all the children recursively starting from an item. Operation
- * succeeds only if all expandable items are expanded.
- *
- * @param startItemId
- * @return True iff the expand operation succeeded
- */
- public boolean expandItemsRecursively(Object startItemId) {
-
- boolean result = true;
-
- // Initial stack
- final Stack<Object> todo = new Stack<Object>();
- todo.add(startItemId);
-
- // Expands recursively
- while (!todo.isEmpty()) {
- final Object id = todo.pop();
- if (areChildrenAllowed(id) && !expandItem(id, false)) {
- result = false;
- }
- if (hasChildren(id)) {
- todo.addAll(getChildren(id));
- }
- }
- requestRepaint();
- return result;
- }
-
- /**
- * Collapses an item.
- *
- * @param itemId
- * the item id.
- * @return True iff the collapse operation succeeded
- */
- public boolean collapseItem(Object itemId) {
-
- // Succeeds if the node is already collapsed
- if (!isExpanded(itemId)) {
- return true;
- }
-
- // Collapse
- expanded.remove(itemId);
- requestRepaint();
- fireCollapseEvent(itemId);
-
- return true;
- }
-
- /**
- * Collapses the items recursively.
- *
- * Collapse all the children recursively starting from an item. Operation
- * succeeds only if all expandable items are collapsed.
- *
- * @param startItemId
- * @return True iff the collapse operation succeeded
- */
- public boolean collapseItemsRecursively(Object startItemId) {
-
- boolean result = true;
-
- // Initial stack
- final Stack<Object> todo = new Stack<Object>();
- todo.add(startItemId);
-
- // Collapse recursively
- while (!todo.isEmpty()) {
- final Object id = todo.pop();
- if (areChildrenAllowed(id) && !collapseItem(id)) {
- result = false;
- }
- if (hasChildren(id)) {
- todo.addAll(getChildren(id));
- }
- }
-
- return result;
- }
-
- /**
- * Returns the current selectable state. Selectable determines if the a node
- * can be selected on the client side. Selectable does not affect
- * {@link #setValue(Object)} or {@link #select(Object)}.
- *
- * <p>
- * The tree is selectable by default.
- * </p>
- *
- * @return the current selectable state.
- */
- public boolean isSelectable() {
- return selectable;
- }
-
- /**
- * Sets the selectable state. Selectable determines if the a node can be
- * selected on the client side. Selectable does not affect
- * {@link #setValue(Object)} or {@link #select(Object)}.
- *
- * <p>
- * The tree is selectable by default.
- * </p>
- *
- * @param selectable
- * The new selectable state.
- */
- public void setSelectable(boolean selectable) {
- if (this.selectable != selectable) {
- this.selectable = selectable;
- requestRepaint();
- }
- }
-
- /**
- * Sets the behavior of the multiselect mode
- *
- * @param mode
- * The mode to set
- */
- public void setMultiselectMode(MultiSelectMode mode) {
- if (multiSelectMode != mode && mode != null) {
- multiSelectMode = mode;
- requestRepaint();
- }
- }
-
- /**
- * Returns the mode the multiselect is in. The mode controls how
- * multiselection can be done.
- *
- * @return The mode
- */
- public MultiSelectMode getMultiselectMode() {
- return multiSelectMode;
- }
-
- /* Component API */
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.AbstractSelect#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
-
- if (variables.containsKey("clickedKey")) {
- String key = (String) variables.get("clickedKey");
-
- Object id = itemIdMapper.get(key);
- MouseEventDetails details = MouseEventDetails
- .deSerialize((String) variables.get("clickEvent"));
- Item item = getItem(id);
- if (item != null) {
- fireEvent(new ItemClickEvent(this, item, id, null, details));
- }
- }
-
- if (!isSelectable() && variables.containsKey("selected")) {
- // Not-selectable is a special case, AbstractSelect does not support
- // TODO could be optimized.
- variables = new HashMap<String, Object>(variables);
- variables.remove("selected");
- }
-
- // Collapses the nodes
- if (variables.containsKey("collapse")) {
- final String[] keys = (String[]) variables.get("collapse");
- for (int i = 0; i < keys.length; i++) {
- final Object id = itemIdMapper.get(keys[i]);
- if (id != null && isExpanded(id)) {
- expanded.remove(id);
- fireCollapseEvent(id);
- }
- }
- }
-
- // Expands the nodes
- if (variables.containsKey("expand")) {
- boolean sendChildTree = false;
- if (variables.containsKey("requestChildTree")) {
- sendChildTree = true;
- }
- final String[] keys = (String[]) variables.get("expand");
- for (int i = 0; i < keys.length; i++) {
- final Object id = itemIdMapper.get(keys[i]);
- if (id != null) {
- expandItem(id, sendChildTree);
- }
- }
- }
-
- // AbstractSelect cannot handle multiselection so we handle
- // it ourself
- if (variables.containsKey("selected") && isMultiSelect()
- && multiSelectMode == MultiSelectMode.DEFAULT) {
- handleSelectedItems(variables);
- variables = new HashMap<String, Object>(variables);
- variables.remove("selected");
- }
-
- // Selections are handled by the select component
- super.changeVariables(source, variables);
-
- // Actions
- if (variables.containsKey("action")) {
- final StringTokenizer st = new StringTokenizer(
- (String) variables.get("action"), ",");
- if (st.countTokens() == 2) {
- final Object itemId = itemIdMapper.get(st.nextToken());
- final Action action = actionMapper.get(st.nextToken());
- if (action != null && (itemId == null || containsId(itemId))
- && actionHandlers != null) {
- for (Handler ah : actionHandlers) {
- ah.handleAction(action, this, itemId);
- }
- }
- }
- }
- }
-
- /**
- * Handles the selection
- *
- * @param variables
- * The variables sent to the server from the client
- */
- private void handleSelectedItems(Map<String, Object> variables) {
- final String[] ka = (String[]) variables.get("selected");
-
- // Converts the key-array to id-set
- final LinkedList<Object> s = new LinkedList<Object>();
- for (int i = 0; i < ka.length; i++) {
- final Object id = itemIdMapper.get(ka[i]);
- if (!isNullSelectionAllowed()
- && (id == null || id == getNullSelectionItemId())) {
- // skip empty selection if nullselection is not allowed
- requestRepaint();
- } else if (id != null && containsId(id)) {
- s.add(id);
- }
- }
-
- if (!isNullSelectionAllowed() && s.size() < 1) {
- // empty selection not allowed, keep old value
- requestRepaint();
- return;
- }
-
- setValue(s, true);
- }
-
- /**
- * Paints any needed component-specific things to the given UIDL stream.
- *
- * @see com.vaadin.ui.AbstractComponent#paintContent(PaintTarget)
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- initialPaint = false;
-
- if (partialUpdate) {
- target.addAttribute("partialUpdate", true);
- target.addAttribute("rootKey", itemIdMapper.key(expandedItemId));
- } else {
- getCaptionChangeListener().clear();
-
- // The tab ordering number
- if (getTabIndex() > 0) {
- target.addAttribute("tabindex", getTabIndex());
- }
-
- // Paint tree attributes
- if (isSelectable()) {
- target.addAttribute("selectmode", (isMultiSelect() ? "multi"
- : "single"));
- if (isMultiSelect()) {
- target.addAttribute("multiselectmode",
- multiSelectMode.ordinal());
- }
- } else {
- target.addAttribute("selectmode", "none");
- }
- if (isNewItemsAllowed()) {
- target.addAttribute("allownewitem", true);
- }
-
- if (isNullSelectionAllowed()) {
- target.addAttribute("nullselect", true);
- }
-
- if (dragMode != TreeDragMode.NONE) {
- target.addAttribute("dragMode", dragMode.ordinal());
- }
-
- }
-
- // Initialize variables
- final Set<Action> actionSet = new LinkedHashSet<Action>();
-
- // rendered selectedKeys
- LinkedList<String> selectedKeys = new LinkedList<String>();
-
- final LinkedList<String> expandedKeys = new LinkedList<String>();
-
- // Iterates through hierarchical tree using a stack of iterators
- final Stack<Iterator<?>> iteratorStack = new Stack<Iterator<?>>();
- Collection<?> ids;
- if (partialUpdate) {
- ids = getChildren(expandedItemId);
- } else {
- ids = rootItemIds();
- }
-
- if (ids != null) {
- iteratorStack.push(ids.iterator());
- }
-
- /*
- * Body actions - Actions which has the target null and can be invoked
- * by right clicking on the Tree body
- */
- if (actionHandlers != null) {
- final ArrayList<String> keys = new ArrayList<String>();
- for (Handler ah : actionHandlers) {
-
- // Getting action for the null item, which in this case
- // means the body item
- final Action[] aa = ah.getActions(null, this);
- if (aa != null) {
- for (int ai = 0; ai < aa.length; ai++) {
- final String akey = actionMapper.key(aa[ai]);
- actionSet.add(aa[ai]);
- keys.add(akey);
- }
- }
- }
- target.addAttribute("alb", keys.toArray());
- }
-
- while (!iteratorStack.isEmpty()) {
-
- // Gets the iterator for current tree level
- final Iterator<?> i = iteratorStack.peek();
-
- // If the level is finished, back to previous tree level
- if (!i.hasNext()) {
-
- // Removes used iterator from the stack
- iteratorStack.pop();
-
- // Closes node
- if (!iteratorStack.isEmpty()) {
- target.endTag("node");
- }
- }
-
- // Adds the item on current level
- else {
- final Object itemId = i.next();
-
- // Starts the item / node
- final boolean isNode = areChildrenAllowed(itemId);
- if (isNode) {
- target.startTag("node");
- } else {
- target.startTag("leaf");
- }
-
- if (itemStyleGenerator != null) {
- String stylename = itemStyleGenerator.getStyle(itemId);
- if (stylename != null) {
- target.addAttribute(TreeConnector.ATTRIBUTE_NODE_STYLE,
- stylename);
- }
- }
-
- if (itemDescriptionGenerator != null) {
- String description = itemDescriptionGenerator
- .generateDescription(this, itemId, null);
- if (description != null && !description.equals("")) {
- target.addAttribute("descr", description);
- }
- }
-
- // Adds the attributes
- target.addAttribute(TreeConnector.ATTRIBUTE_NODE_CAPTION,
- getItemCaption(itemId));
- final Resource icon = getItemIcon(itemId);
- if (icon != null) {
- target.addAttribute(TreeConnector.ATTRIBUTE_NODE_ICON,
- getItemIcon(itemId));
- }
- final String key = itemIdMapper.key(itemId);
- target.addAttribute("key", key);
- if (isSelected(itemId)) {
- target.addAttribute("selected", true);
- selectedKeys.add(key);
- }
- if (areChildrenAllowed(itemId) && isExpanded(itemId)) {
- target.addAttribute("expanded", true);
- expandedKeys.add(key);
- }
-
- // Add caption change listener
- getCaptionChangeListener().addNotifierForItem(itemId);
-
- // Actions
- if (actionHandlers != null) {
- final ArrayList<String> keys = new ArrayList<String>();
- final Iterator<Action.Handler> ahi = actionHandlers
- .iterator();
- while (ahi.hasNext()) {
- final Action[] aa = ahi.next().getActions(itemId, this);
- if (aa != null) {
- for (int ai = 0; ai < aa.length; ai++) {
- final String akey = actionMapper.key(aa[ai]);
- actionSet.add(aa[ai]);
- keys.add(akey);
- }
- }
- }
- target.addAttribute("al", keys.toArray());
- }
-
- // Adds the children if expanded, or close the tag
- if (isExpanded(itemId) && hasChildren(itemId)
- && areChildrenAllowed(itemId)) {
- iteratorStack.push(getChildren(itemId).iterator());
- } else {
- if (isNode) {
- target.endTag("node");
- } else {
- target.endTag("leaf");
- }
- }
- }
- }
-
- // Actions
- if (!actionSet.isEmpty()) {
- target.addVariable(this, "action", "");
- target.startTag("actions");
- final Iterator<Action> i = actionSet.iterator();
- while (i.hasNext()) {
- final Action a = i.next();
- target.startTag("action");
- if (a.getCaption() != null) {
- target.addAttribute(TreeConnector.ATTRIBUTE_ACTION_CAPTION,
- a.getCaption());
- }
- if (a.getIcon() != null) {
- target.addAttribute(TreeConnector.ATTRIBUTE_ACTION_ICON,
- a.getIcon());
- }
- target.addAttribute("key", actionMapper.key(a));
- target.endTag("action");
- }
- target.endTag("actions");
- }
-
- if (partialUpdate) {
- partialUpdate = false;
- } else {
- // Selected
- target.addVariable(this, "selected",
- selectedKeys.toArray(new String[selectedKeys.size()]));
-
- // Expand and collapse
- target.addVariable(this, "expand", new String[] {});
- target.addVariable(this, "collapse", new String[] {});
-
- // New items
- target.addVariable(this, "newitem", new String[] {});
-
- if (dropHandler != null) {
- dropHandler.getAcceptCriterion().paint(target);
- }
-
- }
- }
-
- /* Container.Hierarchical API */
-
- /**
- * Tests if the Item with given ID can have any children.
- *
- * @see com.vaadin.data.Container.Hierarchical#areChildrenAllowed(Object)
- */
- @Override
- public boolean areChildrenAllowed(Object itemId) {
- return ((Container.Hierarchical) items).areChildrenAllowed(itemId);
- }
-
- /**
- * Gets the IDs of all Items that are children of the specified Item.
- *
- * @see com.vaadin.data.Container.Hierarchical#getChildren(Object)
- */
- @Override
- public Collection<?> getChildren(Object itemId) {
- return ((Container.Hierarchical) items).getChildren(itemId);
- }
-
- /**
- * Gets the ID of the parent Item of the specified Item.
- *
- * @see com.vaadin.data.Container.Hierarchical#getParent(Object)
- */
- @Override
- public Object getParent(Object itemId) {
- return ((Container.Hierarchical) items).getParent(itemId);
- }
-
- /**
- * Tests if the Item specified with <code>itemId</code> has child Items.
- *
- * @see com.vaadin.data.Container.Hierarchical#hasChildren(Object)
- */
- @Override
- public boolean hasChildren(Object itemId) {
- return ((Container.Hierarchical) items).hasChildren(itemId);
- }
-
- /**
- * Tests if the Item specified with <code>itemId</code> is a root Item.
- *
- * @see com.vaadin.data.Container.Hierarchical#isRoot(Object)
- */
- @Override
- public boolean isRoot(Object itemId) {
- return ((Container.Hierarchical) items).isRoot(itemId);
- }
-
- /**
- * Gets the IDs of all Items in the container that don't have a parent.
- *
- * @see com.vaadin.data.Container.Hierarchical#rootItemIds()
- */
- @Override
- public Collection<?> rootItemIds() {
- return ((Container.Hierarchical) items).rootItemIds();
- }
-
- /**
- * Sets the given Item's capability to have children.
- *
- * @see com.vaadin.data.Container.Hierarchical#setChildrenAllowed(Object,
- * boolean)
- */
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) {
- final boolean success = ((Container.Hierarchical) items)
- .setChildrenAllowed(itemId, areChildrenAllowed);
- if (success) {
- requestRepaint();
- }
- return success;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.data.Container.Hierarchical#setParent(java.lang.Object ,
- * java.lang.Object)
- */
- @Override
- public boolean setParent(Object itemId, Object newParentId) {
- final boolean success = ((Container.Hierarchical) items).setParent(
- itemId, newParentId);
- if (success) {
- requestRepaint();
- }
- return success;
- }
-
- /* Overriding select behavior */
-
- /**
- * Sets the Container that serves as the data source of the viewer.
- *
- * @see com.vaadin.data.Container.Viewer#setContainerDataSource(Container)
- */
- @Override
- public void setContainerDataSource(Container newDataSource) {
- if (newDataSource == null) {
- // Note: using wrapped IndexedContainer to match constructor (super
- // creates an IndexedContainer, which is then wrapped).
- newDataSource = new ContainerHierarchicalWrapper(
- new IndexedContainer());
- }
-
- // Assure that the data source is ordered by making unordered
- // containers ordered by wrapping them
- if (Container.Hierarchical.class.isAssignableFrom(newDataSource
- .getClass())) {
- super.setContainerDataSource(newDataSource);
- } else {
- super.setContainerDataSource(new ContainerHierarchicalWrapper(
- newDataSource));
- }
- }
-
- /* Expand event and listener */
-
- /**
- * Event to fired when a node is expanded. ExapandEvent is fired when a node
- * is to be expanded. it can me used to dynamically fill the sub-nodes of
- * the node.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class ExpandEvent extends Component.Event {
-
- private final Object expandedItemId;
-
- /**
- * New instance of options change event
- *
- * @param source
- * the Source of the event.
- * @param expandedItemId
- */
- public ExpandEvent(Component source, Object expandedItemId) {
- super(source);
- this.expandedItemId = expandedItemId;
- }
-
- /**
- * Node where the event occurred.
- *
- * @return the Source of the event.
- */
- public Object getItemId() {
- return expandedItemId;
- }
- }
-
- /**
- * Expand event listener.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface ExpandListener extends Serializable {
-
- public static final Method EXPAND_METHOD = ReflectTools.findMethod(
- ExpandListener.class, "nodeExpand", ExpandEvent.class);
-
- /**
- * A node has been expanded.
- *
- * @param event
- * the Expand event.
- */
- public void nodeExpand(ExpandEvent event);
- }
-
- /**
- * Adds the expand listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(ExpandListener listener) {
- addListener(ExpandEvent.class, listener, ExpandListener.EXPAND_METHOD);
- }
-
- /**
- * Removes the expand listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(ExpandListener listener) {
- removeListener(ExpandEvent.class, listener,
- ExpandListener.EXPAND_METHOD);
- }
-
- /**
- * Emits the expand event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireExpandEvent(Object itemId) {
- fireEvent(new ExpandEvent(this, itemId));
- }
-
- /* Collapse event */
-
- /**
- * Collapse event
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class CollapseEvent extends Component.Event {
-
- private final Object collapsedItemId;
-
- /**
- * New instance of options change event.
- *
- * @param source
- * the Source of the event.
- * @param collapsedItemId
- */
- public CollapseEvent(Component source, Object collapsedItemId) {
- super(source);
- this.collapsedItemId = collapsedItemId;
- }
-
- /**
- * Gets tge Collapsed Item id.
- *
- * @return the collapsed item id.
- */
- public Object getItemId() {
- return collapsedItemId;
- }
- }
-
- /**
- * Collapse event listener.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface CollapseListener extends Serializable {
-
- public static final Method COLLAPSE_METHOD = ReflectTools.findMethod(
- CollapseListener.class, "nodeCollapse", CollapseEvent.class);
-
- /**
- * A node has been collapsed.
- *
- * @param event
- * the Collapse event.
- */
- public void nodeCollapse(CollapseEvent event);
- }
-
- /**
- * Adds the collapse listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(CollapseListener listener) {
- addListener(CollapseEvent.class, listener,
- CollapseListener.COLLAPSE_METHOD);
- }
-
- /**
- * Removes the collapse listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(CollapseListener listener) {
- removeListener(CollapseEvent.class, listener,
- CollapseListener.COLLAPSE_METHOD);
- }
-
- /**
- * Emits collapse event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireCollapseEvent(Object itemId) {
- fireEvent(new CollapseEvent(this, itemId));
- }
-
- /* Action container */
-
- /**
- * Adds an action handler.
- *
- * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler)
- */
- @Override
- public void addActionHandler(Action.Handler actionHandler) {
-
- if (actionHandler != null) {
-
- if (actionHandlers == null) {
- actionHandlers = new LinkedList<Action.Handler>();
- actionMapper = new KeyMapper<Action>();
- }
-
- if (!actionHandlers.contains(actionHandler)) {
- actionHandlers.add(actionHandler);
- requestRepaint();
- }
- }
- }
-
- /**
- * Removes an action handler.
- *
- * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler)
- */
- @Override
- public void removeActionHandler(Action.Handler actionHandler) {
-
- if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
-
- actionHandlers.remove(actionHandler);
-
- if (actionHandlers.isEmpty()) {
- actionHandlers = null;
- actionMapper = null;
- }
-
- requestRepaint();
- }
- }
-
- /**
- * Removes all action handlers
- */
- public void removeAllActionHandlers() {
- actionHandlers = null;
- actionMapper = null;
- requestRepaint();
- }
-
- /**
- * Gets the visible item ids.
- *
- * @see com.vaadin.ui.Select#getVisibleItemIds()
- */
- @Override
- public Collection<?> getVisibleItemIds() {
-
- final LinkedList<Object> visible = new LinkedList<Object>();
-
- // Iterates trough hierarchical tree using a stack of iterators
- final Stack<Iterator<?>> iteratorStack = new Stack<Iterator<?>>();
- final Collection<?> ids = rootItemIds();
- if (ids != null) {
- iteratorStack.push(ids.iterator());
- }
- while (!iteratorStack.isEmpty()) {
-
- // Gets the iterator for current tree level
- final Iterator<?> i = iteratorStack.peek();
-
- // If the level is finished, back to previous tree level
- if (!i.hasNext()) {
-
- // Removes used iterator from the stack
- iteratorStack.pop();
- }
-
- // Adds the item on current level
- else {
- final Object itemId = i.next();
-
- visible.add(itemId);
-
- // Adds children if expanded, or close the tag
- if (isExpanded(itemId) && hasChildren(itemId)) {
- iteratorStack.push(getChildren(itemId).iterator());
- }
- }
- }
-
- return visible;
- }
-
- /**
- * Tree does not support <code>setNullSelectionItemId</code>.
- *
- * @see com.vaadin.ui.AbstractSelect#setNullSelectionItemId(java.lang.Object)
- */
- @Override
- public void setNullSelectionItemId(Object nullSelectionItemId)
- throws UnsupportedOperationException {
- if (nullSelectionItemId != null) {
- throw new UnsupportedOperationException();
- }
-
- }
-
- /**
- * Adding new items is not supported.
- *
- * @throws UnsupportedOperationException
- * if set to true.
- * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean)
- */
- @Override
- public void setNewItemsAllowed(boolean allowNewOptions)
- throws UnsupportedOperationException {
- if (allowNewOptions) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Tree does not support lazy options loading mode. Setting this true will
- * throw UnsupportedOperationException.
- *
- * @see com.vaadin.ui.Select#setLazyLoading(boolean)
- */
- public void setLazyLoading(boolean useLazyLoading) {
- if (useLazyLoading) {
- throw new UnsupportedOperationException(
- "Lazy options loading is not supported by Tree.");
- }
- }
-
- private ItemStyleGenerator itemStyleGenerator;
-
- private DropHandler dropHandler;
-
- @Override
- public void addListener(ItemClickListener listener) {
- addListener(VTree.ITEM_CLICK_EVENT_ID, ItemClickEvent.class, listener,
- ItemClickEvent.ITEM_CLICK_METHOD);
- }
-
- @Override
- public void removeListener(ItemClickListener listener) {
- removeListener(VTree.ITEM_CLICK_EVENT_ID, ItemClickEvent.class,
- listener);
- }
-
- /**
- * Sets the {@link ItemStyleGenerator} to be used with this tree.
- *
- * @param itemStyleGenerator
- * item style generator or null to remove generator
- */
- public void setItemStyleGenerator(ItemStyleGenerator itemStyleGenerator) {
- if (this.itemStyleGenerator != itemStyleGenerator) {
- this.itemStyleGenerator = itemStyleGenerator;
- requestRepaint();
- }
- }
-
- /**
- * @return the current {@link ItemStyleGenerator} for this tree. Null if
- * {@link ItemStyleGenerator} is not set.
- */
- public ItemStyleGenerator getItemStyleGenerator() {
- return itemStyleGenerator;
- }
-
- /**
- * ItemStyleGenerator can be used to add custom styles to tree items. The
- * CSS class name that will be added to the cell content is
- * <tt>v-tree-node-[style name]</tt>.
- */
- public interface ItemStyleGenerator extends Serializable {
-
- /**
- * Called by Tree when an item is painted.
- *
- * @param itemId
- * The itemId of the item to be painted
- * @return The style name to add to this item. (the CSS class name will
- * be v-tree-node-[style name]
- */
- public abstract String getStyle(Object itemId);
- }
-
- // Overriden so javadoc comes from Container.Hierarchical
- @Override
- public boolean removeItem(Object itemId)
- throws UnsupportedOperationException {
- return super.removeItem(itemId);
- }
-
- @Override
- public DropHandler getDropHandler() {
- return dropHandler;
- }
-
- public void setDropHandler(DropHandler dropHandler) {
- this.dropHandler = dropHandler;
- }
-
- /**
- * A {@link TargetDetails} implementation with Tree specific api.
- *
- * @since 6.3
- */
- public class TreeTargetDetails extends AbstractSelectTargetDetails {
-
- TreeTargetDetails(Map<String, Object> rawVariables) {
- super(rawVariables);
- }
-
- @Override
- public Tree getTarget() {
- return (Tree) super.getTarget();
- }
-
- /**
- * If the event is on a node that can not have children (see
- * {@link Tree#areChildrenAllowed(Object)}), this method returns the
- * parent item id of the target item (see {@link #getItemIdOver()} ).
- * The identifier of the parent node is also returned if the cursor is
- * on the top part of node. Else this method returns the same as
- * {@link #getItemIdOver()}.
- * <p>
- * In other words this method returns the identifier of the "folder"
- * into the drag operation is targeted.
- * <p>
- * If the method returns null, the current target is on a root node or
- * on other undefined area over the tree component.
- * <p>
- * The default Tree implementation marks the targetted tree node with
- * CSS classnames v-tree-node-dragfolder and
- * v-tree-node-caption-dragfolder (for the caption element).
- */
- public Object getItemIdInto() {
-
- Object itemIdOver = getItemIdOver();
- if (areChildrenAllowed(itemIdOver)
- && getDropLocation() == VerticalDropLocation.MIDDLE) {
- return itemIdOver;
- }
- return getParent(itemIdOver);
- }
-
- /**
- * If drop is targeted into "folder node" (see {@link #getItemIdInto()}
- * ), this method returns the item id of the node after the drag was
- * targeted. This method is useful when implementing drop into specific
- * location (between specific nodes) in tree.
- *
- * @return the id of the item after the user targets the drop or null if
- * "target" is a first item in node list (or the first in root
- * node list)
- */
- public Object getItemIdAfter() {
- Object itemIdOver = getItemIdOver();
- Object itemIdInto2 = getItemIdInto();
- if (itemIdOver.equals(itemIdInto2)) {
- return null;
- }
- VerticalDropLocation dropLocation = getDropLocation();
- if (VerticalDropLocation.TOP == dropLocation) {
- // if on top of the caption area, add before
- Collection<?> children;
- Object itemIdInto = getItemIdInto();
- if (itemIdInto != null) {
- // seek the previous from child list
- children = getChildren(itemIdInto);
- } else {
- children = rootItemIds();
- }
- Object ref = null;
- for (Object object : children) {
- if (object.equals(itemIdOver)) {
- return ref;
- }
- ref = object;
- }
- }
- return itemIdOver;
- }
-
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.DropTarget#translateDropTargetDetails(java.util.Map)
- */
- @Override
- public TreeTargetDetails translateDropTargetDetails(
- Map<String, Object> clientVariables) {
- return new TreeTargetDetails(clientVariables);
- }
-
- /**
- * Helper API for {@link TreeDropCriterion}
- *
- * @param itemId
- * @return
- */
- private String key(Object itemId) {
- return itemIdMapper.key(itemId);
- }
-
- /**
- * Sets the drag mode that controls how Tree behaves as a {@link DragSource}
- * .
- *
- * @param dragMode
- */
- public void setDragMode(TreeDragMode dragMode) {
- this.dragMode = dragMode;
- requestRepaint();
- }
-
- /**
- * @return the drag mode that controls how Tree behaves as a
- * {@link DragSource}.
- *
- * @see TreeDragMode
- */
- public TreeDragMode getDragMode() {
- return dragMode;
- }
-
- /**
- * Concrete implementation of {@link DataBoundTransferable} for data
- * transferred from a tree.
- *
- * @see {@link DataBoundTransferable}.
- *
- * @since 6.3
- */
- protected class TreeTransferable extends DataBoundTransferable {
-
- public TreeTransferable(Component sourceComponent,
- Map<String, Object> rawVariables) {
- super(sourceComponent, rawVariables);
- }
-
- @Override
- public Object getItemId() {
- return getData("itemId");
- }
-
- @Override
- public Object getPropertyId() {
- return getItemCaptionPropertyId();
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.event.dd.DragSource#getTransferable(java.util.Map)
- */
- @Override
- public Transferable getTransferable(Map<String, Object> payload) {
- TreeTransferable transferable = new TreeTransferable(this, payload);
- // updating drag source variables
- Object object = payload.get("itemId");
- if (object != null) {
- transferable.setData("itemId", itemIdMapper.get((String) object));
- }
-
- return transferable;
- }
-
- /**
- * Lazy loading accept criterion for Tree. Accepted target nodes are loaded
- * from server once per drag and drop operation. Developer must override one
- * method that decides accepted tree nodes for the whole Tree.
- *
- * <p>
- * Initially pretty much no data is sent to client. On first required
- * criterion check (per drag request) the client side data structure is
- * initialized from server and no subsequent requests requests are needed
- * during that drag and drop operation.
- */
- public static abstract class TreeDropCriterion extends ServerSideCriterion {
-
- private Tree tree;
-
- private Set<Object> allowedItemIds;
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptCriteria.ServerSideCriterion#getIdentifier
- * ()
- */
- @Override
- protected String getIdentifier() {
- return TreeDropCriterion.class.getCanonicalName();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptCriteria.AcceptCriterion#accepts(com.vaadin
- * .event.dd.DragAndDropEvent)
- */
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- AbstractSelectTargetDetails dropTargetData = (AbstractSelectTargetDetails) dragEvent
- .getTargetDetails();
- tree = (Tree) dragEvent.getTargetDetails().getTarget();
- allowedItemIds = getAllowedItemIds(dragEvent, tree);
-
- return allowedItemIds.contains(dropTargetData.getItemIdOver());
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.event.dd.acceptCriteria.AcceptCriterion#paintResponse(
- * com.vaadin.terminal.PaintTarget)
- */
- @Override
- public void paintResponse(PaintTarget target) throws PaintException {
- /*
- * send allowed nodes to client so subsequent requests can be
- * avoided
- */
- Object[] array = allowedItemIds.toArray();
- for (int i = 0; i < array.length; i++) {
- String key = tree.key(array[i]);
- array[i] = key;
- }
- target.addAttribute("allowedIds", array);
- }
-
- protected abstract Set<Object> getAllowedItemIds(
- DragAndDropEvent dragEvent, Tree tree);
-
- }
-
- /**
- * A criterion that accepts {@link Transferable} only directly on a tree
- * node that can have children.
- * <p>
- * Class is singleton, use {@link TargetItemAllowsChildren#get()} to get the
- * instance.
- *
- * @see Tree#setChildrenAllowed(Object, boolean)
- *
- * @since 6.3
- */
- public static class TargetItemAllowsChildren extends TargetDetailIs {
-
- private static TargetItemAllowsChildren instance = new TargetItemAllowsChildren();
-
- public static TargetItemAllowsChildren get() {
- return instance;
- }
-
- private TargetItemAllowsChildren() {
- super("itemIdOverIsNode", Boolean.TRUE);
- }
-
- /*
- * Uses enhanced server side check
- */
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- try {
- // must be over tree node and in the middle of it (not top or
- // bottom
- // part)
- TreeTargetDetails eventDetails = (TreeTargetDetails) dragEvent
- .getTargetDetails();
-
- Object itemIdOver = eventDetails.getItemIdOver();
- if (!eventDetails.getTarget().areChildrenAllowed(itemIdOver)) {
- return false;
- }
- // return true if directly over
- return eventDetails.getDropLocation() == VerticalDropLocation.MIDDLE;
- } catch (Exception e) {
- return false;
- }
- }
-
- }
-
- /**
- * An accept criterion that checks the parent node (or parent hierarchy) for
- * the item identifier given in constructor. If the parent is found, content
- * is accepted. Criterion can be used to accepts drags on a specific sub
- * tree only.
- * <p>
- * The root items is also consider to be valid target.
- */
- public class TargetInSubtree extends ClientSideCriterion {
-
- private Object rootId;
- private int depthToCheck = -1;
-
- /**
- * Constructs a criteria that accepts the drag if the targeted Item is a
- * descendant of Item identified by given id
- *
- * @param parentItemId
- * the item identifier of the parent node
- */
- public TargetInSubtree(Object parentItemId) {
- rootId = parentItemId;
- }
-
- /**
- * Constructs a criteria that accepts drops within given level below the
- * subtree root identified by given id.
- *
- * @param rootId
- * the item identifier to be sought for
- * @param depthToCheck
- * the depth that tree is traversed upwards to seek for the
- * parent, -1 means that the whole structure should be
- * checked
- */
- public TargetInSubtree(Object rootId, int depthToCheck) {
- this.rootId = rootId;
- this.depthToCheck = depthToCheck;
- }
-
- @Override
- public boolean accept(DragAndDropEvent dragEvent) {
- try {
- TreeTargetDetails eventDetails = (TreeTargetDetails) dragEvent
- .getTargetDetails();
-
- if (eventDetails.getItemIdOver() != null) {
- Object itemId = eventDetails.getItemIdOver();
- int i = 0;
- while (itemId != null
- && (depthToCheck == -1 || i <= depthToCheck)) {
- if (itemId.equals(rootId)) {
- return true;
- }
- itemId = getParent(itemId);
- i++;
- }
- }
- return false;
- } catch (Exception e) {
- return false;
- }
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- target.addAttribute("depth", depthToCheck);
- target.addAttribute("key", key(rootId));
- }
-
- }
-
- /**
- * Set the item description generator which generates tooltips for the tree
- * items
- *
- * @param generator
- * The generator to use or null to disable
- */
- public void setItemDescriptionGenerator(ItemDescriptionGenerator generator) {
- if (generator != itemDescriptionGenerator) {
- itemDescriptionGenerator = generator;
- requestRepaint();
- }
- }
-
- /**
- * Get the item description generator which generates tooltips for tree
- * items
- */
- public ItemDescriptionGenerator getItemDescriptionGenerator() {
- return itemDescriptionGenerator;
- }
-
-}
diff --git a/src/com/vaadin/ui/TreeTable.java b/src/com/vaadin/ui/TreeTable.java
deleted file mode 100644
index 6132b652f7..0000000000
--- a/src/com/vaadin/ui/TreeTable.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import com.vaadin.data.Collapsible;
-import com.vaadin.data.Container;
-import com.vaadin.data.Container.Hierarchical;
-import com.vaadin.data.Container.ItemSetChangeEvent;
-import com.vaadin.data.util.ContainerHierarchicalWrapper;
-import com.vaadin.data.util.HierarchicalContainer;
-import com.vaadin.data.util.HierarchicalContainerOrderedWrapper;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.treetable.TreeTableConnector;
-import com.vaadin.ui.Tree.CollapseEvent;
-import com.vaadin.ui.Tree.CollapseListener;
-import com.vaadin.ui.Tree.ExpandEvent;
-import com.vaadin.ui.Tree.ExpandListener;
-
-/**
- * TreeTable extends the {@link Table} component so that it can also visualize a
- * hierarchy of its Items in a similar manner that {@link Tree} does. The tree
- * hierarchy is always displayed in the first actual column of the TreeTable.
- * <p>
- * The TreeTable supports the usual {@link Table} features like lazy loading, so
- * it should be no problem to display lots of items at once. Only required rows
- * and some cache rows are sent to the client.
- * <p>
- * TreeTable supports standard {@link Hierarchical} container interfaces, but
- * also a more fine tuned version - {@link Collapsible}. A container
- * implementing the {@link Collapsible} interface stores the collapsed/expanded
- * state internally and can this way scale better on the server side than with
- * standard Hierarchical implementations. Developer must however note that
- * {@link Collapsible} containers can not be shared among several users as they
- * share UI state in the container.
- */
-@SuppressWarnings({ "serial" })
-public class TreeTable extends Table implements Hierarchical {
-
- private interface ContainerStrategy extends Serializable {
- public int size();
-
- public boolean isNodeOpen(Object itemId);
-
- public int getDepth(Object itemId);
-
- public void toggleChildVisibility(Object itemId);
-
- public Object getIdByIndex(int index);
-
- public int indexOfId(Object id);
-
- public Object nextItemId(Object itemId);
-
- public Object lastItemId();
-
- public Object prevItemId(Object itemId);
-
- public boolean isLastId(Object itemId);
-
- public Collection<?> getItemIds();
-
- public void containerItemSetChange(ItemSetChangeEvent event);
- }
-
- private abstract class AbstractStrategy implements ContainerStrategy {
-
- /**
- * Consider adding getDepth to {@link Collapsible}, might help
- * scalability with some container implementations.
- */
-
- @Override
- public int getDepth(Object itemId) {
- int depth = 0;
- Hierarchical hierarchicalContainer = getContainerDataSource();
- while (!hierarchicalContainer.isRoot(itemId)) {
- depth++;
- itemId = hierarchicalContainer.getParent(itemId);
- }
- return depth;
- }
-
- @Override
- public void containerItemSetChange(ItemSetChangeEvent event) {
- }
-
- }
-
- /**
- * This strategy is used if current container implements {@link Collapsible}
- * .
- *
- * open-collapsed logic diverted to container, otherwise use default
- * implementations.
- */
- private class CollapsibleStrategy extends AbstractStrategy {
-
- private Collapsible c() {
- return (Collapsible) getContainerDataSource();
- }
-
- @Override
- public void toggleChildVisibility(Object itemId) {
- c().setCollapsed(itemId, !c().isCollapsed(itemId));
- }
-
- @Override
- public boolean isNodeOpen(Object itemId) {
- return !c().isCollapsed(itemId);
- }
-
- @Override
- public int size() {
- return TreeTable.super.size();
- }
-
- @Override
- public Object getIdByIndex(int index) {
- return TreeTable.super.getIdByIndex(index);
- }
-
- @Override
- public int indexOfId(Object id) {
- return TreeTable.super.indexOfId(id);
- }
-
- @Override
- public boolean isLastId(Object itemId) {
- // using the default impl
- return TreeTable.super.isLastId(itemId);
- }
-
- @Override
- public Object lastItemId() {
- // using the default impl
- return TreeTable.super.lastItemId();
- }
-
- @Override
- public Object nextItemId(Object itemId) {
- return TreeTable.super.nextItemId(itemId);
- }
-
- @Override
- public Object prevItemId(Object itemId) {
- return TreeTable.super.prevItemId(itemId);
- }
-
- @Override
- public Collection<?> getItemIds() {
- return TreeTable.super.getItemIds();
- }
-
- }
-
- /**
- * Strategy for Hierarchical but not Collapsible container like
- * {@link HierarchicalContainer}.
- *
- * Store collapsed/open states internally, fool Table to use preorder when
- * accessing items from container via Ordered/Indexed methods.
- */
- private class HierarchicalStrategy extends AbstractStrategy {
-
- private final HashSet<Object> openItems = new HashSet<Object>();
-
- @Override
- public boolean isNodeOpen(Object itemId) {
- return openItems.contains(itemId);
- }
-
- @Override
- public int size() {
- return getPreOrder().size();
- }
-
- @Override
- public Collection<Object> getItemIds() {
- return Collections.unmodifiableCollection(getPreOrder());
- }
-
- @Override
- public boolean isLastId(Object itemId) {
- if (itemId == null) {
- return false;
- }
-
- return itemId.equals(lastItemId());
- }
-
- @Override
- public Object lastItemId() {
- if (getPreOrder().size() > 0) {
- return getPreOrder().get(getPreOrder().size() - 1);
- } else {
- return null;
- }
- }
-
- @Override
- public Object nextItemId(Object itemId) {
- int indexOf = getPreOrder().indexOf(itemId);
- if (indexOf == -1) {
- return null;
- }
- indexOf++;
- if (indexOf == getPreOrder().size()) {
- return null;
- } else {
- return getPreOrder().get(indexOf);
- }
- }
-
- @Override
- public Object prevItemId(Object itemId) {
- int indexOf = getPreOrder().indexOf(itemId);
- indexOf--;
- if (indexOf < 0) {
- return null;
- } else {
- return getPreOrder().get(indexOf);
- }
- }
-
- @Override
- public void toggleChildVisibility(Object itemId) {
- boolean removed = openItems.remove(itemId);
- if (!removed) {
- openItems.add(itemId);
- getLogger().finest("Item " + itemId + " is now expanded");
- } else {
- getLogger().finest("Item " + itemId + " is now collapsed");
- }
- clearPreorderCache();
- }
-
- private void clearPreorderCache() {
- preOrder = null; // clear preorder cache
- }
-
- List<Object> preOrder;
-
- /**
- * Preorder of ids currently visible
- *
- * @return
- */
- private List<Object> getPreOrder() {
- if (preOrder == null) {
- preOrder = new ArrayList<Object>();
- Collection<?> rootItemIds = getContainerDataSource()
- .rootItemIds();
- for (Object id : rootItemIds) {
- preOrder.add(id);
- addVisibleChildTree(id);
- }
- }
- return preOrder;
- }
-
- private void addVisibleChildTree(Object id) {
- if (isNodeOpen(id)) {
- Collection<?> children = getContainerDataSource().getChildren(
- id);
- if (children != null) {
- for (Object childId : children) {
- preOrder.add(childId);
- addVisibleChildTree(childId);
- }
- }
- }
-
- }
-
- @Override
- public int indexOfId(Object id) {
- return getPreOrder().indexOf(id);
- }
-
- @Override
- public Object getIdByIndex(int index) {
- return getPreOrder().get(index);
- }
-
- @Override
- public void containerItemSetChange(ItemSetChangeEvent event) {
- // preorder becomes invalid on sort, item additions etc.
- clearPreorderCache();
- super.containerItemSetChange(event);
- }
-
- }
-
- /**
- * Creates an empty TreeTable with a default container.
- */
- public TreeTable() {
- super(null, new HierarchicalContainer());
- }
-
- /**
- * Creates an empty TreeTable with a default container.
- *
- * @param caption
- * the caption for the TreeTable
- */
- public TreeTable(String caption) {
- this();
- setCaption(caption);
- }
-
- /**
- * Creates a TreeTable instance with given captions and data source.
- *
- * @param caption
- * the caption for the component
- * @param dataSource
- * the dataSource that is used to list items in the component
- */
- public TreeTable(String caption, Container dataSource) {
- super(caption, dataSource);
- }
-
- private ContainerStrategy cStrategy;
- private Object focusedRowId = null;
- private Object hierarchyColumnId;
-
- /**
- * The item id that was expanded or collapsed during this request. Reset at
- * the end of paint and only used for determining if a partial or full paint
- * should be done.
- *
- * Can safely be reset to null whenever a change occurs that would prevent a
- * partial update from rendering the correct result, e.g. rows added or
- * removed during an expand operation.
- */
- private Object toggledItemId;
- private boolean animationsEnabled;
- private boolean clearFocusedRowPending;
-
- /**
- * If the container does not send item set change events, always do a full
- * repaint instead of a partial update when expanding/collapsing nodes.
- */
- private boolean containerSupportsPartialUpdates;
-
- private ContainerStrategy getContainerStrategy() {
- if (cStrategy == null) {
- if (getContainerDataSource() instanceof Collapsible) {
- cStrategy = new CollapsibleStrategy();
- } else {
- cStrategy = new HierarchicalStrategy();
- }
- }
- return cStrategy;
- }
-
- @Override
- protected void paintRowAttributes(PaintTarget target, Object itemId)
- throws PaintException {
- super.paintRowAttributes(target, itemId);
- target.addAttribute("depth", getContainerStrategy().getDepth(itemId));
- if (getContainerDataSource().areChildrenAllowed(itemId)) {
- target.addAttribute("ca", true);
- target.addAttribute("open",
- getContainerStrategy().isNodeOpen(itemId));
- }
- }
-
- @Override
- protected void paintRowIcon(PaintTarget target, Object[][] cells,
- int indexInRowbuffer) throws PaintException {
- // always paint if present (in parent only if row headers visible)
- if (getRowHeaderMode() == ROW_HEADER_MODE_HIDDEN) {
- Resource itemIcon = getItemIcon(cells[CELL_ITEMID][indexInRowbuffer]);
- if (itemIcon != null) {
- target.addAttribute("icon", itemIcon);
- }
- } else if (cells[CELL_ICON][indexInRowbuffer] != null) {
- target.addAttribute("icon",
- (Resource) cells[CELL_ICON][indexInRowbuffer]);
- }
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- super.changeVariables(source, variables);
-
- if (variables.containsKey("toggleCollapsed")) {
- String object = (String) variables.get("toggleCollapsed");
- Object itemId = itemIdMapper.get(object);
- toggledItemId = itemId;
- toggleChildVisibility(itemId, false);
- if (variables.containsKey("selectCollapsed")) {
- // ensure collapsed is selected unless opened with selection
- // head
- if (isSelectable()) {
- select(itemId);
- }
- }
- } else if (variables.containsKey("focusParent")) {
- String key = (String) variables.get("focusParent");
- Object refId = itemIdMapper.get(key);
- Object itemId = getParent(refId);
- focusParent(itemId);
- }
- }
-
- private void focusParent(Object itemId) {
- boolean inView = false;
- Object inPageId = getCurrentPageFirstItemId();
- for (int i = 0; inPageId != null && i < getPageLength(); i++) {
- if (inPageId.equals(itemId)) {
- inView = true;
- break;
- }
- inPageId = nextItemId(inPageId);
- i++;
- }
- if (!inView) {
- setCurrentPageFirstItemId(itemId);
- }
- // Select the row if it is selectable.
- if (isSelectable()) {
- if (isMultiSelect()) {
- setValue(Collections.singleton(itemId));
- } else {
- setValue(itemId);
- }
- }
- setFocusedRow(itemId);
- }
-
- private void setFocusedRow(Object itemId) {
- focusedRowId = itemId;
- if (focusedRowId == null) {
- // Must still inform the client that the focusParent request has
- // been processed
- clearFocusedRowPending = true;
- }
- requestRepaint();
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (focusedRowId != null) {
- target.addAttribute("focusedRow", itemIdMapper.key(focusedRowId));
- focusedRowId = null;
- } else if (clearFocusedRowPending) {
- // Must still inform the client that the focusParent request has
- // been processed
- target.addAttribute("clearFocusPending", true);
- clearFocusedRowPending = false;
- }
- target.addAttribute("animate", animationsEnabled);
- if (hierarchyColumnId != null) {
- Object[] visibleColumns2 = getVisibleColumns();
- for (int i = 0; i < visibleColumns2.length; i++) {
- Object object = visibleColumns2[i];
- if (hierarchyColumnId.equals(object)) {
- target.addAttribute(
- TreeTableConnector.ATTRIBUTE_HIERARCHY_COLUMN_INDEX,
- i);
- break;
- }
- }
- }
- super.paintContent(target);
- toggledItemId = null;
- }
-
- /*
- * Override methods for partial row updates and additions when expanding /
- * collapsing nodes.
- */
-
- @Override
- protected boolean isPartialRowUpdate() {
- return toggledItemId != null && containerSupportsPartialUpdates
- && !isRowCacheInvalidated();
- }
-
- @Override
- protected int getFirstAddedItemIndex() {
- return indexOfId(toggledItemId) + 1;
- }
-
- @Override
- protected int getAddedRowCount() {
- return countSubNodesRecursively(getContainerDataSource(), toggledItemId);
- }
-
- private int countSubNodesRecursively(Hierarchical hc, Object itemId) {
- int count = 0;
- // we need the number of children for toggledItemId no matter if its
- // collapsed or expanded. Other items' children are only counted if the
- // item is expanded.
- if (getContainerStrategy().isNodeOpen(itemId)
- || itemId == toggledItemId) {
- Collection<?> children = hc.getChildren(itemId);
- if (children != null) {
- count += children != null ? children.size() : 0;
- for (Object id : children) {
- count += countSubNodesRecursively(hc, id);
- }
- }
- }
- return count;
- }
-
- @Override
- protected int getFirstUpdatedItemIndex() {
- return indexOfId(toggledItemId);
- }
-
- @Override
- protected int getUpdatedRowCount() {
- return 1;
- }
-
- @Override
- protected boolean shouldHideAddedRows() {
- return !getContainerStrategy().isNodeOpen(toggledItemId);
- }
-
- private void toggleChildVisibility(Object itemId, boolean forceFullRefresh) {
- getContainerStrategy().toggleChildVisibility(itemId);
- // ensure that page still has first item in page, DON'T clear the
- // caches.
- setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);
-
- if (isCollapsed(itemId)) {
- fireCollapseEvent(itemId);
- } else {
- fireExpandEvent(itemId);
- }
-
- if (containerSupportsPartialUpdates && !forceFullRefresh) {
- requestRepaint();
- } else {
- // For containers that do not send item set change events, always do
- // full repaint instead of partial row update.
- refreshRowCache();
- }
- }
-
- @Override
- public int size() {
- return getContainerStrategy().size();
- }
-
- @Override
- public Hierarchical getContainerDataSource() {
- return (Hierarchical) super.getContainerDataSource();
- }
-
- @Override
- public void setContainerDataSource(Container newDataSource) {
- cStrategy = null;
-
- // FIXME: This disables partial updates until TreeTable is fixed so it
- // does not change component hierarchy during paint
- containerSupportsPartialUpdates = (newDataSource instanceof ItemSetChangeNotifier) && false;
-
- if (!(newDataSource instanceof Hierarchical)) {
- newDataSource = new ContainerHierarchicalWrapper(newDataSource);
- }
-
- if (!(newDataSource instanceof Ordered)) {
- newDataSource = new HierarchicalContainerOrderedWrapper(
- (Hierarchical) newDataSource);
- }
-
- super.setContainerDataSource(newDataSource);
- }
-
- @Override
- public void containerItemSetChange(
- com.vaadin.data.Container.ItemSetChangeEvent event) {
- // Can't do partial repaints if items are added or removed during the
- // expand/collapse request
- toggledItemId = null;
- getContainerStrategy().containerItemSetChange(event);
- super.containerItemSetChange(event);
- }
-
- @Override
- protected Object getIdByIndex(int index) {
- return getContainerStrategy().getIdByIndex(index);
- }
-
- @Override
- protected int indexOfId(Object itemId) {
- return getContainerStrategy().indexOfId(itemId);
- }
-
- @Override
- public Object nextItemId(Object itemId) {
- return getContainerStrategy().nextItemId(itemId);
- }
-
- @Override
- public Object lastItemId() {
- return getContainerStrategy().lastItemId();
- }
-
- @Override
- public Object prevItemId(Object itemId) {
- return getContainerStrategy().prevItemId(itemId);
- }
-
- @Override
- public boolean isLastId(Object itemId) {
- return getContainerStrategy().isLastId(itemId);
- }
-
- @Override
- public Collection<?> getItemIds() {
- return getContainerStrategy().getItemIds();
- }
-
- @Override
- public boolean areChildrenAllowed(Object itemId) {
- return getContainerDataSource().areChildrenAllowed(itemId);
- }
-
- @Override
- public Collection<?> getChildren(Object itemId) {
- return getContainerDataSource().getChildren(itemId);
- }
-
- @Override
- public Object getParent(Object itemId) {
- return getContainerDataSource().getParent(itemId);
- }
-
- @Override
- public boolean hasChildren(Object itemId) {
- return getContainerDataSource().hasChildren(itemId);
- }
-
- @Override
- public boolean isRoot(Object itemId) {
- return getContainerDataSource().isRoot(itemId);
- }
-
- @Override
- public Collection<?> rootItemIds() {
- return getContainerDataSource().rootItemIds();
- }
-
- @Override
- public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed)
- throws UnsupportedOperationException {
- return getContainerDataSource().setChildrenAllowed(itemId,
- areChildrenAllowed);
- }
-
- @Override
- public boolean setParent(Object itemId, Object newParentId)
- throws UnsupportedOperationException {
- return getContainerDataSource().setParent(itemId, newParentId);
- }
-
- /**
- * Sets the Item specified by given identifier as collapsed or expanded. If
- * the Item is collapsed, its children are not displayed to the user.
- *
- * @param itemId
- * the identifier of the Item
- * @param collapsed
- * true if the Item should be collapsed, false if expanded
- */
- public void setCollapsed(Object itemId, boolean collapsed) {
- if (isCollapsed(itemId) != collapsed) {
- if (null == toggledItemId && !isRowCacheInvalidated()
- && getVisibleItemIds().contains(itemId)) {
- // optimization: partial refresh if only one item is
- // collapsed/expanded
- toggledItemId = itemId;
- toggleChildVisibility(itemId, false);
- } else {
- // make sure a full refresh takes place - otherwise neither
- // partial nor full repaint of table content is performed
- toggledItemId = null;
- toggleChildVisibility(itemId, true);
- }
- }
- }
-
- /**
- * Checks if Item with given identifier is collapsed in the UI.
- *
- * <p>
- *
- * @param itemId
- * the identifier of the checked Item
- * @return true if the Item with given id is collapsed
- * @see Collapsible#isCollapsed(Object)
- */
- public boolean isCollapsed(Object itemId) {
- return !getContainerStrategy().isNodeOpen(itemId);
- }
-
- /**
- * Explicitly sets the column in which the TreeTable visualizes the
- * hierarchy. If hierarchyColumnId is not set, the hierarchy is visualized
- * in the first visible column.
- *
- * @param hierarchyColumnId
- */
- public void setHierarchyColumn(Object hierarchyColumnId) {
- this.hierarchyColumnId = hierarchyColumnId;
- }
-
- /**
- * @return the identifier of column into which the hierarchy will be
- * visualized or null if the column is not explicitly defined.
- */
- public Object getHierarchyColumnId() {
- return hierarchyColumnId;
- }
-
- /**
- * Adds an expand listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(ExpandListener listener) {
- addListener(ExpandEvent.class, listener, ExpandListener.EXPAND_METHOD);
- }
-
- /**
- * Removes an expand listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(ExpandListener listener) {
- removeListener(ExpandEvent.class, listener,
- ExpandListener.EXPAND_METHOD);
- }
-
- /**
- * Emits an expand event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireExpandEvent(Object itemId) {
- fireEvent(new ExpandEvent(this, itemId));
- }
-
- /**
- * Adds a collapse listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(CollapseListener listener) {
- addListener(CollapseEvent.class, listener,
- CollapseListener.COLLAPSE_METHOD);
- }
-
- /**
- * Removes a collapse listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(CollapseListener listener) {
- removeListener(CollapseEvent.class, listener,
- CollapseListener.COLLAPSE_METHOD);
- }
-
- /**
- * Emits a collapse event.
- *
- * @param itemId
- * the item id.
- */
- protected void fireCollapseEvent(Object itemId) {
- fireEvent(new CollapseEvent(this, itemId));
- }
-
- /**
- * @return true if animations are enabled
- */
- public boolean isAnimationsEnabled() {
- return animationsEnabled;
- }
-
- /**
- * Animations can be enabled by passing true to this method. Currently
- * expanding rows slide in from the top and collapsing rows slide out the
- * same way. NOTE! not supported in Internet Explorer 6 or 7.
- *
- * @param animationsEnabled
- * true or false whether to enable animations or not.
- */
- public void setAnimationsEnabled(boolean animationsEnabled) {
- this.animationsEnabled = animationsEnabled;
- requestRepaint();
- }
-
- private static final Logger getLogger() {
- return Logger.getLogger(TreeTable.class.getName());
- }
-
-}
diff --git a/src/com/vaadin/ui/TwinColSelect.java b/src/com/vaadin/ui/TwinColSelect.java
deleted file mode 100644
index 5539236f77..0000000000
--- a/src/com/vaadin/ui/TwinColSelect.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.util.Collection;
-
-import com.vaadin.data.Container;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.twincolselect.VTwinColSelect;
-
-/**
- * Multiselect component with two lists: left side for available items and right
- * side for selected items.
- */
-@SuppressWarnings("serial")
-public class TwinColSelect extends AbstractSelect {
-
- private int columns = 0;
- private int rows = 0;
-
- private String leftColumnCaption;
- private String rightColumnCaption;
-
- /**
- *
- */
- public TwinColSelect() {
- super();
- setMultiSelect(true);
- }
-
- /**
- * @param caption
- */
- public TwinColSelect(String caption) {
- super(caption);
- setMultiSelect(true);
- }
-
- /**
- * @param caption
- * @param dataSource
- */
- public TwinColSelect(String caption, Container dataSource) {
- super(caption, dataSource);
- setMultiSelect(true);
- }
-
- /**
- * Sets the number of columns in the editor. If the number of columns is set
- * 0, the actual number of displayed columns is determined implicitly by the
- * adapter.
- * <p>
- * The number of columns overrides the value set by setWidth. Only if
- * columns are set to 0 (default) the width set using
- * {@link #setWidth(float, int)} or {@link #setWidth(String)} is used.
- *
- * @param columns
- * the number of columns to set.
- */
- public void setColumns(int columns) {
- if (columns < 0) {
- columns = 0;
- }
- if (this.columns != columns) {
- this.columns = columns;
- requestRepaint();
- }
- }
-
- public int getColumns() {
- return columns;
- }
-
- public int getRows() {
- return rows;
- }
-
- /**
- * Sets the number of rows in the editor. If the number of rows is set to 0,
- * the actual number of displayed rows is determined implicitly by the
- * adapter.
- * <p>
- * If a height if set (using {@link #setHeight(String)} or
- * {@link #setHeight(float, int)}) it overrides the number of rows. Leave
- * the height undefined to use this method. This is the opposite of how
- * {@link #setColumns(int)} work.
- *
- *
- * @param rows
- * the number of rows to set.
- */
- public void setRows(int rows) {
- if (rows < 0) {
- rows = 0;
- }
- if (this.rows != rows) {
- this.rows = rows;
- requestRepaint();
- }
- }
-
- /**
- * @param caption
- * @param options
- */
- public TwinColSelect(String caption, Collection<?> options) {
- super(caption, options);
- setMultiSelect(true);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- target.addAttribute("type", "twincol");
- // Adds the number of columns
- if (columns != 0) {
- target.addAttribute("cols", columns);
- }
- // Adds the number of rows
- if (rows != 0) {
- target.addAttribute("rows", rows);
- }
-
- // Right and left column captions and/or icons (if set)
- String lc = getLeftColumnCaption();
- String rc = getRightColumnCaption();
- if (lc != null) {
- target.addAttribute(VTwinColSelect.ATTRIBUTE_LEFT_CAPTION, lc);
- }
- if (rc != null) {
- target.addAttribute(VTwinColSelect.ATTRIBUTE_RIGHT_CAPTION, rc);
- }
-
- super.paintContent(target);
- }
-
- /**
- * Sets the text shown above the right column.
- *
- * @param caption
- * The text to show
- */
- public void setRightColumnCaption(String rightColumnCaption) {
- this.rightColumnCaption = rightColumnCaption;
- requestRepaint();
- }
-
- /**
- * Returns the text shown above the right column.
- *
- * @return The text shown or null if not set.
- */
- public String getRightColumnCaption() {
- return rightColumnCaption;
- }
-
- /**
- * Sets the text shown above the left column.
- *
- * @param caption
- * The text to show
- */
- public void setLeftColumnCaption(String leftColumnCaption) {
- this.leftColumnCaption = leftColumnCaption;
- requestRepaint();
- }
-
- /**
- * Returns the text shown above the left column.
- *
- * @return The text shown or null if not set.
- */
- public String getLeftColumnCaption() {
- return leftColumnCaption;
- }
-
-}
diff --git a/src/com/vaadin/ui/UniqueSerializable.java b/src/com/vaadin/ui/UniqueSerializable.java
deleted file mode 100644
index 828b285538..0000000000
--- a/src/com/vaadin/ui/UniqueSerializable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-
-/**
- * A base class for generating an unique object that is serializable.
- * <p>
- * This class is abstract but has no abstract methods to force users to create
- * an anonymous inner class. Otherwise each instance will not be unique.
- *
- * @author Vaadin Ltd
- * @version @VERSION@
- * @since 7.0
- *
- */
-public abstract class UniqueSerializable implements Serializable {
-
- @Override
- public int hashCode() {
- return getClass().hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return getClass() == obj.getClass();
- }
-}
diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java
deleted file mode 100644
index 9d533b67f6..0000000000
--- a/src/com/vaadin/ui/Upload.java
+++ /dev/null
@@ -1,1055 +0,0 @@
-/*
- * @VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Map;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.StreamVariable.StreamingProgressEvent;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.server.NoInputStreamException;
-import com.vaadin.terminal.gwt.server.NoOutputStreamException;
-
-/**
- * Component for uploading files from client to server.
- *
- * <p>
- * The visible component consists of a file name input box and a browse button
- * and an upload submit button to start uploading.
- *
- * <p>
- * The Upload component needs a java.io.OutputStream to write the uploaded data.
- * You need to implement the Upload.Receiver interface and return the output
- * stream in the receiveUpload() method.
- *
- * <p>
- * You can get an event regarding starting (StartedEvent), progress
- * (ProgressEvent), and finishing (FinishedEvent) of upload by implementing
- * StartedListener, ProgressListener, and FinishedListener, respectively. The
- * FinishedListener is called for both failed and succeeded uploads. If you wish
- * to separate between these two cases, you can use SucceededListener
- * (SucceededEvenet) and FailedListener (FailedEvent).
- *
- * <p>
- * The upload component does not itself show upload progress, but you can use
- * the ProgressIndicator for providing progress feedback by implementing
- * ProgressListener and updating the indicator in updateProgress().
- *
- * <p>
- * Setting upload component immediate initiates the upload as soon as a file is
- * selected, instead of the common pattern of file selection field and upload
- * button.
- *
- * <p>
- * Note! Because of browser dependent implementations of <input type="file">
- * element, setting size for Upload component is not supported. For some
- * browsers setting size may work to some extend.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Upload extends AbstractComponent implements Component.Focusable,
- Vaadin6Component {
-
- /**
- * Should the field be focused on next repaint?
- */
- private final boolean focus = false;
-
- /**
- * The tab order number of this field.
- */
- private int tabIndex = 0;
-
- /**
- * The output of the upload is redirected to this receiver.
- */
- private Receiver receiver;
-
- private boolean isUploading;
-
- private long contentLength = -1;
-
- private int totalBytes;
-
- private String buttonCaption = "Upload";
-
- /**
- * ProgressListeners to which information about progress is sent during
- * upload
- */
- private LinkedHashSet<ProgressListener> progressListeners;
-
- private boolean interrupted = false;
-
- private boolean notStarted;
-
- private int nextid;
-
- /**
- * Flag to indicate that submitting file has been requested.
- */
- private boolean forceSubmit;
-
- /**
- * Creates a new instance of Upload.
- *
- * The receiver must be set before performing an upload.
- */
- public Upload() {
- }
-
- public Upload(String caption, Receiver uploadReceiver) {
- setCaption(caption);
- receiver = uploadReceiver;
- }
-
- /**
- * Invoked when the value of a variable has changed.
- *
- * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object,
- * java.util.Map)
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey("pollForStart")) {
- int id = (Integer) variables.get("pollForStart");
- if (!isUploading && id == nextid) {
- notStarted = true;
- requestRepaint();
- } else {
- }
- }
- }
-
- /**
- * Paints the content of this component.
- *
- * @param target
- * Target to paint the content on.
- * @throws PaintException
- * if the paint operation failed.
- */
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- if (notStarted) {
- target.addAttribute("notStarted", true);
- notStarted = false;
- return;
- }
- if (forceSubmit) {
- target.addAttribute("forceSubmit", true);
- forceSubmit = true;
- return;
- }
- // The field should be focused
- if (focus) {
- target.addAttribute("focus", true);
- }
-
- // The tab ordering number
- if (tabIndex >= 0) {
- target.addAttribute("tabindex", tabIndex);
- }
-
- target.addAttribute("state", isUploading);
-
- if (buttonCaption != null) {
- target.addAttribute("buttoncaption", buttonCaption);
- }
-
- target.addAttribute("nextid", nextid);
-
- // Post file to this strean variable
- target.addVariable(this, "action", getStreamVariable());
-
- }
-
- /**
- * Interface that must be implemented by the upload receivers to provide the
- * Upload component an output stream to write the uploaded data.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface Receiver extends Serializable {
-
- /**
- * Invoked when a new upload arrives.
- *
- * @param filename
- * the desired filename of the upload, usually as specified
- * by the client.
- * @param mimeType
- * the MIME type of the uploaded file.
- * @return Stream to which the uploaded file should be written.
- */
- public OutputStream receiveUpload(String filename, String mimeType);
-
- }
-
- /* Upload events */
-
- private static final Method UPLOAD_FINISHED_METHOD;
-
- private static final Method UPLOAD_FAILED_METHOD;
-
- private static final Method UPLOAD_SUCCEEDED_METHOD;
-
- private static final Method UPLOAD_STARTED_METHOD;
-
- static {
- try {
- UPLOAD_FINISHED_METHOD = FinishedListener.class.getDeclaredMethod(
- "uploadFinished", new Class[] { FinishedEvent.class });
- UPLOAD_FAILED_METHOD = FailedListener.class.getDeclaredMethod(
- "uploadFailed", new Class[] { FailedEvent.class });
- UPLOAD_STARTED_METHOD = StartedListener.class.getDeclaredMethod(
- "uploadStarted", new Class[] { StartedEvent.class });
- UPLOAD_SUCCEEDED_METHOD = SucceededListener.class
- .getDeclaredMethod("uploadSucceeded",
- new Class[] { SucceededEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in Upload");
- }
- }
-
- /**
- * Upload.FinishedEvent is sent when the upload receives a file, regardless
- * of whether the reception was successful or failed. If you wish to
- * distinguish between the two cases, use either SucceededEvent or
- * FailedEvent, which are both subclasses of the FinishedEvent.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class FinishedEvent extends Component.Event {
-
- /**
- * Length of the received file.
- */
- private final long length;
-
- /**
- * MIME type of the received file.
- */
- private final String type;
-
- /**
- * Received file name.
- */
- private final String filename;
-
- /**
- *
- * @param source
- * the source of the file.
- * @param filename
- * the received file name.
- * @param MIMEType
- * the MIME type of the received file.
- * @param length
- * the length of the received file.
- */
- public FinishedEvent(Upload source, String filename, String MIMEType,
- long length) {
- super(source);
- type = MIMEType;
- this.filename = filename;
- this.length = length;
- }
-
- /**
- * Uploads where the event occurred.
- *
- * @return the Source of the event.
- */
- public Upload getUpload() {
- return (Upload) getSource();
- }
-
- /**
- * Gets the file name.
- *
- * @return the filename.
- */
- public String getFilename() {
- return filename;
- }
-
- /**
- * Gets the MIME Type of the file.
- *
- * @return the MIME type.
- */
- public String getMIMEType() {
- return type;
- }
-
- /**
- * Gets the length of the file.
- *
- * @return the length.
- */
- public long getLength() {
- return length;
- }
-
- }
-
- /**
- * Upload.FailedEvent event is sent when the upload is received, but the
- * reception is interrupted for some reason.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class FailedEvent extends FinishedEvent {
-
- private Exception reason = null;
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- * @param exception
- */
- public FailedEvent(Upload source, String filename, String MIMEType,
- long length, Exception reason) {
- this(source, filename, MIMEType, length);
- this.reason = reason;
- }
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- * @param exception
- */
- public FailedEvent(Upload source, String filename, String MIMEType,
- long length) {
- super(source, filename, MIMEType, length);
- }
-
- /**
- * Gets the exception that caused the failure.
- *
- * @return the exception that caused the failure, null if n/a
- */
- public Exception getReason() {
- return reason;
- }
-
- }
-
- /**
- * FailedEvent that indicates that an output stream could not be obtained.
- */
- public static class NoOutputStreamEvent extends FailedEvent {
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- */
- public NoOutputStreamEvent(Upload source, String filename,
- String MIMEType, long length) {
- super(source, filename, MIMEType, length);
- }
- }
-
- /**
- * FailedEvent that indicates that an input stream could not be obtained.
- */
- public static class NoInputStreamEvent extends FailedEvent {
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- */
- public NoInputStreamEvent(Upload source, String filename,
- String MIMEType, long length) {
- super(source, filename, MIMEType, length);
- }
-
- }
-
- /**
- * Upload.SucceededEvent event is sent when the upload is received
- * successfully.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public static class SucceededEvent extends FinishedEvent {
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- */
- public SucceededEvent(Upload source, String filename, String MIMEType,
- long length) {
- super(source, filename, MIMEType, length);
- }
-
- }
-
- /**
- * Upload.StartedEvent event is sent when the upload is started to received.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
- public static class StartedEvent extends Component.Event {
-
- private final String filename;
- private final String type;
- /**
- * Length of the received file.
- */
- private final long length;
-
- /**
- *
- * @param source
- * @param filename
- * @param MIMEType
- * @param length
- */
- public StartedEvent(Upload source, String filename, String MIMEType,
- long contentLength) {
- super(source);
- this.filename = filename;
- type = MIMEType;
- length = contentLength;
- }
-
- /**
- * Uploads where the event occurred.
- *
- * @return the Source of the event.
- */
- public Upload getUpload() {
- return (Upload) getSource();
- }
-
- /**
- * Gets the file name.
- *
- * @return the filename.
- */
- public String getFilename() {
- return filename;
- }
-
- /**
- * Gets the MIME Type of the file.
- *
- * @return the MIME type.
- */
- public String getMIMEType() {
- return type;
- }
-
- /**
- * @return the length of the file that is being uploaded
- */
- public long getContentLength() {
- return length;
- }
-
- }
-
- /**
- * Receives the events when the upload starts.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.0
- */
- public interface StartedListener extends Serializable {
-
- /**
- * Upload has started.
- *
- * @param event
- * the Upload started event.
- */
- public void uploadStarted(StartedEvent event);
- }
-
- /**
- * Receives the events when the uploads are ready.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface FinishedListener extends Serializable {
-
- /**
- * Upload has finished.
- *
- * @param event
- * the Upload finished event.
- */
- public void uploadFinished(FinishedEvent event);
- }
-
- /**
- * Receives events when the uploads are finished, but unsuccessful.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface FailedListener extends Serializable {
-
- /**
- * Upload has finished unsuccessfully.
- *
- * @param event
- * the Upload failed event.
- */
- public void uploadFailed(FailedEvent event);
- }
-
- /**
- * Receives events when the uploads are successfully finished.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public interface SucceededListener extends Serializable {
-
- /**
- * Upload successfull..
- *
- * @param event
- * the Upload successfull event.
- */
- public void uploadSucceeded(SucceededEvent event);
- }
-
- /**
- * Adds the upload started event listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(StartedListener listener) {
- addListener(StartedEvent.class, listener, UPLOAD_STARTED_METHOD);
- }
-
- /**
- * Removes the upload started event listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(StartedListener listener) {
- removeListener(StartedEvent.class, listener, UPLOAD_STARTED_METHOD);
- }
-
- /**
- * Adds the upload received event listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(FinishedListener listener) {
- addListener(FinishedEvent.class, listener, UPLOAD_FINISHED_METHOD);
- }
-
- /**
- * Removes the upload received event listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(FinishedListener listener) {
- removeListener(FinishedEvent.class, listener, UPLOAD_FINISHED_METHOD);
- }
-
- /**
- * Adds the upload interrupted event listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(FailedListener listener) {
- addListener(FailedEvent.class, listener, UPLOAD_FAILED_METHOD);
- }
-
- /**
- * Removes the upload interrupted event listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(FailedListener listener) {
- removeListener(FailedEvent.class, listener, UPLOAD_FAILED_METHOD);
- }
-
- /**
- * Adds the upload success event listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(SucceededListener listener) {
- addListener(SucceededEvent.class, listener, UPLOAD_SUCCEEDED_METHOD);
- }
-
- /**
- * Removes the upload success event listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(SucceededListener listener) {
- removeListener(SucceededEvent.class, listener, UPLOAD_SUCCEEDED_METHOD);
- }
-
- /**
- * Adds the upload success event listener.
- *
- * @param listener
- * the Listener to be added.
- */
- public void addListener(ProgressListener listener) {
- if (progressListeners == null) {
- progressListeners = new LinkedHashSet<ProgressListener>();
- }
- progressListeners.add(listener);
- }
-
- /**
- * Removes the upload success event listener.
- *
- * @param listener
- * the Listener to be removed.
- */
- public void removeListener(ProgressListener listener) {
- if (progressListeners != null) {
- progressListeners.remove(listener);
- }
- }
-
- /**
- * Emit upload received event.
- *
- * @param filename
- * @param MIMEType
- * @param length
- */
- protected void fireStarted(String filename, String MIMEType) {
- fireEvent(new Upload.StartedEvent(this, filename, MIMEType,
- contentLength));
- }
-
- /**
- * Emits the upload failed event.
- *
- * @param filename
- * @param MIMEType
- * @param length
- */
- protected void fireUploadInterrupted(String filename, String MIMEType,
- long length) {
- fireEvent(new Upload.FailedEvent(this, filename, MIMEType, length));
- }
-
- protected void fireNoInputStream(String filename, String MIMEType,
- long length) {
- fireEvent(new Upload.NoInputStreamEvent(this, filename, MIMEType,
- length));
- }
-
- protected void fireNoOutputStream(String filename, String MIMEType,
- long length) {
- fireEvent(new Upload.NoOutputStreamEvent(this, filename, MIMEType,
- length));
- }
-
- protected void fireUploadInterrupted(String filename, String MIMEType,
- long length, Exception e) {
- fireEvent(new Upload.FailedEvent(this, filename, MIMEType, length, e));
- }
-
- /**
- * Emits the upload success event.
- *
- * @param filename
- * @param MIMEType
- * @param length
- *
- */
- protected void fireUploadSuccess(String filename, String MIMEType,
- long length) {
- fireEvent(new Upload.SucceededEvent(this, filename, MIMEType, length));
- }
-
- /**
- * Emits the progress event.
- *
- * @param totalBytes
- * bytes received so far
- * @param contentLength
- * actual size of the file being uploaded, if known
- *
- */
- protected void fireUpdateProgress(long totalBytes, long contentLength) {
- // this is implemented differently than other listeners to maintain
- // backwards compatibility
- if (progressListeners != null) {
- for (Iterator<ProgressListener> it = progressListeners.iterator(); it
- .hasNext();) {
- ProgressListener l = it.next();
- l.updateProgress(totalBytes, contentLength);
- }
- }
- }
-
- /**
- * Returns the current receiver.
- *
- * @return the StreamVariable.
- */
- public Receiver getReceiver() {
- return receiver;
- }
-
- /**
- * Sets the receiver.
- *
- * @param receiver
- * the receiver to set.
- */
- public void setReceiver(Receiver receiver) {
- this.receiver = receiver;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void focus() {
- super.focus();
- }
-
- /**
- * Gets the Tabulator index of this Focusable component.
- *
- * @see com.vaadin.ui.Component.Focusable#getTabIndex()
- */
- @Override
- public int getTabIndex() {
- return tabIndex;
- }
-
- /**
- * Sets the Tabulator index of this Focusable component.
- *
- * @see com.vaadin.ui.Component.Focusable#setTabIndex(int)
- */
- @Override
- public void setTabIndex(int tabIndex) {
- this.tabIndex = tabIndex;
- }
-
- /**
- * Go into upload state. This is to prevent double uploading on same
- * component.
- *
- * Warning: this is an internal method used by the framework and should not
- * be used by user of the Upload component. Using it results in the Upload
- * component going in wrong state and not working. It is currently public
- * because it is used by another class.
- */
- public void startUpload() {
- if (isUploading) {
- throw new IllegalStateException("uploading already started");
- }
- isUploading = true;
- nextid++;
- }
-
- /**
- * Interrupts the upload currently being received. The interruption will be
- * done by the receiving tread so this method will return immediately and
- * the actual interrupt will happen a bit later.
- */
- public void interruptUpload() {
- if (isUploading) {
- interrupted = true;
- }
- }
-
- /**
- * Go into state where new uploading can begin.
- *
- * Warning: this is an internal method used by the framework and should not
- * be used by user of the Upload component.
- */
- private void endUpload() {
- isUploading = false;
- contentLength = -1;
- interrupted = false;
- requestRepaint();
- }
-
- public boolean isUploading() {
- return isUploading;
- }
-
- /**
- * Gets read bytes of the file currently being uploaded.
- *
- * @return bytes
- */
- public long getBytesRead() {
- return totalBytes;
- }
-
- /**
- * Returns size of file currently being uploaded. Value sane only during
- * upload.
- *
- * @return size in bytes
- */
- public long getUploadSize() {
- return contentLength;
- }
-
- /**
- * This method is deprecated, use addListener(ProgressListener) instead.
- *
- * @deprecated Use addListener(ProgressListener) instead.
- * @param progressListener
- */
- @Deprecated
- public void setProgressListener(ProgressListener progressListener) {
- addListener(progressListener);
- }
-
- /**
- * This method is deprecated.
- *
- * @deprecated Replaced with addListener/removeListener
- * @return listener
- *
- */
- @Deprecated
- public ProgressListener getProgressListener() {
- if (progressListeners == null || progressListeners.isEmpty()) {
- return null;
- } else {
- return progressListeners.iterator().next();
- }
- }
-
- /**
- * ProgressListener receives events to track progress of upload.
- */
- public interface ProgressListener extends Serializable {
- /**
- * Updates progress to listener
- *
- * @param readBytes
- * bytes transferred
- * @param contentLength
- * total size of file currently being uploaded, -1 if unknown
- */
- public void updateProgress(long readBytes, long contentLength);
- }
-
- /**
- * @return String to be rendered into button that fires uploading
- */
- public String getButtonCaption() {
- return buttonCaption;
- }
-
- /**
- * In addition to the actual file chooser, upload components have button
- * that starts actual upload progress. This method is used to set text in
- * that button.
- * <p>
- * In case the button text is set to null, the button is hidden. In this
- * case developer must explicitly initiate the upload process with
- * {@link #submitUpload()}.
- * <p>
- * In case the Upload is used in immediate mode using
- * {@link #setImmediate(boolean)}, the file choose (html input with type
- * "file") is hidden and only the button with this text is shown.
- * <p>
- *
- * <p>
- * <strong>Note</strong> the string given is set as is to the button. HTML
- * formatting is not stripped. Be sure to properly validate your value
- * according to your needs.
- *
- * @param buttonCaption
- * text for upload components button.
- */
- public void setButtonCaption(String buttonCaption) {
- this.buttonCaption = buttonCaption;
- requestRepaint();
- }
-
- /**
- * Forces the upload the send selected file to the server.
- * <p>
- * In case developer wants to use this feature, he/she will most probably
- * want to hide the uploads internal submit button by setting its caption to
- * null with {@link #setButtonCaption(String)} method.
- * <p>
- * Note, that the upload runs asynchronous. Developer should use normal
- * upload listeners to trac the process of upload. If the field is empty
- * uploaded the file name will be empty string and file length 0 in the
- * upload finished event.
- * <p>
- * Also note, that the developer should not remove or modify the upload in
- * the same user transaction where the upload submit is requested. The
- * upload may safely be hidden or removed once the upload started event is
- * fired.
- */
- public void submitUpload() {
- requestRepaint();
- forceSubmit = true;
- }
-
- @Override
- public void requestRepaint() {
- forceSubmit = false;
- super.requestRepaint();
- }
-
- /*
- * Handle to terminal via Upload monitors and controls the upload during it
- * is being streamed.
- */
- private com.vaadin.terminal.StreamVariable streamVariable;
-
- protected com.vaadin.terminal.StreamVariable getStreamVariable() {
- if (streamVariable == null) {
- streamVariable = new com.vaadin.terminal.StreamVariable() {
- private StreamingStartEvent lastStartedEvent;
-
- @Override
- public boolean listenProgress() {
- return (progressListeners != null && !progressListeners
- .isEmpty());
- }
-
- @Override
- public void onProgress(StreamingProgressEvent event) {
- fireUpdateProgress(event.getBytesReceived(),
- event.getContentLength());
- }
-
- @Override
- public boolean isInterrupted() {
- return interrupted;
- }
-
- @Override
- public OutputStream getOutputStream() {
- OutputStream receiveUpload = receiver.receiveUpload(
- lastStartedEvent.getFileName(),
- lastStartedEvent.getMimeType());
- lastStartedEvent = null;
- return receiveUpload;
- }
-
- @Override
- public void streamingStarted(StreamingStartEvent event) {
- startUpload();
- contentLength = event.getContentLength();
- fireStarted(event.getFileName(), event.getMimeType());
- lastStartedEvent = event;
- }
-
- @Override
- public void streamingFinished(StreamingEndEvent event) {
- fireUploadSuccess(event.getFileName(), event.getMimeType(),
- event.getContentLength());
- endUpload();
- requestRepaint();
- }
-
- @Override
- public void streamingFailed(StreamingErrorEvent event) {
- Exception exception = event.getException();
- if (exception instanceof NoInputStreamException) {
- fireNoInputStream(event.getFileName(),
- event.getMimeType(), 0);
- } else if (exception instanceof NoOutputStreamException) {
- fireNoOutputStream(event.getFileName(),
- event.getMimeType(), 0);
- } else {
- fireUploadInterrupted(event.getFileName(),
- event.getMimeType(), 0, exception);
- }
- endUpload();
- }
- };
- }
- return streamVariable;
- }
-
- @Override
- public java.util.Collection<?> getListeners(java.lang.Class<?> eventType) {
- if (StreamingProgressEvent.class.isAssignableFrom(eventType)) {
- if (progressListeners == null) {
- return Collections.EMPTY_LIST;
- } else {
- return Collections.unmodifiableCollection(progressListeners);
- }
-
- }
- return super.getListeners(eventType);
- };
-}
diff --git a/src/com/vaadin/ui/VerticalLayout.java b/src/com/vaadin/ui/VerticalLayout.java
deleted file mode 100644
index a04d052d98..0000000000
--- a/src/com/vaadin/ui/VerticalLayout.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-/**
- * Vertical layout
- *
- * <code>VerticalLayout</code> is a component container, which shows the
- * subcomponents in the order of their addition (vertically). A vertical layout
- * is by default 100% wide.
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 5.3
- */
-@SuppressWarnings("serial")
-public class VerticalLayout extends AbstractOrderedLayout {
-
- public VerticalLayout() {
- setWidth("100%");
- }
-
-}
diff --git a/src/com/vaadin/ui/VerticalSplitPanel.java b/src/com/vaadin/ui/VerticalSplitPanel.java
deleted file mode 100644
index 0630240e9c..0000000000
--- a/src/com/vaadin/ui/VerticalSplitPanel.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-/**
- * A vertical split panel contains two components and lays them vertically. The
- * first component is above the second component.
- *
- * <pre>
- * +--------------------------+
- * | |
- * | The first component |
- * | |
- * +==========================+ <-- splitter
- * | |
- * | The second component |
- * | |
- * +--------------------------+
- * </pre>
- *
- */
-public class VerticalSplitPanel extends AbstractSplitPanel {
-
- public VerticalSplitPanel() {
- super();
- setSizeFull();
- }
-
-}
diff --git a/src/com/vaadin/ui/Video.java b/src/com/vaadin/ui/Video.java
deleted file mode 100644
index d4f95a5be3..0000000000
--- a/src/com/vaadin/ui/Video.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import com.vaadin.shared.ui.video.VideoState;
-import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.server.ResourceReference;
-
-/**
- * The Video component translates into an HTML5 &lt;video&gt; element and as
- * such is only supported in browsers that support HTML5 media markup. Browsers
- * that do not support HTML5 display the text or HTML set by calling
- * {@link #setAltText(String)}.
- *
- * A flash-player fallback can be implemented by setting HTML content allowed (
- * {@link #setHtmlContentAllowed(boolean)} and calling
- * {@link #setAltText(String)} with the flash player markup. An example of flash
- * fallback can be found at the <a href=
- * "https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Using_Flash"
- * >Mozilla Developer Network</a>.
- *
- * Multiple sources can be specified. Which of the sources is used is selected
- * by the browser depending on which file formats it supports. See <a
- * href="http://en.wikipedia.org/wiki/HTML5_video#Table">wikipedia</a> for a
- * table of formats supported by different browsers.
- *
- * @author Vaadin Ltd
- * @since 6.7.0
- */
-public class Video extends AbstractMedia {
-
- @Override
- public VideoState getState() {
- return (VideoState) super.getState();
- }
-
- public Video() {
- this("", null);
- }
-
- /**
- * @param caption
- * The caption for this video.
- */
- public Video(String caption) {
- this(caption, null);
- }
-
- /**
- * @param caption
- * The caption for this video.
- * @param source
- * The Resource containing the video to play.
- */
- public Video(String caption, Resource source) {
- setCaption(caption);
- setSource(source);
- setShowControls(true);
- }
-
- /**
- * Sets the poster image, which is shown in place of the video before the
- * user presses play.
- *
- * @param poster
- */
- public void setPoster(Resource poster) {
- getState().setPoster(ResourceReference.create(poster));
- requestRepaint();
- }
-
- /**
- * @return The poster image.
- */
- public Resource getPoster() {
- return ResourceReference.getResource(getState().getPoster());
- }
-
-}
diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java
deleted file mode 100644
index e413d35e6d..0000000000
--- a/src/com/vaadin/ui/Window.java
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.BlurNotifier;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.event.FieldEvents.FocusNotifier;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.ShortcutAction;
-import com.vaadin.event.ShortcutAction.KeyCode;
-import com.vaadin.event.ShortcutAction.ModifierKey;
-import com.vaadin.event.ShortcutListener;
-import com.vaadin.shared.MouseEventDetails;
-import com.vaadin.shared.ui.window.WindowServerRpc;
-import com.vaadin.shared.ui.window.WindowState;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
-import com.vaadin.terminal.gwt.client.ui.root.VRoot;
-
-/**
- * A component that represents a floating popup window that can be added to a
- * {@link Root}. A window is added to a {@code Root} using
- * {@link Root#addWindow(Window)}. </p>
- * <p>
- * The contents of a window is set using {@link #setContent(ComponentContainer)}
- * or by using the {@link #Window(String, ComponentContainer)} constructor. The
- * contents can in turn contain other components. By default, a
- * {@link VerticalLayout} is used as content.
- * </p>
- * <p>
- * A window can be positioned on the screen using absolute coordinates (pixels)
- * or set to be centered using {@link #center()}
- * </p>
- * <p>
- * The caption is displayed in the window header.
- * </p>
- * <p>
- * In Vaadin versions prior to 7.0.0, Window was also used as application level
- * windows. This function is now covered by the {@link Root} class.
- * </p>
- *
- * @author Vaadin Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
-@SuppressWarnings("serial")
-public class Window extends Panel implements FocusNotifier, BlurNotifier,
- Vaadin6Component {
-
- private WindowServerRpc rpc = new WindowServerRpc() {
-
- @Override
- public void click(MouseEventDetails mouseDetails) {
- fireEvent(new ClickEvent(Window.this, mouseDetails));
- }
- };
-
- private int browserWindowWidth = -1;
-
- private int browserWindowHeight = -1;
-
- /**
- * Creates a new unnamed window with a default layout.
- */
- public Window() {
- this("", null);
- }
-
- /**
- * Creates a new unnamed window with a default layout and given title.
- *
- * @param caption
- * the title of the window.
- */
- public Window(String caption) {
- this(caption, null);
- }
-
- /**
- * Creates a new unnamed window with the given content and title.
- *
- * @param caption
- * the title of the window.
- * @param content
- * the contents of the window
- */
- public Window(String caption, ComponentContainer content) {
- super(caption, content);
- registerRpc(rpc);
- setSizeUndefined();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Panel#addComponent(com.vaadin.ui.Component)
- */
-
- @Override
- public void addComponent(Component c) {
- if (c instanceof Window) {
- throw new IllegalArgumentException(
- "Window cannot be added to another via addComponent. "
- + "Use addWindow(Window) instead.");
- }
- super.addComponent(c);
- }
-
- /* ********************************************************************* */
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Panel#paintContent(com.vaadin.terminal.PaintTarget)
- */
-
- @Override
- public synchronized void paintContent(PaintTarget target)
- throws PaintException {
- if (bringToFront != null) {
- target.addAttribute("bringToFront", bringToFront.intValue());
- bringToFront = null;
- }
-
- // Contents of the window panel is painted
- super.paintContent(target);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.ui.Panel#changeVariables(java.lang.Object, java.util.Map)
- */
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
-
- // TODO Are these for top level windows or sub windows?
- boolean sizeHasChanged = false;
- // size is handled in super class, but resize events only in windows ->
- // so detect if size change occurs before super.changeVariables()
- if (variables.containsKey("height")
- && (getHeightUnits() != Unit.PIXELS || (Integer) variables
- .get("height") != getHeight())) {
- sizeHasChanged = true;
- }
- if (variables.containsKey("width")
- && (getWidthUnits() != Unit.PIXELS || (Integer) variables
- .get("width") != getWidth())) {
- sizeHasChanged = true;
- }
- Integer browserHeightVar = (Integer) variables
- .get(VRoot.BROWSER_HEIGHT_VAR);
- if (browserHeightVar != null
- && browserHeightVar.intValue() != browserWindowHeight) {
- browserWindowHeight = browserHeightVar.intValue();
- sizeHasChanged = true;
- }
- Integer browserWidthVar = (Integer) variables
- .get(VRoot.BROWSER_WIDTH_VAR);
- if (browserWidthVar != null
- && browserWidthVar.intValue() != browserWindowWidth) {
- browserWindowWidth = browserWidthVar.intValue();
- sizeHasChanged = true;
- }
-
- super.changeVariables(source, variables);
-
- // Positioning
- final Integer positionx = (Integer) variables.get("positionx");
- if (positionx != null) {
- final int x = positionx.intValue();
- // This is information from the client so it is already using the
- // position. No need to repaint.
- setPositionX(x < 0 ? -1 : x, false);
- }
- final Integer positiony = (Integer) variables.get("positiony");
- if (positiony != null) {
- final int y = positiony.intValue();
- // This is information from the client so it is already using the
- // position. No need to repaint.
- setPositionY(y < 0 ? -1 : y, false);
- }
-
- if (isClosable()) {
- // Closing
- final Boolean close = (Boolean) variables.get("close");
- if (close != null && close.booleanValue()) {
- close();
- }
- }
-
- // fire event if size has really changed
- if (sizeHasChanged) {
- fireResize();
- }
-
- if (variables.containsKey(FocusEvent.EVENT_ID)) {
- fireEvent(new FocusEvent(this));
- } else if (variables.containsKey(BlurEvent.EVENT_ID)) {
- fireEvent(new BlurEvent(this));
- }
-
- }
-
- /**
- * Method that handles window closing (from UI).
- *
- * <p>
- * By default, sub-windows are removed from their respective parent windows
- * and thus visually closed on browser-side. Browser-level windows also
- * closed on the client-side, but they are not implicitly removed from the
- * application.
- * </p>
- *
- * <p>
- * To explicitly close a sub-window, use {@link #removeWindow(Window)}. To
- * react to a window being closed (after it is closed), register a
- * {@link CloseListener}.
- * </p>
- */
- public void close() {
- Root root = getRoot();
-
- // Don't do anything if not attached to a root
- if (root != null) {
- // focus is restored to the parent window
- root.focus();
- // subwindow is removed from the root
- root.removeWindow(this);
- }
- }
-
- /**
- * Gets the distance of Window left border in pixels from left border of the
- * containing (main window).
- *
- * @return the Distance of Window left border in pixels from left border of
- * the containing (main window). or -1 if unspecified.
- * @since 4.0.0
- */
- public int getPositionX() {
- return getState().getPositionX();
- }
-
- /**
- * Sets the distance of Window left border in pixels from left border of the
- * containing (main window).
- *
- * @param positionX
- * the Distance of Window left border in pixels from left border
- * of the containing (main window). or -1 if unspecified.
- * @since 4.0.0
- */
- public void setPositionX(int positionX) {
- setPositionX(positionX, true);
- }
-
- /**
- * Sets the distance of Window left border in pixels from left border of the
- * containing (main window).
- *
- * @param positionX
- * the Distance of Window left border in pixels from left border
- * of the containing (main window). or -1 if unspecified.
- * @param repaintRequired
- * true if the window needs to be repainted, false otherwise
- * @since 6.3.4
- */
- private void setPositionX(int positionX, boolean repaintRequired) {
- getState().setPositionX(positionX);
- getState().setCentered(false);
- if (repaintRequired) {
- requestRepaint();
- }
- }
-
- /**
- * Gets the distance of Window top border in pixels from top border of the
- * containing (main window).
- *
- * @return Distance of Window top border in pixels from top border of the
- * containing (main window). or -1 if unspecified .
- *
- * @since 4.0.0
- */
- public int getPositionY() {
- return getState().getPositionY();
- }
-
- /**
- * Sets the distance of Window top border in pixels from top border of the
- * containing (main window).
- *
- * @param positionY
- * the Distance of Window top border in pixels from top border of
- * the containing (main window). or -1 if unspecified
- *
- * @since 4.0.0
- */
- public void setPositionY(int positionY) {
- setPositionY(positionY, true);
- }
-
- /**
- * Sets the distance of Window top border in pixels from top border of the
- * containing (main window).
- *
- * @param positionY
- * the Distance of Window top border in pixels from top border of
- * the containing (main window). or -1 if unspecified
- * @param repaintRequired
- * true if the window needs to be repainted, false otherwise
- *
- * @since 6.3.4
- */
- private void setPositionY(int positionY, boolean repaintRequired) {
- getState().setPositionY(positionY);
- getState().setCentered(false);
- if (repaintRequired) {
- requestRepaint();
- }
- }
-
- private static final Method WINDOW_CLOSE_METHOD;
- static {
- try {
- WINDOW_CLOSE_METHOD = CloseListener.class.getDeclaredMethod(
- "windowClose", new Class[] { CloseEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error, window close method not found");
- }
- }
-
- public class CloseEvent extends Component.Event {
-
- /**
- *
- * @param source
- */
- public CloseEvent(Component source) {
- super(source);
- }
-
- /**
- * Gets the Window.
- *
- * @return the window.
- */
- public Window getWindow() {
- return (Window) getSource();
- }
- }
-
- /**
- * An interface used for listening to Window close events. Add the
- * CloseListener to a browser level window or a sub window and
- * {@link CloseListener#windowClose(CloseEvent)} will be called whenever the
- * user closes the window.
- *
- * <p>
- * Since Vaadin 6.5, removing a window using {@link #removeWindow(Window)}
- * fires the CloseListener.
- * </p>
- */
- public interface CloseListener extends Serializable {
- /**
- * Called when the user closes a window. Use
- * {@link CloseEvent#getWindow()} to get a reference to the
- * {@link Window} that was closed.
- *
- * @param e
- * Event containing
- */
- public void windowClose(CloseEvent e);
- }
-
- /**
- * Adds a CloseListener to the window.
- *
- * For a sub window the CloseListener is fired when the user closes it
- * (clicks on the close button).
- *
- * For a browser level window the CloseListener is fired when the browser
- * level window is closed. Note that closing a browser level window does not
- * mean it will be destroyed. Also note that Opera does not send events like
- * all other browsers and therefore the close listener might not be called
- * if Opera is used.
- *
- * <p>
- * Since Vaadin 6.5, removing windows using {@link #removeWindow(Window)}
- * does fire the CloseListener.
- * </p>
- *
- * @param listener
- * the CloseListener to add.
- */
- public void addListener(CloseListener listener) {
- addListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
- }
-
- /**
- * Removes the CloseListener from the window.
- *
- * <p>
- * For more information on CloseListeners see {@link CloseListener}.
- * </p>
- *
- * @param listener
- * the CloseListener to remove.
- */
- public void removeListener(CloseListener listener) {
- removeListener(CloseEvent.class, listener, WINDOW_CLOSE_METHOD);
- }
-
- protected void fireClose() {
- fireEvent(new Window.CloseEvent(this));
- }
-
- /**
- * Method for the resize event.
- */
- private static final Method WINDOW_RESIZE_METHOD;
- static {
- try {
- WINDOW_RESIZE_METHOD = ResizeListener.class.getDeclaredMethod(
- "windowResized", new Class[] { ResizeEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error, window resized method not found");
- }
- }
-
- /**
- * Resize events are fired whenever the client-side fires a resize-event
- * (e.g. the browser window is resized). The frequency may vary across
- * browsers.
- */
- public class ResizeEvent extends Component.Event {
-
- /**
- *
- * @param source
- */
- public ResizeEvent(Component source) {
- super(source);
- }
-
- /**
- * Get the window form which this event originated
- *
- * @return the window
- */
- public Window getWindow() {
- return (Window) getSource();
- }
- }
-
- /**
- * Listener for window resize events.
- *
- * @see com.vaadin.ui.Window.ResizeEvent
- */
- public interface ResizeListener extends Serializable {
- public void windowResized(ResizeEvent e);
- }
-
- /**
- * Add a resize listener.
- *
- * @param listener
- */
- public void addListener(ResizeListener listener) {
- addListener(ResizeEvent.class, listener, WINDOW_RESIZE_METHOD);
- }
-
- /**
- * Remove a resize listener.
- *
- * @param listener
- */
- public void removeListener(ResizeListener listener) {
- removeListener(ResizeEvent.class, listener);
- }
-
- /**
- * Fire the resize event.
- */
- protected void fireResize() {
- fireEvent(new ResizeEvent(this));
- }
-
- /**
- * Used to keep the right order of windows if multiple windows are brought
- * to front in a single changeset. If this is not used, the order is quite
- * random (depends on the order getting to dirty list. e.g. which window got
- * variable changes).
- */
- private Integer bringToFront = null;
-
- /**
- * If there are currently several windows visible, calling this method makes
- * this window topmost.
- * <p>
- * This method can only be called if this window connected a root. Else an
- * illegal state exception is thrown. Also if there are modal windows and
- * this window is not modal, and illegal state exception is thrown.
- * <p>
- */
- public void bringToFront() {
- Root root = getRoot();
- if (root == null) {
- throw new IllegalStateException(
- "Window must be attached to parent before calling bringToFront method.");
- }
- int maxBringToFront = -1;
- for (Window w : root.getWindows()) {
- if (!isModal() && w.isModal()) {
- throw new IllegalStateException(
- "The root contains modal windows, non-modal window cannot be brought to front.");
- }
- if (w.bringToFront != null) {
- maxBringToFront = Math.max(maxBringToFront,
- w.bringToFront.intValue());
- }
- }
- bringToFront = Integer.valueOf(maxBringToFront + 1);
- requestRepaint();
- }
-
- /**
- * Sets sub-window modal, so that widgets behind it cannot be accessed.
- * <b>Note:</b> affects sub-windows only.
- *
- * @param modal
- * true if modality is to be turned on
- */
- public void setModal(boolean modal) {
- getState().setModal(modal);
- center();
- requestRepaint();
- }
-
- /**
- * @return true if this window is modal.
- */
- public boolean isModal() {
- return getState().isModal();
- }
-
- /**
- * Sets sub-window resizable. <b>Note:</b> affects sub-windows only.
- *
- * @param resizable
- * true if resizability is to be turned on
- */
- public void setResizable(boolean resizable) {
- getState().setResizable(resizable);
- requestRepaint();
- }
-
- /**
- *
- * @return true if window is resizable by the end-user, otherwise false.
- */
- public boolean isResizable() {
- return getState().isResizable();
- }
-
- /**
- *
- * @return true if a delay is used before recalculating sizes, false if
- * sizes are recalculated immediately.
- */
- public boolean isResizeLazy() {
- return getState().isResizeLazy();
- }
-
- /**
- * Should resize operations be lazy, i.e. should there be a delay before
- * layout sizes are recalculated. Speeds up resize operations in slow UIs
- * with the penalty of slightly decreased usability.
- *
- * Note, some browser send false resize events for the browser window and
- * are therefore always lazy.
- *
- * @param resizeLazy
- * true to use a delay before recalculating sizes, false to
- * calculate immediately.
- */
- public void setResizeLazy(boolean resizeLazy) {
- getState().setResizeLazy(resizeLazy);
- requestRepaint();
- }
-
- /**
- * Sets this window to be centered relative to its parent window. Affects
- * sub-windows only. If the window is resized as a result of the size of its
- * content changing, it will keep itself centered as long as its position is
- * not explicitly changed programmatically or by the user.
- * <p>
- * <b>NOTE:</b> This method has several issues as currently implemented.
- * Please refer to http://dev.vaadin.com/ticket/8971 for details.
- */
- public void center() {
- getState().setCentered(true);
- requestRepaint();
- }
-
- /**
- * Returns the closable status of the sub window. If a sub window is
- * closable it typically shows an X in the upper right corner. Clicking on
- * the X sends a close event to the server. Setting closable to false will
- * remove the X from the sub window and prevent the user from closing the
- * window.
- *
- * Note! For historical reasons readonly controls the closability of the sub
- * window and therefore readonly and closable affect each other. Setting
- * readonly to true will set closable to false and vice versa.
- * <p/>
- * Closable only applies to sub windows, not to browser level windows.
- *
- * @return true if the sub window can be closed by the user.
- */
- public boolean isClosable() {
- return !isReadOnly();
- }
-
- /**
- * Sets the closable status for the sub window. If a sub window is closable
- * it typically shows an X in the upper right corner. Clicking on the X
- * sends a close event to the server. Setting closable to false will remove
- * the X from the sub window and prevent the user from closing the window.
- *
- * Note! For historical reasons readonly controls the closability of the sub
- * window and therefore readonly and closable affect each other. Setting
- * readonly to true will set closable to false and vice versa.
- * <p/>
- * Closable only applies to sub windows, not to browser level windows.
- *
- * @param closable
- * determines if the sub window can be closed by the user.
- */
- public void setClosable(boolean closable) {
- setReadOnly(!closable);
- }
-
- /**
- * Indicates whether a sub window can be dragged or not. By default a sub
- * window is draggable.
- * <p/>
- * Draggable only applies to sub windows, not to browser level windows.
- *
- * @param draggable
- * true if the sub window can be dragged by the user
- */
- public boolean isDraggable() {
- return getState().isDraggable();
- }
-
- /**
- * Enables or disables that a sub window can be dragged (moved) by the user.
- * By default a sub window is draggable.
- * <p/>
- * Draggable only applies to sub windows, not to browser level windows.
- *
- * @param draggable
- * true if the sub window can be dragged by the user
- */
- public void setDraggable(boolean draggable) {
- getState().setDraggable(draggable);
- requestRepaint();
- }
-
- /*
- * Actions
- */
- protected CloseShortcut closeShortcut;
-
- /**
- * Makes is possible to close the window by pressing the given
- * {@link KeyCode} and (optional) {@link ModifierKey}s.<br/>
- * Note that this shortcut only reacts while the window has focus, closing
- * itself - if you want to close a subwindow from a parent window, use
- * {@link #addAction(com.vaadin.event.Action)} of the parent window instead.
- *
- * @param keyCode
- * the keycode for invoking the shortcut
- * @param modifiers
- * the (optional) modifiers for invoking the shortcut, null for
- * none
- */
- public void setCloseShortcut(int keyCode, int... modifiers) {
- if (closeShortcut != null) {
- removeAction(closeShortcut);
- }
- closeShortcut = new CloseShortcut(this, keyCode, modifiers);
- addAction(closeShortcut);
- }
-
- /**
- * Removes the keyboard shortcut previously set with
- * {@link #setCloseShortcut(int, int...)}.
- */
- public void removeCloseShortcut() {
- if (closeShortcut != null) {
- removeAction(closeShortcut);
- closeShortcut = null;
- }
- }
-
- /**
- * A {@link ShortcutListener} specifically made to define a keyboard
- * shortcut that closes the window.
- *
- * <pre>
- * <code>
- * // within the window using helper
- * subWindow.setCloseShortcut(KeyCode.ESCAPE, null);
- *
- * // or globally
- * getWindow().addAction(new Window.CloseShortcut(subWindow, KeyCode.ESCAPE));
- * </code>
- * </pre>
- *
- */
- public static class CloseShortcut extends ShortcutListener {
- protected Window window;
-
- /**
- * Creates a keyboard shortcut for closing the given window using the
- * shorthand notation defined in {@link ShortcutAction}.
- *
- * @param window
- * to be closed when the shortcut is invoked
- * @param shorthandCaption
- * the caption with shortcut keycode and modifiers indicated
- */
- public CloseShortcut(Window window, String shorthandCaption) {
- super(shorthandCaption);
- this.window = window;
- }
-
- /**
- * Creates a keyboard shortcut for closing the given window using the
- * given {@link KeyCode} and {@link ModifierKey}s.
- *
- * @param window
- * to be closed when the shortcut is invoked
- * @param keyCode
- * KeyCode to react to
- * @param modifiers
- * optional modifiers for shortcut
- */
- public CloseShortcut(Window window, int keyCode, int... modifiers) {
- super(null, keyCode, modifiers);
- this.window = window;
- }
-
- /**
- * Creates a keyboard shortcut for closing the given window using the
- * given {@link KeyCode}.
- *
- * @param window
- * to be closed when the shortcut is invoked
- * @param keyCode
- * KeyCode to react to
- */
- public CloseShortcut(Window window, int keyCode) {
- this(window, keyCode, null);
- }
-
- @Override
- public void handleAction(Object sender, Object target) {
- window.close();
- }
- }
-
- /**
- * Note, that focus/blur listeners in Window class are only supported by sub
- * windows. Also note that Window is not considered focused if its contained
- * component currently has focus.
- *
- * @see com.vaadin.event.FieldEvents.FocusNotifier#addListener(com.vaadin.event.FieldEvents.FocusListener)
- */
-
- @Override
- public void addListener(FocusListener listener) {
- addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener,
- FocusListener.focusMethod);
- }
-
- @Override
- public void removeListener(FocusListener listener) {
- removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener);
- }
-
- /**
- * Note, that focus/blur listeners in Window class are only supported by sub
- * windows. Also note that Window is not considered focused if its contained
- * component currently has focus.
- *
- * @see com.vaadin.event.FieldEvents.BlurNotifier#addListener(com.vaadin.event.FieldEvents.BlurListener)
- */
-
- @Override
- public void addListener(BlurListener listener) {
- addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener,
- BlurListener.blurMethod);
- }
-
- @Override
- public void removeListener(BlurListener listener) {
- removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
- }
-
- /**
- * {@inheritDoc}
- *
- * If the window is a sub-window focusing will cause the sub-window to be
- * brought on top of other sub-windows on gain keyboard focus.
- */
-
- @Override
- public void focus() {
- /*
- * When focusing a sub-window it basically means it should be brought to
- * the front. Instead of just moving the keyboard focus we focus the
- * window and bring it top-most.
- */
- super.focus();
- bringToFront();
- }
-
- @Override
- public WindowState getState() {
- return (WindowState) super.getState();
- }
-}
diff --git a/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif b/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif
deleted file mode 100644
index 936c220d11..0000000000
--- a/src/com/vaadin/ui/doc-files/component_class_hierarchy.gif
+++ /dev/null
Binary files differ
diff --git a/src/com/vaadin/ui/doc-files/component_interfaces.gif b/src/com/vaadin/ui/doc-files/component_interfaces.gif
deleted file mode 100644
index 44c99826bb..0000000000
--- a/src/com/vaadin/ui/doc-files/component_interfaces.gif
+++ /dev/null
Binary files differ
diff --git a/src/com/vaadin/ui/package.html b/src/com/vaadin/ui/package.html
deleted file mode 100644
index 6b19a28fe7..0000000000
--- a/src/com/vaadin/ui/package.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-
-</head>
-
-<body bgcolor="white">
-
-<!-- Package summary here -->
-
-<p>Provides interfaces and classes in Vaadin.</p>
-
-<h2>Package Specification</h2>
-
-<p><strong>Interface hierarchy</strong></p>
-
-<p>The general interface hierarchy looks like this:</p>
-
-<p style="text-align: center;"><img
- src="doc-files/component_interfaces.gif" /></p>
-
-<p><i>Note that the above picture includes only the main
-interfaces. This package includes several other lesser sub-interfaces
-which are not significant in this scope. The interfaces not appearing
-here are documented with the classes that define them.</i></p>
-
-<p>The {@link com.vaadin.ui.Component} interface is the top-level
-interface which must be implemented by all user interface components in
-Vaadin. It defines the common properties of the components and how the
-framework will handle them. Most simple components, such as {@link
-com.vaadin.ui.Button}, for example, do not need to implement the
-lower-level interfaces described below. Notice that also the classes and
-interfaces required by the component event framework are defined in
-{@link com.vaadin.ui.Component}.</p>
-
-<p>The next level in the component hierarchy are the classes
-implementing the {@link com.vaadin.ui.ComponentContainer} interface. It
-adds the capacity to contain other components to {@link
-com.vaadin.ui.Component} with a simple API.</p>
-
-<p>The third and last level is the {@link com.vaadin.ui.Layout},
-which adds the concept of location to the components contained in a
-{@link com.vaadin.ui.ComponentContainer}. It can be used to create
-containers which contents can be positioned.</p>
-
-<p><strong>Component class hierarchy</strong></p>
-
-<p>The actual component classes form a hierarchy like this:</p>
-
-<center><img src="doc-files/component_class_hierarchy.gif" /></center>
-<br />
-
-<center><i>Underlined classes are abstract.</i></center>
-
-<p>At the top level is {@link com.vaadin.ui.AbstractComponent} which
-implements the {@link com.vaadin.ui.Component} interface. As the name
-suggests it is abstract, but it does include a default implementation
-for all methods defined in <code>Component</code> so that a component is
-free to override only those functionalities it needs.</p>
-
-<p>As seen in the picture, <code>AbstractComponent</code> serves as
-the superclass for several "real" components, but it also has a some
-abstract extensions. {@link com.vaadin.ui.AbstractComponentContainer}
-serves as the root class for all components (for example, panels and
-windows) who can contain other components. {@link
-com.vaadin.ui.AbstractField}, on the other hand, implements several
-interfaces to provide a base class for components that are used for data
-display and manipulation.</p>
-
-
-<!-- Package spec here -->
-
-<!-- Put @see and @since tags down here. -->
-
-</body>
-</html>
diff --git a/src/com/vaadin/ui/themes/BaseTheme.java b/src/com/vaadin/ui/themes/BaseTheme.java
deleted file mode 100644
index 6f448746bf..0000000000
--- a/src/com/vaadin/ui/themes/BaseTheme.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui.themes;
-
-/**
- * <p>
- * The Base theme is the foundation for all Vaadin themes. Although it is not
- * necessary to use it as the starting point for all other themes, it is heavily
- * encouraged, since it abstracts and hides away many necessary style properties
- * that the Vaadin terminal expects and needs.
- * </p>
- * <p>
- * When creating your own theme, either extend this class and specify the styles
- * implemented in your theme here, or extend some other theme that has a class
- * file specified (e.g. Reindeer or Runo).
- * </p>
- * <p>
- * All theme class files should follow the convention of specifying the theme
- * name as a string constant <code>THEME_NAME</code>.
- *
- * @since 6.3.0
- *
- */
-public class BaseTheme {
-
- public static final String THEME_NAME = "base";
-
- /**
- * Creates a button that looks like a regular hypertext link but still acts
- * like a normal button.
- */
- public static final String BUTTON_LINK = "link";
-
- /**
- * Removes extra decorations from the panel.
- *
- * @deprecated Base theme does not implement this style, but it is defined
- * here since it has been a part of the framework before
- * multiple themes were available. Use the constant provided by
- * the theme you're using instead, e.g.
- * {@link Reindeer#PANEL_LIGHT} or {@link Runo#PANEL_LIGHT}.
- */
- @Deprecated
- public static final String PANEL_LIGHT = "light";
-
- /**
- * Adds the connector lines between a parent node and its child nodes to
- * indicate the tree hierarchy better.
- */
- public static final String TREE_CONNECTORS = "connectors";
-
- /**
- * Clips the component so it will be constrained to its given size and not
- * overflow.
- */
- public static final String CLIP = "v-clip";
-
-} \ No newline at end of file
diff --git a/src/com/vaadin/ui/themes/ChameleonTheme.java b/src/com/vaadin/ui/themes/ChameleonTheme.java
deleted file mode 100644
index 5ae8cd4e57..0000000000
--- a/src/com/vaadin/ui/themes/ChameleonTheme.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui.themes;
-
-public class ChameleonTheme extends BaseTheme {
-
- public static final String THEME_NAME = "chameleon";
-
- /***************************************************************************
- * Label styles
- **************************************************************************/
-
- /**
- * Large font for main application headings
- */
- public static final String LABEL_H1 = "h1";
-
- /**
- * Large font for different sections in the application
- */
- public static final String LABEL_H2 = "h2";
-
- /**
- * Font for sub-section headers
- */
- public static final String LABEL_H3 = "h3";
-
- /**
- * Font for paragraphs headers
- */
- public static final String LABEL_H4 = "h4";
-
- /**
- * Big font for important or emphasized texts
- */
- public static final String LABEL_BIG = "big";
-
- /**
- * Small and a little lighter font
- */
- public static final String LABEL_SMALL = "small";
-
- /**
- * Very small and lighter font for things such as footnotes and component
- * specific informations. Use carefully, since this style will usually
- * reduce legibility.
- */
- public static final String LABEL_TINY = "tiny";
-
- /**
- * Adds color to the text (usually the alternate color of the theme)
- */
- public static final String LABEL_COLOR = "color";
-
- /**
- * Adds a warning icon on the left side and a yellow background to the label
- */
- public static final String LABEL_WARNING = "warning";
-
- /**
- * Adds an error icon on the left side and a red background to the label
- */
- public static final String LABEL_ERROR = "error";
-
- /**
- * Adds a spinner icon on the left side of the label
- */
- public static final String LABEL_LOADING = "loading";
-
- /***************************************************************************
- * Button styles
- **************************************************************************/
-
- /**
- * Default action style for buttons (the button that gets activated when
- * user presses 'enter' in a form). Use sparingly, only one default button
- * per screen should be visible.
- */
- public static final String BUTTON_DEFAULT = "default";
-
- /**
- * Small sized button, use for context specific actions for example
- */
- public static final String BUTTON_SMALL = "small";
-
- /**
- * Big button, use to get more attention for the button action
- */
- public static final String BUTTON_BIG = "big";
-
- /**
- * Adds more padding on the sides of the button. Makes it easier for the
- * user to hit the button.
- */
- public static final String BUTTON_WIDE = "wide";
-
- /**
- * Adds more padding on the top and on the bottom of the button. Makes it
- * easier for the user to hit the button.
- */
- public static final String BUTTON_TALL = "tall";
-
- /**
- * Removes all graphics from the button, leaving only the caption and the
- * icon visible. Useful for making icon-only buttons and toolbar buttons.
- */
- public static final String BUTTON_BORDERLESS = "borderless";
-
- /**
- * Places the button icon on top of the caption. By default the icon is on
- * the left side of the button caption.
- */
- public static final String BUTTON_ICON_ON_TOP = "icon-on-top";
-
- /**
- * Places the button icon on the right side of the caption. By default the
- * icon is on the left side of the button caption.
- */
- public static final String BUTTON_ICON_ON_RIGHT = "icon-on-right";
-
- /**
- * Removes the button caption and only shows its icon
- */
- public static final String BUTTON_ICON_ONLY = "icon-only";
-
- /**
- * Makes the button look like it is pressed down. Useful for creating a
- * toggle button.
- */
- public static final String BUTTON_DOWN = "down";
-
- /***************************************************************************
- * TextField styles
- **************************************************************************/
-
- /**
- * Small sized text field with small font
- */
- public static final String TEXTFIELD_SMALL = "small";
-
- /**
- * Large sized text field with big font
- */
- public static final String TEXTFIELD_BIG = "big";
-
- /**
- * Adds a magnifier icon on the left side of the fields text
- */
- public static final String TEXTFIELD_SEARCH = "search";
-
- /***************************************************************************
- * Select styles
- **************************************************************************/
-
- /**
- * Small sized select with small font
- */
- public static final String SELECT_SMALL = "small";
-
- /**
- * Large sized select with big font
- */
- public static final String SELECT_BIG = "big";
-
- /**
- * Adds a magnifier icon on the left side of the fields text
- */
- public static final String COMBOBOX_SEARCH = "search";
-
- /**
- * Adds a magnifier icon on the left side of the fields text
- */
- public static final String COMBOBOX_SELECT_BUTTON = "select-button";
-
- /***************************************************************************
- * DateField styles
- **************************************************************************/
-
- /**
- * Small sized date field with small font
- */
- public static final String DATEFIELD_SMALL = "small";
-
- /**
- * Large sized date field with big font
- */
- public static final String DATEFIELD_BIG = "big";
-
- /***************************************************************************
- * Panel styles
- **************************************************************************/
-
- /**
- * Removes borders and background color from the panel
- */
- public static final String PANEL_BORDERLESS = "borderless";
-
- /**
- * Adds a more vibrant header for the panel, using the alternate color of
- * the theme, and adds slight rounded corners (not supported in all
- * browsers)
- */
- public static final String PANEL_BUBBLE = "bubble";
-
- /**
- * Removes borders and background color from the panel
- */
- public static final String PANEL_LIGHT = "light";
-
- /***************************************************************************
- * SplitPanel styles
- **************************************************************************/
-
- /**
- * Reduces the split handle to a minimal size (1 pixel)
- */
- public static final String SPLITPANEL_SMALL = "small";
-
- /***************************************************************************
- * TabSheet styles
- **************************************************************************/
-
- /**
- * Removes borders and background color from the tab sheet
- */
- public static final String TABSHEET_BORDERLESS = "borderless";
-
- /***************************************************************************
- * Accordion styles
- **************************************************************************/
-
- /**
- * Makes the accordion background opaque (non-transparent)
- */
- public static final String ACCORDION_OPAQUE = "opaque";
-
- /***************************************************************************
- * Table styles
- **************************************************************************/
-
- /**
- * Removes borders and background color from the table
- */
- public static final String TABLE_BORDERLESS = "borderless";
-
- /**
- * Makes the column header and content font size smaller inside the table
- */
- public static final String TABLE_SMALL = "small";
-
- /**
- * Makes the column header and content font size bigger inside the table
- */
- public static final String TABLE_BIG = "big";
-
- /**
- * Adds a light alternate background color to even rows in the table.
- */
- public static final String TABLE_STRIPED = "striped";
-
- /***************************************************************************
- * ProgressIndicator styles
- **************************************************************************/
-
- /**
- * Reduces the height of the progress bar
- */
- public static final String PROGRESS_INDICATOR_SMALL = "small";
-
- /**
- * Increases the height of the progress bar. If the indicator is in
- * indeterminate mode, shows a bigger spinner than the regular indeterminate
- * indicator.
- */
- public static final String PROGRESS_INDICATOR_BIG = "big";
-
- /**
- * Displays an indeterminate progress indicator as a bar with animated
- * background stripes. This style can be used in combination with the
- * "small" and "big" styles.
- */
- public static final String PROGRESS_INDICATOR_INDETERMINATE_BAR = "bar";
-
- /***************************************************************************
- * Window styles
- **************************************************************************/
-
- /**
- * Sub-window style that makes the window background opaque (i.e. not
- * semi-transparent).
- */
- public static final String WINDOW_OPAQUE = "opaque";
-
- /***************************************************************************
- * Compound styles
- **************************************************************************/
-
- /**
- * Creates a context for a segment button control. Place buttons inside the
- * segment, and add "<code>first</code>" and "<code>last</code>" style names
- * for the first and last button in the segment. Then use the
- * {@link #BUTTON_DOWN} style to indicate button states.
- *
- * E.g.
- *
- * <pre>
- * HorizontalLayout ("segment")
- * + Button ("first down")
- * + Button ("down")
- * + Button
- * ...
- * + Button ("last")
- * </pre>
- *
- * You can also use most of the different button styles for the contained
- * buttons (e.g. {@link #BUTTON_BIG}, {@link #BUTTON_ICON_ONLY} etc.).
- */
- public static final String COMPOUND_HORIZONTAL_LAYOUT_SEGMENT = "segment";
-
- /**
- * Use this mixin-style in combination with the
- * {@link #COMPOUND_HORIZONTAL_LAYOUT_SEGMENT} style to make buttons with
- * the "down" style use the themes alternate color (e.g. blue instead of
- * gray).
- *
- * E.g.
- *
- * <pre>
- * HorizontalLayout ("segment segment-alternate")
- * + Button ("first down")
- * + Button ("down")
- * + Button
- * ...
- * + Button ("last")
- * </pre>
- */
- public static final String COMPOUND_HORIZONTAL_LAYOUT_SEGMENT_ALTERNATE = "segment-alternate";
-
- /**
- * Creates an iTunes-like menu from a CssLayout or a VerticalLayout. Place
- * plain Labels and NativeButtons inside the layout, and you're all set.
- *
- * E.g.
- *
- * <pre>
- * CssLayout ("sidebar-menu")
- * + Label
- * + NativeButton
- * + NativeButton
- * ...
- * + Label
- * + NativeButton
- * </pre>
- */
- public static final String COMPOUND_LAYOUT_SIDEBAR_MENU = "sidebar-menu";
-
- /**
- * Adds a toolbar-like background for the layout, and aligns Buttons and
- * Segments horizontally. Feel free to use different buttons styles inside
- * the toolbar, like {@link #BUTTON_ICON_ON_TOP} and
- * {@link #BUTTON_BORDERLESS}
- */
- public static final String COMPOUND_CSSLAYOUT_TOOLBAR = "toolbar";
-}
diff --git a/src/com/vaadin/ui/themes/LiferayTheme.java b/src/com/vaadin/ui/themes/LiferayTheme.java
deleted file mode 100644
index 9b48306ac2..0000000000
--- a/src/com/vaadin/ui/themes/LiferayTheme.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui.themes;
-
-public class LiferayTheme extends BaseTheme {
-
- public static final String THEME_NAME = "liferay";
-
- /***************************************************************************
- *
- * Panel styles
- *
- **************************************************************************/
-
- /**
- * Removes borders and background from the panel
- */
- public static final String PANEL_LIGHT = "light";
-
- /***************************************************************************
- *
- * SplitPanel styles
- *
- **************************************************************************/
-
- /**
- * Reduces the split handle to a minimal size (1 pixel)
- */
- public static final String SPLITPANEL_SMALL = "small";
-}
diff --git a/src/com/vaadin/ui/themes/Reindeer.java b/src/com/vaadin/ui/themes/Reindeer.java
deleted file mode 100644
index 7aaae8faa2..0000000000
--- a/src/com/vaadin/ui/themes/Reindeer.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui.themes;
-
-import com.vaadin.ui.CssLayout;
-import com.vaadin.ui.FormLayout;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.HorizontalSplitPanel;
-import com.vaadin.ui.VerticalLayout;
-import com.vaadin.ui.VerticalSplitPanel;
-
-public class Reindeer extends BaseTheme {
-
- public static final String THEME_NAME = "reindeer";
-
- /***************************************************************************
- *
- * Label styles
- *
- **************************************************************************/
-
- /**
- * Large font for main application headings
- */
- public static final String LABEL_H1 = "h1";
-
- /**
- * Large font for different sections in the application
- */
- public static final String LABEL_H2 = "h2";
-
- /**
- * Small and a little lighter font
- */
- public static final String LABEL_SMALL = "light";
-
- /**
- * @deprecated Use {@link #LABEL_SMALL} instead.
- */
- @Deprecated
- public static final String LABEL_LIGHT = "small";
-
- /***************************************************************************
- *
- * Button styles
- *
- **************************************************************************/
-
- /**
- * Default action style for buttons (the button that should get activated
- * when the user presses 'enter' in a form). Use sparingly, only one default
- * button per view should be visible.
- */
- public static final String BUTTON_DEFAULT = "primary";
-
- /**
- * @deprecated Use {@link #BUTTON_DEFAULT} instead
- */
- @Deprecated
- public static final String BUTTON_PRIMARY = BUTTON_DEFAULT;
-
- /**
- * Small sized button, use for context specific actions for example
- */
- public static final String BUTTON_SMALL = "small";
-
- /***************************************************************************
- *
- * TextField styles
- *
- **************************************************************************/
-
- /**
- * Small sized text field with small font
- */
- public static final String TEXTFIELD_SMALL = "small";
-
- /***************************************************************************
- *
- * Panel styles
- *
- **************************************************************************/
-
- /**
- * Removes borders and background color from the panel
- */
- public static final String PANEL_LIGHT = "light";
-
- /***************************************************************************
- *
- * SplitPanel styles
- *
- **************************************************************************/
-
- /**
- * Reduces the split handle to a minimal size (1 pixel)
- */
- public static final String SPLITPANEL_SMALL = "small";
-
- /***************************************************************************
- *
- * TabSheet styles
- *
- **************************************************************************/
-
- /**
- * Removes borders from the default tab sheet style.
- */
- public static final String TABSHEET_BORDERLESS = "borderless";
-
- /**
- * Removes borders and background color from the tab sheet, and shows the
- * tabs as a small bar.
- */
- public static final String TABSHEET_SMALL = "bar";
-
- /**
- * @deprecated Use {@link #TABSHEET_SMALL} instead.
- */
- @Deprecated
- public static final String TABSHEET_BAR = TABSHEET_SMALL;
-
- /**
- * Removes borders and background color from the tab sheet. The tabs are
- * presented with minimal lines indicating the selected tab.
- */
- public static final String TABSHEET_MINIMAL = "minimal";
-
- /**
- * Makes the tab close buttons visible only when the user is hovering over
- * the tab.
- */
- public static final String TABSHEET_HOVER_CLOSABLE = "hover-closable";
-
- /**
- * Makes the tab close buttons visible only when the tab is selected.
- */
- public static final String TABSHEET_SELECTED_CLOSABLE = "selected-closable";
-
- /***************************************************************************
- *
- * Table styles
- *
- **************************************************************************/
-
- /**
- * Removes borders from the table
- */
- public static final String TABLE_BORDERLESS = "borderless";
-
- /**
- * Makes the table headers dark and more prominent.
- */
- public static final String TABLE_STRONG = "strong";
-
- /***************************************************************************
- *
- * Layout styles
- *
- **************************************************************************/
-
- /**
- * Changes the background of a layout to white. Applies to
- * {@link VerticalLayout}, {@link HorizontalLayout}, {@link GridLayout},
- * {@link FormLayout}, {@link CssLayout}, {@link VerticalSplitPanel} and
- * {@link HorizontalSplitPanel}.
- * <p>
- * <em>Does not revert any contained components back to normal if some
- * parent layout has style {@link #LAYOUT_BLACK} applied.</em>
- */
- public static final String LAYOUT_WHITE = "white";
-
- /**
- * Changes the background of a layout to a shade of blue. Applies to
- * {@link VerticalLayout}, {@link HorizontalLayout}, {@link GridLayout},
- * {@link FormLayout}, {@link CssLayout}, {@link VerticalSplitPanel} and
- * {@link HorizontalSplitPanel}.
- * <p>
- * <em>Does not revert any contained components back to normal if some
- * parent layout has style {@link #LAYOUT_BLACK} applied.</em>
- */
- public static final String LAYOUT_BLUE = "blue";
-
- /**
- * <p>
- * Changes the background of a layout to almost black, and at the same time
- * transforms contained components to their black style correspondents when
- * available. At least texts, buttons, text fields, selects, date fields,
- * tables and a few other component styles should change.
- * </p>
- * <p>
- * Applies to {@link VerticalLayout}, {@link HorizontalLayout},
- * {@link GridLayout}, {@link FormLayout} and {@link CssLayout}.
- * </p>
- *
- */
- public static final String LAYOUT_BLACK = "black";
-
- /***************************************************************************
- *
- * Window styles
- *
- **************************************************************************/
-
- /**
- * Makes the whole window white and increases the font size of the title.
- */
- public static final String WINDOW_LIGHT = "light";
-
- /**
- * Makes the whole window black, and changes contained components in the
- * same way as {@link #LAYOUT_BLACK} does.
- */
- public static final String WINDOW_BLACK = "black";
-}
diff --git a/src/com/vaadin/ui/themes/Runo.java b/src/com/vaadin/ui/themes/Runo.java
deleted file mode 100644
index 28a19e8dcd..0000000000
--- a/src/com/vaadin/ui/themes/Runo.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui.themes;
-
-public class Runo extends BaseTheme {
-
- public static final String THEME_NAME = "runo";
-
- public static String themeName() {
- return THEME_NAME.toLowerCase();
- }
-
- /***************************************************************************
- *
- * Button styles
- *
- **************************************************************************/
-
- /**
- * Small sized button, use for context specific actions for example
- */
- public static final String BUTTON_SMALL = "small";
-
- /**
- * Big sized button, use to gather much attention for some particular action
- */
- public static final String BUTTON_BIG = "big";
-
- /**
- * Default action style for buttons (the button that should get activated
- * when the user presses 'enter' in a form). Use sparingly, only one default
- * button per view should be visible.
- */
- public static final String BUTTON_DEFAULT = "default";
-
- /***************************************************************************
- *
- * Panel styles
- *
- **************************************************************************/
-
- /**
- * Removes borders and background color from the panel
- */
- public static final String PANEL_LIGHT = "light";
-
- /***************************************************************************
- *
- * TabSheet styles
- *
- **************************************************************************/
-
- /**
- * Smaller tabs, no border and background for content area
- */
- public static final String TABSHEET_SMALL = "light";
-
- /***************************************************************************
- *
- * SplitPanel styles
- *
- **************************************************************************/
-
- /**
- * Reduces the width/height of the split handle. Useful when you don't want
- * the split handle to touch the sides of the containing layout.
- */
- public static final String SPLITPANEL_REDUCED = "rounded";
-
- /**
- * Reduces the visual size of the split handle to one pixel (the active drag
- * size is still larger).
- */
- public static final String SPLITPANEL_SMALL = "small";
-
- /***************************************************************************
- *
- * Label styles
- *
- **************************************************************************/
-
- /**
- * Largest title/header size. Use for main sections in your application.
- */
- public static final String LABEL_H1 = "h1";
-
- /**
- * Similar style as in panel captions. Useful for sub-sections within a
- * view.
- */
- public static final String LABEL_H2 = "h2";
-
- /**
- * Small font size. Useful for contextual help texts and similar less
- * frequently needed information. Use with modesty, since this style will be
- * more harder to read due to its smaller size and contrast.
- */
- public static final String LABEL_SMALL = "small";
-
- /***************************************************************************
- *
- * Layout styles
- *
- **************************************************************************/
-
- /**
- * An alternative background color for layouts. Use on top of white
- * background (e.g. inside Panels, TabSheets and sub-windows).
- */
- public static final String LAYOUT_DARKER = "darker";
-
- /**
- * Add a drop shadow around the layout and its contained components.
- * Produces a rectangular shadow, even if the contained component would have
- * a different shape.
- * <p>
- * Note: does not work in Internet Explorer 6
- */
- public static final String CSSLAYOUT_SHADOW = "box-shadow";
-
- /**
- * Adds necessary styles to the layout to make it look selectable (i.e.
- * clickable). Add a click listener for the layout, and toggle the
- * {@link #CSSLAYOUT_SELECTABLE_SELECTED} style for the same layout to make
- * it look selected or not.
- */
- public static final String CSSLAYOUT_SELECTABLE = "selectable";
- public static final String CSSLAYOUT_SELECTABLE_SELECTED = "selectable-selected";
-
- /***************************************************************************
- *
- * TextField styles
- *
- **************************************************************************/
-
- /**
- * Small sized text field with small font
- */
- public static final String TEXTFIELD_SMALL = "small";
-
- /***************************************************************************
- *
- * Table styles
- *
- **************************************************************************/
-
- /**
- * Smaller header and item fonts.
- */
- public static final String TABLE_SMALL = "small";
-
- /**
- * Removes the border and background color from the table. Removes
- * alternating row background colors as well.
- */
- public static final String TABLE_BORDERLESS = "borderless";
-
- /***************************************************************************
- *
- * Accordion styles
- *
- **************************************************************************/
-
- /**
- * A detached looking accordion, providing space around its captions and
- * content. Doesn't necessarily need a Panel or other container to wrap it
- * in order to make it look right.
- */
- public static final String ACCORDION_LIGHT = "light";
-
- /***************************************************************************
- *
- * Window styles
- *
- **************************************************************************/
-
- /**
- * Smaller header and a darker background color for the window. Useful for
- * smaller dialog-like windows.
- */
- public static final String WINDOW_DIALOG = "dialog";
-}
diff --git a/src/com/vaadin/util/SerializerHelper.java b/src/com/vaadin/util/SerializerHelper.java
deleted file mode 100644
index 5b7b388dd6..0000000000
--- a/src/com/vaadin/util/SerializerHelper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-package com.vaadin.util;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * Helper class for performing serialization. Most of the methods are here are
- * workarounds for problems in Google App Engine. Used internally by Vaadin and
- * should not be used by application developers. Subject to change at any time.
- *
- * @since 6.0
- */
-public class SerializerHelper {
-
- /**
- * Serializes the class reference so {@link #readClass(ObjectInputStream)}
- * can deserialize it. Supports null class references.
- *
- * @param out
- * The {@link ObjectOutputStream} to serialize to.
- * @param cls
- * A class or null.
- * @throws IOException
- * Rethrows any IOExceptions from the ObjectOutputStream
- */
- public static void writeClass(ObjectOutputStream out, Class<?> cls)
- throws IOException {
- if (cls == null) {
- out.writeObject(null);
- } else {
- out.writeObject(cls.getName());
- }
-
- }
-
- /**
- * Serializes the class references so
- * {@link #readClassArray(ObjectInputStream)} can deserialize it. Supports
- * null class arrays.
- *
- * @param out
- * The {@link ObjectOutputStream} to serialize to.
- * @param classes
- * An array containing class references or null.
- * @throws IOException
- * Rethrows any IOExceptions from the ObjectOutputStream
- */
- public static void writeClassArray(ObjectOutputStream out,
- Class<?>[] classes) throws IOException {
- if (classes == null) {
- out.writeObject(null);
- } else {
- String[] classNames = new String[classes.length];
- for (int i = 0; i < classes.length; i++) {
- classNames[i] = classes[i].getName();
- }
- out.writeObject(classNames);
- }
- }
-
- /**
- * Deserializes a class references serialized by
- * {@link #writeClassArray(ObjectOutputStream, Class[])}. Supports null
- * class arrays.
- *
- * @param in
- * {@link ObjectInputStream} to read from.
- * @return Class array with the class references or null.
- * @throws ClassNotFoundException
- * If one of the classes could not be resolved.
- * @throws IOException
- * Rethrows IOExceptions from the ObjectInputStream
- */
- public static Class<?>[] readClassArray(ObjectInputStream in)
- throws ClassNotFoundException, IOException {
- String[] classNames = (String[]) in.readObject();
- if (classNames == null) {
- return null;
- }
- Class<?>[] classes = new Class<?>[classNames.length];
- for (int i = 0; i < classNames.length; i++) {
- classes[i] = resolveClass(classNames[i]);
- }
-
- return classes;
- }
-
- /**
- * List of primitive classes. Google App Engine has problems
- * serializing/deserializing these (#3064).
- */
- private static Class<?>[] primitiveClasses = new Class<?>[] { byte.class,
- short.class, int.class, long.class, float.class, double.class,
- boolean.class, char.class };
-
- /**
- * Resolves the class given by {@code className}.
- *
- * @param className
- * The fully qualified class name.
- * @return A {@code Class} reference.
- * @throws ClassNotFoundException
- * If the class could not be resolved.
- */
- public static Class<?> resolveClass(String className)
- throws ClassNotFoundException {
- for (Class<?> c : primitiveClasses) {
- if (className.equals(c.getName())) {
- return c;
- }
- }
-
- return Class.forName(className);
- }
-
- /**
- * Deserializes a class reference serialized by
- * {@link #writeClass(ObjectOutputStream, Class)}. Supports null class
- * references.
- *
- * @param in
- * {@code ObjectInputStream} to read from.
- * @return Class reference to the resolved class
- * @throws ClassNotFoundException
- * If the class could not be resolved.
- * @throws IOException
- * Rethrows IOExceptions from the ObjectInputStream
- */
- public static Class<?> readClass(ObjectInputStream in) throws IOException,
- ClassNotFoundException {
- String className = (String) in.readObject();
- if (className == null) {
- return null;
- } else {
- return resolveClass(className);
-
- }
-
- }
-
-}
diff --git a/src/org/jsoup/Connection.java b/src/org/jsoup/Connection.java
deleted file mode 100644
index 564eeb89b7..0000000000
--- a/src/org/jsoup/Connection.java
+++ /dev/null
@@ -1,481 +0,0 @@
-package org.jsoup;
-
-import org.jsoup.nodes.Document;
-import org.jsoup.parser.Parser;
-
-import java.net.URL;
-import java.util.Map;
-import java.util.Collection;
-import java.io.IOException;
-
-/**
- * A Connection provides a convenient interface to fetch content from the web, and parse them into Documents.
- * <p>
- * To get a new Connection, use {@link org.jsoup.Jsoup#connect(String)}. Connections contain {@link Connection.Request}
- * and {@link Connection.Response} objects. The request objects are reusable as prototype requests.
- * <p>
- * Request configuration can be made using either the shortcut methods in Connection (e.g. {@link #userAgent(String)}),
- * or by methods in the Connection.Request object directly. All request configuration must be made before the request
- * is executed.
- * <p>
- * The Connection interface is <b>currently in beta</b> and subject to change. Comments, suggestions, and bug reports are welcome.
- */
-public interface Connection {
-
- /**
- * GET and POST http methods.
- */
- public enum Method {
- GET, POST
- }
-
- /**
- * Set the request URL to fetch. The protocol must be HTTP or HTTPS.
- * @param url URL to connect to
- * @return this Connection, for chaining
- */
- public Connection url(URL url);
-
- /**
- * Set the request URL to fetch. The protocol must be HTTP or HTTPS.
- * @param url URL to connect to
- * @return this Connection, for chaining
- */
- public Connection url(String url);
-
- /**
- * Set the request user-agent header.
- * @param userAgent user-agent to use
- * @return this Connection, for chaining
- */
- public Connection userAgent(String userAgent);
-
- /**
- * Set the request timeouts (connect and read). If a timeout occurs, an IOException will be thrown. The default
- * timeout is 3 seconds (3000 millis). A timeout of zero is treated as an infinite timeout.
- * @param millis number of milliseconds (thousandths of a second) before timing out connects or reads.
- * @return this Connection, for chaining
- */
- public Connection timeout(int millis);
-
- /**
- * Set the request referrer (aka "referer") header.
- * @param referrer referrer to use
- * @return this Connection, for chaining
- */
- public Connection referrer(String referrer);
-
- /**
- * Configures the connection to (not) follow server redirects. By default this is <b>true</b>.
- * @param followRedirects true if server redirects should be followed.
- * @return this Connection, for chaining
- */
- public Connection followRedirects(boolean followRedirects);
-
- /**
- * Set the request method to use, GET or POST. Default is GET.
- * @param method HTTP request method
- * @return this Connection, for chaining
- */
- public Connection method(Method method);
-
- /**
- * Configures the connection to not throw exceptions when a HTTP error occurs. (4xx - 5xx, e.g. 404 or 500). By
- * default this is <b>false</b>; an IOException is thrown if an error is encountered. If set to <b>true</b>, the
- * response is populated with the error body, and the status message will reflect the error.
- * @param ignoreHttpErrors - false (default) if HTTP errors should be ignored.
- * @return this Connection, for chaining
- */
- public Connection ignoreHttpErrors(boolean ignoreHttpErrors);
-
- /**
- * Ignore the document's Content-Type when parsing the response. By default this is <b>false</b>, an unrecognised
- * content-type will cause an IOException to be thrown. (This is to prevent producing garbage by attempting to parse
- * a JPEG binary image, for example.) Set to true to force a parse attempt regardless of content type.
- * @param ignoreContentType set to true if you would like the content type ignored on parsing the response into a
- * Document.
- * @return this Connection, for chaining
- */
- public Connection ignoreContentType(boolean ignoreContentType);
-
- /**
- * Add a request data parameter. Request parameters are sent in the request query string for GETs, and in the request
- * body for POSTs. A request may have multiple values of the same name.
- * @param key data key
- * @param value data value
- * @return this Connection, for chaining
- */
- public Connection data(String key, String value);
-
- /**
- * Adds all of the supplied data to the request data parameters
- * @param data map of data parameters
- * @return this Connection, for chaining
- */
- public Connection data(Map<String, String> data);
-
- /**
- * Add a number of request data parameters. Multiple parameters may be set at once, e.g.:
- * <code>.data("name", "jsoup", "language", "Java", "language", "English");</code> creates a query string like:
- * <code>?name=jsoup&language=Java&language=English</code>
- * @param keyvals a set of key value pairs.
- * @return this Connection, for chaining
- */
- public Connection data(String... keyvals);
-
- /**
- * Set a request header.
- * @param name header name
- * @param value header value
- * @return this Connection, for chaining
- * @see org.jsoup.Connection.Request#headers()
- */
- public Connection header(String name, String value);
-
- /**
- * Set a cookie to be sent in the request.
- * @param name name of cookie
- * @param value value of cookie
- * @return this Connection, for chaining
- */
- public Connection cookie(String name, String value);
-
- /**
- * Adds each of the supplied cookies to the request.
- * @param cookies map of cookie name -> value pairs
- * @return this Connection, for chaining
- */
- public Connection cookies(Map<String, String> cookies);
-
- /**
- * Provide an alternate parser to use when parsing the response to a Document.
- * @param parser alternate parser
- * @return this Connection, for chaining
- */
- public Connection parser(Parser parser);
-
- /**
- * Execute the request as a GET, and parse the result.
- * @return parsed Document
- * @throws IOException on error
- */
- public Document get() throws IOException;
-
- /**
- * Execute the request as a POST, and parse the result.
- * @return parsed Document
- * @throws IOException on error
- */
- public Document post() throws IOException;
-
- /**
- * Execute the request.
- * @return a response object
- * @throws IOException on error
- */
- public Response execute() throws IOException;
-
- /**
- * Get the request object associated with this connection
- * @return request
- */
- public Request request();
-
- /**
- * Set the connection's request
- * @param request new request object
- * @return this Connection, for chaining
- */
- public Connection request(Request request);
-
- /**
- * Get the response, once the request has been executed
- * @return response
- */
- public Response response();
-
- /**
- * Set the connection's response
- * @param response new response
- * @return this Connection, for chaining
- */
- public Connection response(Response response);
-
-
- /**
- * Common methods for Requests and Responses
- * @param <T> Type of Base, either Request or Response
- */
- interface Base<T extends Base> {
-
- /**
- * Get the URL
- * @return URL
- */
- public URL url();
-
- /**
- * Set the URL
- * @param url new URL
- * @return this, for chaining
- */
- public T url(URL url);
-
- /**
- * Get the request method
- * @return method
- */
- public Method method();
-
- /**
- * Set the request method
- * @param method new method
- * @return this, for chaining
- */
- public T method(Method method);
-
- /**
- * Get the value of a header. This is a simplified header model, where a header may only have one value.
- * <p>
- * Header names are case insensitive.
- * @param name name of header (case insensitive)
- * @return value of header, or null if not set.
- * @see #hasHeader(String)
- * @see #cookie(String)
- */
- public String header(String name);
-
- /**
- * Set a header. This method will overwrite any existing header with the same case insensitive name.
- * @param name Name of header
- * @param value Value of header
- * @return this, for chaining
- */
- public T header(String name, String value);
-
- /**
- * Check if a header is present
- * @param name name of header (case insensitive)
- * @return if the header is present in this request/response
- */
- public boolean hasHeader(String name);
-
- /**
- * Remove a header by name
- * @param name name of header to remove (case insensitive)
- * @return this, for chaining
- */
- public T removeHeader(String name);
-
- /**
- * Retrieve all of the request/response headers as a map
- * @return headers
- */
- public Map<String, String> headers();
-
- /**
- * Get a cookie value by name from this request/response.
- * <p>
- * Response objects have a simplified cookie model. Each cookie set in the response is added to the response
- * object's cookie key=value map. The cookie's path, domain, and expiry date are ignored.
- * @param name name of cookie to retrieve.
- * @return value of cookie, or null if not set
- */
- public String cookie(String name);
-
- /**
- * Set a cookie in this request/response.
- * @param name name of cookie
- * @param value value of cookie
- * @return this, for chaining
- */
- public T cookie(String name, String value);
-
- /**
- * Check if a cookie is present
- * @param name name of cookie
- * @return if the cookie is present in this request/response
- */
- public boolean hasCookie(String name);
-
- /**
- * Remove a cookie by name
- * @param name name of cookie to remove
- * @return this, for chaining
- */
- public T removeCookie(String name);
-
- /**
- * Retrieve all of the request/response cookies as a map
- * @return cookies
- */
- public Map<String, String> cookies();
-
- }
-
- /**
- * Represents a HTTP request.
- */
- public interface Request extends Base<Request> {
- /**
- * Get the request timeout, in milliseconds.
- * @return the timeout in milliseconds.
- */
- public int timeout();
-
- /**
- * Update the request timeout.
- * @param millis timeout, in milliseconds
- * @return this Request, for chaining
- */
- public Request timeout(int millis);
-
- /**
- * Get the current followRedirects configuration.
- * @return true if followRedirects is enabled.
- */
- public boolean followRedirects();
-
- /**
- * Configures the request to (not) follow server redirects. By default this is <b>true</b>.
- *
- * @param followRedirects true if server redirects should be followed.
- * @return this Request, for chaining
- */
- public Request followRedirects(boolean followRedirects);
-
- /**
- * Get the current ignoreHttpErrors configuration.
- * @return true if errors will be ignored; false (default) if HTTP errors will cause an IOException to be thrown.
- */
- public boolean ignoreHttpErrors();
-
- /**
- * Configures the request to ignore HTTP errors in the response.
- * @param ignoreHttpErrors set to true to ignore HTTP errors.
- * @return this Request, for chaining
- */
- public Request ignoreHttpErrors(boolean ignoreHttpErrors);
-
- /**
- * Get the current ignoreContentType configuration.
- * @return true if invalid content-types will be ignored; false (default) if they will cause an IOException to be thrown.
- */
- public boolean ignoreContentType();
-
- /**
- * Configures the request to ignore the Content-Type of the response.
- * @param ignoreContentType set to true to ignore the content type.
- * @return this Request, for chaining
- */
- public Request ignoreContentType(boolean ignoreContentType);
-
- /**
- * Add a data parameter to the request
- * @param keyval data to add.
- * @return this Request, for chaining
- */
- public Request data(KeyVal keyval);
-
- /**
- * Get all of the request's data parameters
- * @return collection of keyvals
- */
- public Collection<KeyVal> data();
-
- /**
- * Specify the parser to use when parsing the document.
- * @param parser parser to use.
- * @return this Request, for chaining
- */
- public Request parser(Parser parser);
-
- /**
- * Get the current parser to use when parsing the document.
- * @return current Parser
- */
- public Parser parser();
- }
-
- /**
- * Represents a HTTP response.
- */
- public interface Response extends Base<Response> {
-
- /**
- * Get the status code of the response.
- * @return status code
- */
- public int statusCode();
-
- /**
- * Get the status message of the response.
- * @return status message
- */
- public String statusMessage();
-
- /**
- * Get the character set name of the response.
- * @return character set name
- */
- public String charset();
-
- /**
- * Get the response content type (e.g. "text/html");
- * @return the response content type
- */
- public String contentType();
-
- /**
- * Parse the body of the response as a Document.
- * @return a parsed Document
- * @throws IOException on error
- */
- public Document parse() throws IOException;
-
- /**
- * Get the body of the response as a plain string.
- * @return body
- */
- public String body();
-
- /**
- * Get the body of the response as an array of bytes.
- * @return body bytes
- */
- public byte[] bodyAsBytes();
- }
-
- /**
- * A Key Value tuple.
- */
- public interface KeyVal {
-
- /**
- * Update the key of a keyval
- * @param key new key
- * @return this KeyVal, for chaining
- */
- public KeyVal key(String key);
-
- /**
- * Get the key of a keyval
- * @return the key
- */
- public String key();
-
- /**
- * Update the value of a keyval
- * @param value the new value
- * @return this KeyVal, for chaining
- */
- public KeyVal value(String value);
-
- /**
- * Get the value of a keyval
- * @return the value
- */
- public String value();
- }
-}
-
diff --git a/src/org/jsoup/Jsoup.java b/src/org/jsoup/Jsoup.java
deleted file mode 100644
index 8c6afcee36..0000000000
--- a/src/org/jsoup/Jsoup.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package org.jsoup;
-
-import org.jsoup.nodes.Document;
-import org.jsoup.parser.Parser;
-import org.jsoup.safety.Cleaner;
-import org.jsoup.safety.Whitelist;
-import org.jsoup.helper.DataUtil;
-import org.jsoup.helper.HttpConnection;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-/**
- The core public access point to the jsoup functionality.
-
- @author Jonathan Hedley */
-public class Jsoup {
- private Jsoup() {}
-
- /**
- Parse HTML into a Document. The parser will make a sensible, balanced document tree out of any HTML.
-
- @param html HTML to parse
- @param baseUri The URL where the HTML was retrieved from. Used to resolve relative URLs to absolute URLs, that occur
- before the HTML declares a {@code <base href>} tag.
- @return sane HTML
- */
- public static Document parse(String html, String baseUri) {
- return Parser.parse(html, baseUri);
- }
-
- /**
- Parse HTML into a Document, using the provided Parser. You can provide an alternate parser, such as a simple XML
- (non-HTML) parser.
-
- @param html HTML to parse
- @param baseUri The URL where the HTML was retrieved from. Used to resolve relative URLs to absolute URLs, that occur
- before the HTML declares a {@code <base href>} tag.
- @param parser alternate {@link Parser#xmlParser() parser} to use.
- @return sane HTML
- */
- public static Document parse(String html, String baseUri, Parser parser) {
- return parser.parseInput(html, baseUri);
- }
-
- /**
- Parse HTML into a Document. As no base URI is specified, absolute URL detection relies on the HTML including a
- {@code <base href>} tag.
-
- @param html HTML to parse
- @return sane HTML
-
- @see #parse(String, String)
- */
- public static Document parse(String html) {
- return Parser.parse(html, "");
- }
-
- /**
- * Creates a new {@link Connection} to a URL. Use to fetch and parse a HTML page.
- * <p>
- * Use examples:
- * <ul>
- * <li><code>Document doc = Jsoup.connect("http://example.com").userAgent("Mozilla").data("name", "jsoup").get();</code></li>
- * <li><code>Document doc = Jsoup.connect("http://example.com").cookie("auth", "token").post();
- * </ul>
- * @param url URL to connect to. The protocol must be {@code http} or {@code https}.
- * @return the connection. You can add data, cookies, and headers; set the user-agent, referrer, method; and then execute.
- */
- public static Connection connect(String url) {
- return HttpConnection.connect(url);
- }
-
- /**
- Parse the contents of a file as HTML.
-
- @param in file to load HTML from
- @param charsetName (optional) character set of file contents. Set to {@code null} to determine from {@code http-equiv} meta tag, if
- present, or fall back to {@code UTF-8} (which is often safe to do).
- @param baseUri The URL where the HTML was retrieved from, to resolve relative links against.
- @return sane HTML
-
- @throws IOException if the file could not be found, or read, or if the charsetName is invalid.
- */
- public static Document parse(File in, String charsetName, String baseUri) throws IOException {
- return DataUtil.load(in, charsetName, baseUri);
- }
-
- /**
- Parse the contents of a file as HTML. The location of the file is used as the base URI to qualify relative URLs.
-
- @param in file to load HTML from
- @param charsetName (optional) character set of file contents. Set to {@code null} to determine from {@code http-equiv} meta tag, if
- present, or fall back to {@code UTF-8} (which is often safe to do).
- @return sane HTML
-
- @throws IOException if the file could not be found, or read, or if the charsetName is invalid.
- @see #parse(File, String, String)
- */
- public static Document parse(File in, String charsetName) throws IOException {
- return DataUtil.load(in, charsetName, in.getAbsolutePath());
- }
-
- /**
- Read an input stream, and parse it to a Document.
-
- @param in input stream to read. Make sure to close it after parsing.
- @param charsetName (optional) character set of file contents. Set to {@code null} to determine from {@code http-equiv} meta tag, if
- present, or fall back to {@code UTF-8} (which is often safe to do).
- @param baseUri The URL where the HTML was retrieved from, to resolve relative links against.
- @return sane HTML
-
- @throws IOException if the file could not be found, or read, or if the charsetName is invalid.
- */
- public static Document parse(InputStream in, String charsetName, String baseUri) throws IOException {
- return DataUtil.load(in, charsetName, baseUri);
- }
-
- /**
- Read an input stream, and parse it to a Document. You can provide an alternate parser, such as a simple XML
- (non-HTML) parser.
-
- @param in input stream to read. Make sure to close it after parsing.
- @param charsetName (optional) character set of file contents. Set to {@code null} to determine from {@code http-equiv} meta tag, if
- present, or fall back to {@code UTF-8} (which is often safe to do).
- @param baseUri The URL where the HTML was retrieved from, to resolve relative links against.
- @param parser alternate {@link Parser#xmlParser() parser} to use.
- @return sane HTML
-
- @throws IOException if the file could not be found, or read, or if the charsetName is invalid.
- */
- public static Document parse(InputStream in, String charsetName, String baseUri, Parser parser) throws IOException {
- return DataUtil.load(in, charsetName, baseUri, parser);
- }
-
- /**
- Parse a fragment of HTML, with the assumption that it forms the {@code body} of the HTML.
-
- @param bodyHtml body HTML fragment
- @param baseUri URL to resolve relative URLs against.
- @return sane HTML document
-
- @see Document#body()
- */
- public static Document parseBodyFragment(String bodyHtml, String baseUri) {
- return Parser.parseBodyFragment(bodyHtml, baseUri);
- }
-
- /**
- Parse a fragment of HTML, with the assumption that it forms the {@code body} of the HTML.
-
- @param bodyHtml body HTML fragment
- @return sane HTML document
-
- @see Document#body()
- */
- public static Document parseBodyFragment(String bodyHtml) {
- return Parser.parseBodyFragment(bodyHtml, "");
- }
-
- /**
- Fetch a URL, and parse it as HTML. Provided for compatibility; in most cases use {@link #connect(String)} instead.
- <p>
- The encoding character set is determined by the content-type header or http-equiv meta tag, or falls back to {@code UTF-8}.
-
- @param url URL to fetch (with a GET). The protocol must be {@code http} or {@code https}.
- @param timeoutMillis Connection and read timeout, in milliseconds. If exceeded, IOException is thrown.
- @return The parsed HTML.
-
- @throws IOException If the final server response != 200 OK (redirects are followed), or if there's an error reading
- the response stream.
-
- @see #connect(String)
- */
- public static Document parse(URL url, int timeoutMillis) throws IOException {
- Connection con = HttpConnection.connect(url);
- con.timeout(timeoutMillis);
- return con.get();
- }
-
- /**
- Get safe HTML from untrusted input HTML, by parsing input HTML and filtering it through a white-list of permitted
- tags and attributes.
-
- @param bodyHtml input untrusted HTML
- @param baseUri URL to resolve relative URLs against
- @param whitelist white-list of permitted HTML elements
- @return safe HTML
-
- @see Cleaner#clean(Document)
- */
- public static String clean(String bodyHtml, String baseUri, Whitelist whitelist) {
- Document dirty = parseBodyFragment(bodyHtml, baseUri);
- Cleaner cleaner = new Cleaner(whitelist);
- Document clean = cleaner.clean(dirty);
- return clean.body().html();
- }
-
- /**
- Get safe HTML from untrusted input HTML, by parsing input HTML and filtering it through a white-list of permitted
- tags and attributes.
-
- @param bodyHtml input untrusted HTML
- @param whitelist white-list of permitted HTML elements
- @return safe HTML
-
- @see Cleaner#clean(Document)
- */
- public static String clean(String bodyHtml, Whitelist whitelist) {
- return clean(bodyHtml, "", whitelist);
- }
-
- /**
- Test if the input HTML has only tags and attributes allowed by the Whitelist. Useful for form validation. The input HTML should
- still be run through the cleaner to set up enforced attributes, and to tidy the output.
- @param bodyHtml HTML to test
- @param whitelist whitelist to test against
- @return true if no tags or attributes were removed; false otherwise
- @see #clean(String, org.jsoup.safety.Whitelist)
- */
- public static boolean isValid(String bodyHtml, Whitelist whitelist) {
- Document dirty = parseBodyFragment(bodyHtml, "");
- Cleaner cleaner = new Cleaner(whitelist);
- return cleaner.isValid(dirty);
- }
-
-}
diff --git a/src/org/jsoup/examples/HtmlToPlainText.java b/src/org/jsoup/examples/HtmlToPlainText.java
deleted file mode 100644
index 8f563e9608..0000000000
--- a/src/org/jsoup/examples/HtmlToPlainText.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.jsoup.examples;
-
-import org.jsoup.Jsoup;
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-import org.jsoup.nodes.TextNode;
-import org.jsoup.select.NodeTraversor;
-import org.jsoup.select.NodeVisitor;
-
-import java.io.IOException;
-
-/**
- * HTML to plain-text. This example program demonstrates the use of jsoup to convert HTML input to lightly-formatted
- * plain-text. That is divergent from the general goal of jsoup's .text() methods, which is to get clean data from a
- * scrape.
- * <p/>
- * Note that this is a fairly simplistic formatter -- for real world use you'll want to embrace and extend.
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- */
-public class HtmlToPlainText {
- public static void main(String... args) throws IOException {
- Validate.isTrue(args.length == 1, "usage: supply url to fetch");
- String url = args[0];
-
- // fetch the specified URL and parse to a HTML DOM
- Document doc = Jsoup.connect(url).get();
-
- HtmlToPlainText formatter = new HtmlToPlainText();
- String plainText = formatter.getPlainText(doc);
- System.out.println(plainText);
- }
-
- /**
- * Format an Element to plain-text
- * @param element the root element to format
- * @return formatted text
- */
- public String getPlainText(Element element) {
- FormattingVisitor formatter = new FormattingVisitor();
- NodeTraversor traversor = new NodeTraversor(formatter);
- traversor.traverse(element); // walk the DOM, and call .head() and .tail() for each node
-
- return formatter.toString();
- }
-
- // the formatting rules, implemented in a breadth-first DOM traverse
- private class FormattingVisitor implements NodeVisitor {
- private static final int maxWidth = 80;
- private int width = 0;
- private StringBuilder accum = new StringBuilder(); // holds the accumulated text
-
- // hit when the node is first seen
- public void head(Node node, int depth) {
- String name = node.nodeName();
- if (node instanceof TextNode)
- append(((TextNode) node).text()); // TextNodes carry all user-readable text in the DOM.
- else if (name.equals("li"))
- append("\n * ");
- }
-
- // hit when all of the node's children (if any) have been visited
- public void tail(Node node, int depth) {
- String name = node.nodeName();
- if (name.equals("br"))
- append("\n");
- else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5"))
- append("\n\n");
- else if (name.equals("a"))
- append(String.format(" <%s>", node.absUrl("href")));
- }
-
- // appends text to the string builder with a simple word wrap method
- private void append(String text) {
- if (text.startsWith("\n"))
- width = 0; // reset counter if starts with a newline. only from formats above, not in natural text
- if (text.equals(" ") &&
- (accum.length() == 0 || StringUtil.in(accum.substring(accum.length() - 1), " ", "\n")))
- return; // don't accumulate long runs of empty spaces
-
- if (text.length() + width > maxWidth) { // won't fit, needs to wrap
- String words[] = text.split("\\s+");
- for (int i = 0; i < words.length; i++) {
- String word = words[i];
- boolean last = i == words.length - 1;
- if (!last) // insert a space if not the last word
- word = word + " ";
- if (word.length() + width > maxWidth) { // wrap and reset counter
- accum.append("\n").append(word);
- width = word.length();
- } else {
- accum.append(word);
- width += word.length();
- }
- }
- } else { // fits as is, without need to wrap text
- accum.append(text);
- width += text.length();
- }
- }
-
- public String toString() {
- return accum.toString();
- }
- }
-}
diff --git a/src/org/jsoup/examples/ListLinks.java b/src/org/jsoup/examples/ListLinks.java
deleted file mode 100644
index 64b29ba107..0000000000
--- a/src/org/jsoup/examples/ListLinks.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.jsoup.examples;
-
-import org.jsoup.Jsoup;
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-
-import java.io.IOException;
-
-/**
- * Example program to list links from a URL.
- */
-public class ListLinks {
- public static void main(String[] args) throws IOException {
- Validate.isTrue(args.length == 1, "usage: supply url to fetch");
- String url = args[0];
- print("Fetching %s...", url);
-
- Document doc = Jsoup.connect(url).get();
- Elements links = doc.select("a[href]");
- Elements media = doc.select("[src]");
- Elements imports = doc.select("link[href]");
-
- print("\nMedia: (%d)", media.size());
- for (Element src : media) {
- if (src.tagName().equals("img"))
- print(" * %s: <%s> %sx%s (%s)",
- src.tagName(), src.attr("abs:src"), src.attr("width"), src.attr("height"),
- trim(src.attr("alt"), 20));
- else
- print(" * %s: <%s>", src.tagName(), src.attr("abs:src"));
- }
-
- print("\nImports: (%d)", imports.size());
- for (Element link : imports) {
- print(" * %s <%s> (%s)", link.tagName(),link.attr("abs:href"), link.attr("rel"));
- }
-
- print("\nLinks: (%d)", links.size());
- for (Element link : links) {
- print(" * a: <%s> (%s)", link.attr("abs:href"), trim(link.text(), 35));
- }
- }
-
- private static void print(String msg, Object... args) {
- System.out.println(String.format(msg, args));
- }
-
- private static String trim(String s, int width) {
- if (s.length() > width)
- return s.substring(0, width-1) + ".";
- else
- return s;
- }
-}
diff --git a/src/org/jsoup/examples/package-info.java b/src/org/jsoup/examples/package-info.java
deleted file mode 100644
index c312f430d4..0000000000
--- a/src/org/jsoup/examples/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- Contains example programs and use of jsoup. See the <a href="http://jsoup.org/cookbook/">jsoup cookbook</a>.
- */
-package org.jsoup.examples; \ No newline at end of file
diff --git a/src/org/jsoup/helper/DataUtil.java b/src/org/jsoup/helper/DataUtil.java
deleted file mode 100644
index 9adfe42153..0000000000
--- a/src/org/jsoup/helper/DataUtil.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package org.jsoup.helper;
-
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.parser.Parser;
-
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Internal static utilities for handling data.
- *
- */
-public class DataUtil {
- private static final Pattern charsetPattern = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
- static final String defaultCharset = "UTF-8"; // used if not found in header or meta charset
- private static final int bufferSize = 0x20000; // ~130K.
-
- private DataUtil() {}
-
- /**
- * Loads a file to a Document.
- * @param in file to load
- * @param charsetName character set of input
- * @param baseUri base URI of document, to resolve relative links against
- * @return Document
- * @throws IOException on IO error
- */
- public static Document load(File in, String charsetName, String baseUri) throws IOException {
- FileInputStream inStream = null;
- try {
- inStream = new FileInputStream(in);
- ByteBuffer byteData = readToByteBuffer(inStream);
- return parseByteData(byteData, charsetName, baseUri, Parser.htmlParser());
- } finally {
- if (inStream != null)
- inStream.close();
- }
- }
-
- /**
- * Parses a Document from an input steam.
- * @param in input stream to parse. You will need to close it.
- * @param charsetName character set of input
- * @param baseUri base URI of document, to resolve relative links against
- * @return Document
- * @throws IOException on IO error
- */
- public static Document load(InputStream in, String charsetName, String baseUri) throws IOException {
- ByteBuffer byteData = readToByteBuffer(in);
- return parseByteData(byteData, charsetName, baseUri, Parser.htmlParser());
- }
-
- /**
- * Parses a Document from an input steam, using the provided Parser.
- * @param in input stream to parse. You will need to close it.
- * @param charsetName character set of input
- * @param baseUri base URI of document, to resolve relative links against
- * @param parser alternate {@link Parser#xmlParser() parser} to use.
- * @return Document
- * @throws IOException on IO error
- */
- public static Document load(InputStream in, String charsetName, String baseUri, Parser parser) throws IOException {
- ByteBuffer byteData = readToByteBuffer(in);
- return parseByteData(byteData, charsetName, baseUri, parser);
- }
-
- // reads bytes first into a buffer, then decodes with the appropriate charset. done this way to support
- // switching the chartset midstream when a meta http-equiv tag defines the charset.
- static Document parseByteData(ByteBuffer byteData, String charsetName, String baseUri, Parser parser) {
- String docData;
- Document doc = null;
- if (charsetName == null) { // determine from meta. safe parse as UTF-8
- // look for <meta http-equiv="Content-Type" content="text/html;charset=gb2312"> or HTML5 <meta charset="gb2312">
- docData = Charset.forName(defaultCharset).decode(byteData).toString();
- doc = parser.parseInput(docData, baseUri);
- Element meta = doc.select("meta[http-equiv=content-type], meta[charset]").first();
- if (meta != null) { // if not found, will keep utf-8 as best attempt
- String foundCharset = meta.hasAttr("http-equiv") ? getCharsetFromContentType(meta.attr("content")) : meta.attr("charset");
- if (foundCharset != null && foundCharset.length() != 0 && !foundCharset.equals(defaultCharset)) { // need to re-decode
- charsetName = foundCharset;
- byteData.rewind();
- docData = Charset.forName(foundCharset).decode(byteData).toString();
- doc = null;
- }
- }
- } else { // specified by content type header (or by user on file load)
- Validate.notEmpty(charsetName, "Must set charset arg to character set of file to parse. Set to null to attempt to detect from HTML");
- docData = Charset.forName(charsetName).decode(byteData).toString();
- }
- if (doc == null) {
- // there are times where there is a spurious byte-order-mark at the start of the text. Shouldn't be present
- // in utf-8. If after decoding, there is a BOM, strip it; otherwise will cause the parser to go straight
- // into head mode
- if (docData.charAt(0) == 65279)
- docData = docData.substring(1);
-
- doc = parser.parseInput(docData, baseUri);
- doc.outputSettings().charset(charsetName);
- }
- return doc;
- }
-
- static ByteBuffer readToByteBuffer(InputStream inStream) throws IOException {
- byte[] buffer = new byte[bufferSize];
- ByteArrayOutputStream outStream = new ByteArrayOutputStream(bufferSize);
- int read;
- while(true) {
- read = inStream.read(buffer);
- if (read == -1) break;
- outStream.write(buffer, 0, read);
- }
- ByteBuffer byteData = ByteBuffer.wrap(outStream.toByteArray());
- return byteData;
- }
-
- /**
- * Parse out a charset from a content type header.
- * @param contentType e.g. "text/html; charset=EUC-JP"
- * @return "EUC-JP", or null if not found. Charset is trimmed and uppercased.
- */
- static String getCharsetFromContentType(String contentType) {
- if (contentType == null) return null;
- Matcher m = charsetPattern.matcher(contentType);
- if (m.find()) {
- return m.group(1).trim().toUpperCase();
- }
- return null;
- }
-
-
-}
diff --git a/src/org/jsoup/helper/DescendableLinkedList.java b/src/org/jsoup/helper/DescendableLinkedList.java
deleted file mode 100644
index 28ca1971eb..0000000000
--- a/src/org/jsoup/helper/DescendableLinkedList.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.jsoup.helper;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-/**
- * Provides a descending iterator and other 1.6 methods to allow support on the 1.5 JRE.
- */
-public class DescendableLinkedList<E> extends LinkedList<E> {
-
- /**
- * Create a new DescendableLinkedList.
- */
- public DescendableLinkedList() {
- super();
- }
-
- /**
- * Add a new element to the start of the list.
- * @param e element to add
- */
- public void push(E e) {
- addFirst(e);
- }
-
- /**
- * Look at the last element, if there is one.
- * @return the last element, or null
- */
- public E peekLast() {
- return size() == 0 ? null : getLast();
- }
-
- /**
- * Remove and return the last element, if there is one
- * @return the last element, or null
- */
- public E pollLast() {
- return size() == 0 ? null : removeLast();
- }
-
- /**
- * Get an iterator that starts and the end of the list and works towards the start.
- * @return an iterator that starts and the end of the list and works towards the start.
- */
- public Iterator<E> descendingIterator() {
- return new DescendingIterator<E>(size());
- }
-
- private class DescendingIterator<E> implements Iterator<E> {
- private final ListIterator<E> iter;
-
- @SuppressWarnings("unchecked")
- private DescendingIterator(int index) {
- iter = (ListIterator<E>) listIterator(index);
- }
-
- /**
- * Check if there is another element on the list.
- * @return if another element
- */
- public boolean hasNext() {
- return iter.hasPrevious();
- }
-
- /**
- * Get the next element.
- * @return the next element.
- */
- public E next() {
- return iter.previous();
- }
-
- /**
- * Remove the current element.
- */
- public void remove() {
- iter.remove();
- }
- }
-}
diff --git a/src/org/jsoup/helper/HttpConnection.java b/src/org/jsoup/helper/HttpConnection.java
deleted file mode 100644
index 06200a2547..0000000000
--- a/src/org/jsoup/helper/HttpConnection.java
+++ /dev/null
@@ -1,658 +0,0 @@
-package org.jsoup.helper;
-
-import org.jsoup.Connection;
-import org.jsoup.nodes.Document;
-import org.jsoup.parser.Parser;
-import org.jsoup.parser.TokenQueue;
-
-import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.*;
-import java.util.zip.GZIPInputStream;
-
-/**
- * Implementation of {@link Connection}.
- * @see org.jsoup.Jsoup#connect(String)
- */
-public class HttpConnection implements Connection {
- public static Connection connect(String url) {
- Connection con = new HttpConnection();
- con.url(url);
- return con;
- }
-
- public static Connection connect(URL url) {
- Connection con = new HttpConnection();
- con.url(url);
- return con;
- }
-
- private Connection.Request req;
- private Connection.Response res;
-
- private HttpConnection() {
- req = new Request();
- res = new Response();
- }
-
- public Connection url(URL url) {
- req.url(url);
- return this;
- }
-
- public Connection url(String url) {
- Validate.notEmpty(url, "Must supply a valid URL");
- try {
- req.url(new URL(url));
- } catch (MalformedURLException e) {
- throw new IllegalArgumentException("Malformed URL: " + url, e);
- }
- return this;
- }
-
- public Connection userAgent(String userAgent) {
- Validate.notNull(userAgent, "User agent must not be null");
- req.header("User-Agent", userAgent);
- return this;
- }
-
- public Connection timeout(int millis) {
- req.timeout(millis);
- return this;
- }
-
- public Connection followRedirects(boolean followRedirects) {
- req.followRedirects(followRedirects);
- return this;
- }
-
- public Connection referrer(String referrer) {
- Validate.notNull(referrer, "Referrer must not be null");
- req.header("Referer", referrer);
- return this;
- }
-
- public Connection method(Method method) {
- req.method(method);
- return this;
- }
-
- public Connection ignoreHttpErrors(boolean ignoreHttpErrors) {
- req.ignoreHttpErrors(ignoreHttpErrors);
- return this;
- }
-
- public Connection ignoreContentType(boolean ignoreContentType) {
- req.ignoreContentType(ignoreContentType);
- return this;
- }
-
- public Connection data(String key, String value) {
- req.data(KeyVal.create(key, value));
- return this;
- }
-
- public Connection data(Map<String, String> data) {
- Validate.notNull(data, "Data map must not be null");
- for (Map.Entry<String, String> entry : data.entrySet()) {
- req.data(KeyVal.create(entry.getKey(), entry.getValue()));
- }
- return this;
- }
-
- public Connection data(String... keyvals) {
- Validate.notNull(keyvals, "Data key value pairs must not be null");
- Validate.isTrue(keyvals.length %2 == 0, "Must supply an even number of key value pairs");
- for (int i = 0; i < keyvals.length; i += 2) {
- String key = keyvals[i];
- String value = keyvals[i+1];
- Validate.notEmpty(key, "Data key must not be empty");
- Validate.notNull(value, "Data value must not be null");
- req.data(KeyVal.create(key, value));
- }
- return this;
- }
-
- public Connection header(String name, String value) {
- req.header(name, value);
- return this;
- }
-
- public Connection cookie(String name, String value) {
- req.cookie(name, value);
- return this;
- }
-
- public Connection cookies(Map<String, String> cookies) {
- Validate.notNull(cookies, "Cookie map must not be null");
- for (Map.Entry<String, String> entry : cookies.entrySet()) {
- req.cookie(entry.getKey(), entry.getValue());
- }
- return this;
- }
-
- public Connection parser(Parser parser) {
- req.parser(parser);
- return this;
- }
-
- public Document get() throws IOException {
- req.method(Method.GET);
- execute();
- return res.parse();
- }
-
- public Document post() throws IOException {
- req.method(Method.POST);
- execute();
- return res.parse();
- }
-
- public Connection.Response execute() throws IOException {
- res = Response.execute(req);
- return res;
- }
-
- public Connection.Request request() {
- return req;
- }
-
- public Connection request(Connection.Request request) {
- req = request;
- return this;
- }
-
- public Connection.Response response() {
- return res;
- }
-
- public Connection response(Connection.Response response) {
- res = response;
- return this;
- }
-
- @SuppressWarnings({"unchecked"})
- private static abstract class Base<T extends Connection.Base> implements Connection.Base<T> {
- URL url;
- Method method;
- Map<String, String> headers;
- Map<String, String> cookies;
-
- private Base() {
- headers = new LinkedHashMap<String, String>();
- cookies = new LinkedHashMap<String, String>();
- }
-
- public URL url() {
- return url;
- }
-
- public T url(URL url) {
- Validate.notNull(url, "URL must not be null");
- this.url = url;
- return (T) this;
- }
-
- public Method method() {
- return method;
- }
-
- public T method(Method method) {
- Validate.notNull(method, "Method must not be null");
- this.method = method;
- return (T) this;
- }
-
- public String header(String name) {
- Validate.notNull(name, "Header name must not be null");
- return getHeaderCaseInsensitive(name);
- }
-
- public T header(String name, String value) {
- Validate.notEmpty(name, "Header name must not be empty");
- Validate.notNull(value, "Header value must not be null");
- removeHeader(name); // ensures we don't get an "accept-encoding" and a "Accept-Encoding"
- headers.put(name, value);
- return (T) this;
- }
-
- public boolean hasHeader(String name) {
- Validate.notEmpty(name, "Header name must not be empty");
- return getHeaderCaseInsensitive(name) != null;
- }
-
- public T removeHeader(String name) {
- Validate.notEmpty(name, "Header name must not be empty");
- Map.Entry<String, String> entry = scanHeaders(name); // remove is case insensitive too
- if (entry != null)
- headers.remove(entry.getKey()); // ensures correct case
- return (T) this;
- }
-
- public Map<String, String> headers() {
- return headers;
- }
-
- private String getHeaderCaseInsensitive(String name) {
- Validate.notNull(name, "Header name must not be null");
- // quick evals for common case of title case, lower case, then scan for mixed
- String value = headers.get(name);
- if (value == null)
- value = headers.get(name.toLowerCase());
- if (value == null) {
- Map.Entry<String, String> entry = scanHeaders(name);
- if (entry != null)
- value = entry.getValue();
- }
- return value;
- }
-
- private Map.Entry<String, String> scanHeaders(String name) {
- String lc = name.toLowerCase();
- for (Map.Entry<String, String> entry : headers.entrySet()) {
- if (entry.getKey().toLowerCase().equals(lc))
- return entry;
- }
- return null;
- }
-
- public String cookie(String name) {
- Validate.notNull(name, "Cookie name must not be null");
- return cookies.get(name);
- }
-
- public T cookie(String name, String value) {
- Validate.notEmpty(name, "Cookie name must not be empty");
- Validate.notNull(value, "Cookie value must not be null");
- cookies.put(name, value);
- return (T) this;
- }
-
- public boolean hasCookie(String name) {
- Validate.notEmpty("Cookie name must not be empty");
- return cookies.containsKey(name);
- }
-
- public T removeCookie(String name) {
- Validate.notEmpty("Cookie name must not be empty");
- cookies.remove(name);
- return (T) this;
- }
-
- public Map<String, String> cookies() {
- return cookies;
- }
- }
-
- public static class Request extends Base<Connection.Request> implements Connection.Request {
- private int timeoutMilliseconds;
- private boolean followRedirects;
- private Collection<Connection.KeyVal> data;
- private boolean ignoreHttpErrors = false;
- private boolean ignoreContentType = false;
- private Parser parser;
-
- private Request() {
- timeoutMilliseconds = 3000;
- followRedirects = true;
- data = new ArrayList<Connection.KeyVal>();
- method = Connection.Method.GET;
- headers.put("Accept-Encoding", "gzip");
- parser = Parser.htmlParser();
- }
-
- public int timeout() {
- return timeoutMilliseconds;
- }
-
- public Request timeout(int millis) {
- Validate.isTrue(millis >= 0, "Timeout milliseconds must be 0 (infinite) or greater");
- timeoutMilliseconds = millis;
- return this;
- }
-
- public boolean followRedirects() {
- return followRedirects;
- }
-
- public Connection.Request followRedirects(boolean followRedirects) {
- this.followRedirects = followRedirects;
- return this;
- }
-
- public boolean ignoreHttpErrors() {
- return ignoreHttpErrors;
- }
-
- public Connection.Request ignoreHttpErrors(boolean ignoreHttpErrors) {
- this.ignoreHttpErrors = ignoreHttpErrors;
- return this;
- }
-
- public boolean ignoreContentType() {
- return ignoreContentType;
- }
-
- public Connection.Request ignoreContentType(boolean ignoreContentType) {
- this.ignoreContentType = ignoreContentType;
- return this;
- }
-
- public Request data(Connection.KeyVal keyval) {
- Validate.notNull(keyval, "Key val must not be null");
- data.add(keyval);
- return this;
- }
-
- public Collection<Connection.KeyVal> data() {
- return data;
- }
-
- public Request parser(Parser parser) {
- this.parser = parser;
- return this;
- }
-
- public Parser parser() {
- return parser;
- }
- }
-
- public static class Response extends Base<Connection.Response> implements Connection.Response {
- private static final int MAX_REDIRECTS = 20;
- private int statusCode;
- private String statusMessage;
- private ByteBuffer byteData;
- private String charset;
- private String contentType;
- private boolean executed = false;
- private int numRedirects = 0;
- private Connection.Request req;
-
- Response() {
- super();
- }
-
- private Response(Response previousResponse) throws IOException {
- super();
- if (previousResponse != null) {
- numRedirects = previousResponse.numRedirects + 1;
- if (numRedirects >= MAX_REDIRECTS)
- throw new IOException(String.format("Too many redirects occurred trying to load URL %s", previousResponse.url()));
- }
- }
-
- static Response execute(Connection.Request req) throws IOException {
- return execute(req, null);
- }
-
- static Response execute(Connection.Request req, Response previousResponse) throws IOException {
- Validate.notNull(req, "Request must not be null");
- String protocol = req.url().getProtocol();
- Validate
- .isTrue(protocol.equals("http") || protocol.equals("https"), "Only http & https protocols supported");
-
- // set up the request for execution
- if (req.method() == Connection.Method.GET && req.data().size() > 0)
- serialiseRequestUrl(req); // appends query string
- HttpURLConnection conn = createConnection(req);
- conn.connect();
- if (req.method() == Connection.Method.POST)
- writePost(req.data(), conn.getOutputStream());
-
- int status = conn.getResponseCode();
- boolean needsRedirect = false;
- if (status != HttpURLConnection.HTTP_OK) {
- if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER)
- needsRedirect = true;
- else if (!req.ignoreHttpErrors())
- throw new IOException(status + " error loading URL " + req.url().toString());
- }
- Response res = new Response(previousResponse);
- res.setupFromConnection(conn, previousResponse);
- if (needsRedirect && req.followRedirects()) {
- req.method(Method.GET); // always redirect with a get. any data param from original req are dropped.
- req.data().clear();
- req.url(new URL(req.url(), res.header("Location")));
- for (Map.Entry<String, String> cookie : res.cookies.entrySet()) { // add response cookies to request (for e.g. login posts)
- req.cookie(cookie.getKey(), cookie.getValue());
- }
- return execute(req, res);
- }
- res.req = req;
-
- InputStream bodyStream = null;
- InputStream dataStream = null;
- try {
- dataStream = conn.getErrorStream() != null ? conn.getErrorStream() : conn.getInputStream();
- bodyStream = res.hasHeader("Content-Encoding") && res.header("Content-Encoding").equalsIgnoreCase("gzip") ?
- new BufferedInputStream(new GZIPInputStream(dataStream)) :
- new BufferedInputStream(dataStream);
-
- res.byteData = DataUtil.readToByteBuffer(bodyStream);
- res.charset = DataUtil.getCharsetFromContentType(res.contentType); // may be null, readInputStream deals with it
- } finally {
- if (bodyStream != null) bodyStream.close();
- if (dataStream != null) dataStream.close();
- }
-
- res.executed = true;
- return res;
- }
-
- public int statusCode() {
- return statusCode;
- }
-
- public String statusMessage() {
- return statusMessage;
- }
-
- public String charset() {
- return charset;
- }
-
- public String contentType() {
- return contentType;
- }
-
- public Document parse() throws IOException {
- Validate.isTrue(executed, "Request must be executed (with .execute(), .get(), or .post() before parsing response");
- if (!req.ignoreContentType() && (contentType == null || !(contentType.startsWith("text/") || contentType.startsWith("application/xml") || contentType.startsWith("application/xhtml+xml"))))
- throw new IOException(String.format("Unhandled content type \"%s\" on URL %s. Must be text/*, application/xml, or application/xhtml+xml",
- contentType, url.toString()));
- Document doc = DataUtil.parseByteData(byteData, charset, url.toExternalForm(), req.parser());
- byteData.rewind();
- charset = doc.outputSettings().charset().name(); // update charset from meta-equiv, possibly
- return doc;
- }
-
- public String body() {
- Validate.isTrue(executed, "Request must be executed (with .execute(), .get(), or .post() before getting response body");
- // charset gets set from header on execute, and from meta-equiv on parse. parse may not have happened yet
- String body;
- if (charset == null)
- body = Charset.forName(DataUtil.defaultCharset).decode(byteData).toString();
- else
- body = Charset.forName(charset).decode(byteData).toString();
- byteData.rewind();
- return body;
- }
-
- public byte[] bodyAsBytes() {
- Validate.isTrue(executed, "Request must be executed (with .execute(), .get(), or .post() before getting response body");
- return byteData.array();
- }
-
- // set up connection defaults, and details from request
- private static HttpURLConnection createConnection(Connection.Request req) throws IOException {
- HttpURLConnection conn = (HttpURLConnection) req.url().openConnection();
- conn.setRequestMethod(req.method().name());
- conn.setInstanceFollowRedirects(false); // don't rely on native redirection support
- conn.setConnectTimeout(req.timeout());
- conn.setReadTimeout(req.timeout());
- if (req.method() == Method.POST)
- conn.setDoOutput(true);
- if (req.cookies().size() > 0)
- conn.addRequestProperty("Cookie", getRequestCookieString(req));
- for (Map.Entry<String, String> header : req.headers().entrySet()) {
- conn.addRequestProperty(header.getKey(), header.getValue());
- }
- return conn;
- }
-
- // set up url, method, header, cookies
- private void setupFromConnection(HttpURLConnection conn, Connection.Response previousResponse) throws IOException {
- method = Connection.Method.valueOf(conn.getRequestMethod());
- url = conn.getURL();
- statusCode = conn.getResponseCode();
- statusMessage = conn.getResponseMessage();
- contentType = conn.getContentType();
-
- Map<String, List<String>> resHeaders = conn.getHeaderFields();
- processResponseHeaders(resHeaders);
-
- // if from a redirect, map previous response cookies into this response
- if (previousResponse != null) {
- for (Map.Entry<String, String> prevCookie : previousResponse.cookies().entrySet()) {
- if (!hasCookie(prevCookie.getKey()))
- cookie(prevCookie.getKey(), prevCookie.getValue());
- }
- }
- }
-
- void processResponseHeaders(Map<String, List<String>> resHeaders) {
- for (Map.Entry<String, List<String>> entry : resHeaders.entrySet()) {
- String name = entry.getKey();
- if (name == null)
- continue; // http/1.1 line
-
- List<String> values = entry.getValue();
- if (name.equalsIgnoreCase("Set-Cookie")) {
- for (String value : values) {
- if (value == null)
- continue;
- TokenQueue cd = new TokenQueue(value);
- String cookieName = cd.chompTo("=").trim();
- String cookieVal = cd.consumeTo(";").trim();
- if (cookieVal == null)
- cookieVal = "";
- // ignores path, date, domain, secure et al. req'd?
- // name not blank, value not null
- if (cookieName != null && cookieName.length() > 0)
- cookie(cookieName, cookieVal);
- }
- } else { // only take the first instance of each header
- if (!values.isEmpty())
- header(name, values.get(0));
- }
- }
- }
-
- private static void writePost(Collection<Connection.KeyVal> data, OutputStream outputStream) throws IOException {
- OutputStreamWriter w = new OutputStreamWriter(outputStream, DataUtil.defaultCharset);
- boolean first = true;
- for (Connection.KeyVal keyVal : data) {
- if (!first)
- w.append('&');
- else
- first = false;
-
- w.write(URLEncoder.encode(keyVal.key(), DataUtil.defaultCharset));
- w.write('=');
- w.write(URLEncoder.encode(keyVal.value(), DataUtil.defaultCharset));
- }
- w.close();
- }
-
- private static String getRequestCookieString(Connection.Request req) {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (Map.Entry<String, String> cookie : req.cookies().entrySet()) {
- if (!first)
- sb.append("; ");
- else
- first = false;
- sb.append(cookie.getKey()).append('=').append(cookie.getValue());
- // todo: spec says only ascii, no escaping / encoding defined. validate on set? or escape somehow here?
- }
- return sb.toString();
- }
-
- // for get url reqs, serialise the data map into the url
- private static void serialiseRequestUrl(Connection.Request req) throws IOException {
- URL in = req.url();
- StringBuilder url = new StringBuilder();
- boolean first = true;
- // reconstitute the query, ready for appends
- url
- .append(in.getProtocol())
- .append("://")
- .append(in.getAuthority()) // includes host, port
- .append(in.getPath())
- .append("?");
- if (in.getQuery() != null) {
- url.append(in.getQuery());
- first = false;
- }
- for (Connection.KeyVal keyVal : req.data()) {
- if (!first)
- url.append('&');
- else
- first = false;
- url
- .append(URLEncoder.encode(keyVal.key(), DataUtil.defaultCharset))
- .append('=')
- .append(URLEncoder.encode(keyVal.value(), DataUtil.defaultCharset));
- }
- req.url(new URL(url.toString()));
- req.data().clear(); // moved into url as get params
- }
- }
-
- public static class KeyVal implements Connection.KeyVal {
- private String key;
- private String value;
-
- public static KeyVal create(String key, String value) {
- Validate.notEmpty(key, "Data key must not be empty");
- Validate.notNull(value, "Data value must not be null");
- return new KeyVal(key, value);
- }
-
- private KeyVal(String key, String value) {
- this.key = key;
- this.value = value;
- }
-
- public KeyVal key(String key) {
- Validate.notEmpty(key, "Data key must not be empty");
- this.key = key;
- return this;
- }
-
- public String key() {
- return key;
- }
-
- public KeyVal value(String value) {
- Validate.notNull(value, "Data value must not be null");
- this.value = value;
- return this;
- }
-
- public String value() {
- return value;
- }
-
- @Override
- public String toString() {
- return key + "=" + value;
- }
- }
-}
diff --git a/src/org/jsoup/helper/StringUtil.java b/src/org/jsoup/helper/StringUtil.java
deleted file mode 100644
index 071a92c7a5..0000000000
--- a/src/org/jsoup/helper/StringUtil.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.jsoup.helper;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * A minimal String utility class. Designed for internal jsoup use only.
- */
-public final class StringUtil {
- // memoised padding up to 10
- private static final String[] padding = {"", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
-
- /**
- * Join a collection of strings by a seperator
- * @param strings collection of string objects
- * @param sep string to place between strings
- * @return joined string
- */
- public static String join(Collection strings, String sep) {
- return join(strings.iterator(), sep);
- }
-
- /**
- * Join a collection of strings by a seperator
- * @param strings iterator of string objects
- * @param sep string to place between strings
- * @return joined string
- */
- public static String join(Iterator strings, String sep) {
- if (!strings.hasNext())
- return "";
-
- String start = strings.next().toString();
- if (!strings.hasNext()) // only one, avoid builder
- return start;
-
- StringBuilder sb = new StringBuilder(64).append(start);
- while (strings.hasNext()) {
- sb.append(sep);
- sb.append(strings.next());
- }
- return sb.toString();
- }
-
- /**
- * Returns space padding
- * @param width amount of padding desired
- * @return string of spaces * width
- */
- public static String padding(int width) {
- if (width < 0)
- throw new IllegalArgumentException("width must be > 0");
-
- if (width < padding.length)
- return padding[width];
-
- char[] out = new char[width];
- for (int i = 0; i < width; i++)
- out[i] = ' ';
- return String.valueOf(out);
- }
-
- /**
- * Tests if a string is blank: null, emtpy, or only whitespace (" ", \r\n, \t, etc)
- * @param string string to test
- * @return if string is blank
- */
- public static boolean isBlank(String string) {
- if (string == null || string.length() == 0)
- return true;
-
- int l = string.length();
- for (int i = 0; i < l; i++) {
- if (!StringUtil.isWhitespace(string.codePointAt(i)))
- return false;
- }
- return true;
- }
-
- /**
- * Tests if a string is numeric, i.e. contains only digit characters
- * @param string string to test
- * @return true if only digit chars, false if empty or null or contains non-digit chrs
- */
- public static boolean isNumeric(String string) {
- if (string == null || string.length() == 0)
- return false;
-
- int l = string.length();
- for (int i = 0; i < l; i++) {
- if (!Character.isDigit(string.codePointAt(i)))
- return false;
- }
- return true;
- }
-
- /**
- * Tests if a code point is "whitespace" as defined in the HTML spec.
- * @param c code point to test
- * @return true if code point is whitespace, false otherwise
- */
- public static boolean isWhitespace(int c){
- return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
- }
-
- public static String normaliseWhitespace(String string) {
- StringBuilder sb = new StringBuilder(string.length());
-
- boolean lastWasWhite = false;
- boolean modified = false;
-
- int l = string.length();
- for (int i = 0; i < l; i++) {
- int c = string.codePointAt(i);
- if (isWhitespace(c)) {
- if (lastWasWhite) {
- modified = true;
- continue;
- }
- if (c != ' ')
- modified = true;
- sb.append(' ');
- lastWasWhite = true;
- }
- else {
- sb.appendCodePoint(c);
- lastWasWhite = false;
- }
- }
- return modified ? sb.toString() : string;
- }
-
- public static boolean in(String needle, String... haystack) {
- for (String hay : haystack) {
- if (hay.equals(needle))
- return true;
- }
- return false;
- }
-}
diff --git a/src/org/jsoup/helper/Validate.java b/src/org/jsoup/helper/Validate.java
deleted file mode 100644
index 814bcc3a40..0000000000
--- a/src/org/jsoup/helper/Validate.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.jsoup.helper;
-
-/**
- * Simple validation methods. Designed for jsoup internal use
- */
-public final class Validate {
-
- private Validate() {}
-
- /**
- * Validates that the object is not null
- * @param obj object to test
- */
- public static void notNull(Object obj) {
- if (obj == null)
- throw new IllegalArgumentException("Object must not be null");
- }
-
- /**
- * Validates that the object is not null
- * @param obj object to test
- * @param msg message to output if validation fails
- */
- public static void notNull(Object obj, String msg) {
- if (obj == null)
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Validates that the value is true
- * @param val object to test
- */
- public static void isTrue(boolean val) {
- if (!val)
- throw new IllegalArgumentException("Must be true");
- }
-
- /**
- * Validates that the value is true
- * @param val object to test
- * @param msg message to output if validation fails
- */
- public static void isTrue(boolean val, String msg) {
- if (!val)
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Validates that the value is false
- * @param val object to test
- */
- public static void isFalse(boolean val) {
- if (val)
- throw new IllegalArgumentException("Must be false");
- }
-
- /**
- * Validates that the value is false
- * @param val object to test
- * @param msg message to output if validation fails
- */
- public static void isFalse(boolean val, String msg) {
- if (val)
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Validates that the array contains no null elements
- * @param objects the array to test
- */
- public static void noNullElements(Object[] objects) {
- noNullElements(objects, "Array must not contain any null objects");
- }
-
- /**
- * Validates that the array contains no null elements
- * @param objects the array to test
- * @param msg message to output if validation fails
- */
- public static void noNullElements(Object[] objects, String msg) {
- for (Object obj : objects)
- if (obj == null)
- throw new IllegalArgumentException(msg);
- }
-
- /**
- * Validates that the string is not empty
- * @param string the string to test
- */
- public static void notEmpty(String string) {
- if (string == null || string.length() == 0)
- throw new IllegalArgumentException("String must not be empty");
- }
-
- /**
- * Validates that the string is not empty
- * @param string the string to test
- * @param msg message to output if validation fails
- */
- public static void notEmpty(String string, String msg) {
- if (string == null || string.length() == 0)
- throw new IllegalArgumentException(msg);
- }
-
- /**
- Cause a failure.
- @param msg message to output.
- */
- public static void fail(String msg) {
- throw new IllegalArgumentException(msg);
- }
-}
diff --git a/src/org/jsoup/nodes/Attribute.java b/src/org/jsoup/nodes/Attribute.java
deleted file mode 100644
index 02eb29db83..0000000000
--- a/src/org/jsoup/nodes/Attribute.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.Validate;
-
-import java.util.Map;
-
-/**
- A single key + value attribute. Keys are trimmed and normalised to lower-case.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class Attribute implements Map.Entry<String, String>, Cloneable {
- private String key;
- private String value;
-
- /**
- * Create a new attribute from unencoded (raw) key and value.
- * @param key attribute key
- * @param value attribute value
- * @see #createFromEncoded
- */
- public Attribute(String key, String value) {
- Validate.notEmpty(key);
- Validate.notNull(value);
- this.key = key.trim().toLowerCase();
- this.value = value;
- }
-
- /**
- Get the attribute key.
- @return the attribute key
- */
- public String getKey() {
- return key;
- }
-
- /**
- Set the attribute key. Gets normalised as per the constructor method.
- @param key the new key; must not be null
- */
- public void setKey(String key) {
- Validate.notEmpty(key);
- this.key = key.trim().toLowerCase();
- }
-
- /**
- Get the attribute value.
- @return the attribute value
- */
- public String getValue() {
- return value;
- }
-
- /**
- Set the attribute value.
- @param value the new attribute value; must not be null
- */
- public String setValue(String value) {
- Validate.notNull(value);
- String old = this.value;
- this.value = value;
- return old;
- }
-
- /**
- Get the HTML representation of this attribute; e.g. {@code href="index.html"}.
- @return HTML
- */
- public String html() {
- return key + "=\"" + Entities.escape(value, (new Document("")).outputSettings()) + "\"";
- }
-
- protected void html(StringBuilder accum, Document.OutputSettings out) {
- accum
- .append(key)
- .append("=\"")
- .append(Entities.escape(value, out))
- .append("\"");
- }
-
- /**
- Get the string representation of this attribute, implemented as {@link #html()}.
- @return string
- */
- public String toString() {
- return html();
- }
-
- /**
- * Create a new Attribute from an unencoded key and a HTML attribute encoded value.
- * @param unencodedKey assumes the key is not encoded, as can be only run of simple \w chars.
- * @param encodedValue HTML attribute encoded value
- * @return attribute
- */
- public static Attribute createFromEncoded(String unencodedKey, String encodedValue) {
- String value = Entities.unescape(encodedValue, true);
- return new Attribute(unencodedKey, value);
- }
-
- protected boolean isDataAttribute() {
- return key.startsWith(Attributes.dataPrefix) && key.length() > Attributes.dataPrefix.length();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Attribute)) return false;
-
- Attribute attribute = (Attribute) o;
-
- if (key != null ? !key.equals(attribute.key) : attribute.key != null) return false;
- if (value != null ? !value.equals(attribute.value) : attribute.value != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = key != null ? key.hashCode() : 0;
- result = 31 * result + (value != null ? value.hashCode() : 0);
- return result;
- }
-
- @Override
- public Attribute clone() {
- try {
- return (Attribute) super.clone(); // only fields are immutable strings key and value, so no more deep copy required
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/org/jsoup/nodes/Attributes.java b/src/org/jsoup/nodes/Attributes.java
deleted file mode 100644
index 9436750fc9..0000000000
--- a/src/org/jsoup/nodes/Attributes.java
+++ /dev/null
@@ -1,249 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.Validate;
-
-import java.util.*;
-
-/**
- * The attributes of an Element.
- * <p/>
- * Attributes are treated as a map: there can be only one value associated with an attribute key.
- * <p/>
- * Attribute key and value comparisons are done case insensitively, and keys are normalised to
- * lower-case.
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- */
-public class Attributes implements Iterable<Attribute>, Cloneable {
- protected static final String dataPrefix = "data-";
-
- private LinkedHashMap<String, Attribute> attributes = null;
- // linked hash map to preserve insertion order.
- // null be default as so many elements have no attributes -- saves a good chunk of memory
-
- /**
- Get an attribute value by key.
- @param key the attribute key
- @return the attribute value if set; or empty string if not set.
- @see #hasKey(String)
- */
- public String get(String key) {
- Validate.notEmpty(key);
-
- if (attributes == null)
- return "";
-
- Attribute attr = attributes.get(key.toLowerCase());
- return attr != null ? attr.getValue() : "";
- }
-
- /**
- Set a new attribute, or replace an existing one by key.
- @param key attribute key
- @param value attribute value
- */
- public void put(String key, String value) {
- Attribute attr = new Attribute(key, value);
- put(attr);
- }
-
- /**
- Set a new attribute, or replace an existing one by key.
- @param attribute attribute
- */
- public void put(Attribute attribute) {
- Validate.notNull(attribute);
- if (attributes == null)
- attributes = new LinkedHashMap<String, Attribute>(2);
- attributes.put(attribute.getKey(), attribute);
- }
-
- /**
- Remove an attribute by key.
- @param key attribute key to remove
- */
- public void remove(String key) {
- Validate.notEmpty(key);
- if (attributes == null)
- return;
- attributes.remove(key.toLowerCase());
- }
-
- /**
- Tests if these attributes contain an attribute with this key.
- @param key key to check for
- @return true if key exists, false otherwise
- */
- public boolean hasKey(String key) {
- return attributes != null && attributes.containsKey(key.toLowerCase());
- }
-
- /**
- Get the number of attributes in this set.
- @return size
- */
- public int size() {
- if (attributes == null)
- return 0;
- return attributes.size();
- }
-
- /**
- Add all the attributes from the incoming set to this set.
- @param incoming attributes to add to these attributes.
- */
- public void addAll(Attributes incoming) {
- if (incoming.size() == 0)
- return;
- if (attributes == null)
- attributes = new LinkedHashMap<String, Attribute>(incoming.size());
- attributes.putAll(incoming.attributes);
- }
-
- public Iterator<Attribute> iterator() {
- return asList().iterator();
- }
-
- /**
- Get the attributes as a List, for iteration. Do not modify the keys of the attributes via this view, as changes
- to keys will not be recognised in the containing set.
- @return an view of the attributes as a List.
- */
- public List<Attribute> asList() {
- if (attributes == null)
- return Collections.emptyList();
-
- List<Attribute> list = new ArrayList<Attribute>(attributes.size());
- for (Map.Entry<String, Attribute> entry : attributes.entrySet()) {
- list.add(entry.getValue());
- }
- return Collections.unmodifiableList(list);
- }
-
- /**
- * Retrieves a filtered view of attributes that are HTML5 custom data attributes; that is, attributes with keys
- * starting with {@code data-}.
- * @return map of custom data attributes.
- */
- public Map<String, String> dataset() {
- return new Dataset();
- }
-
- /**
- Get the HTML representation of these attributes.
- @return HTML
- */
- public String html() {
- StringBuilder accum = new StringBuilder();
- html(accum, (new Document("")).outputSettings()); // output settings a bit funky, but this html() seldom used
- return accum.toString();
- }
-
- void html(StringBuilder accum, Document.OutputSettings out) {
- if (attributes == null)
- return;
-
- for (Map.Entry<String, Attribute> entry : attributes.entrySet()) {
- Attribute attribute = entry.getValue();
- accum.append(" ");
- attribute.html(accum, out);
- }
- }
-
- public String toString() {
- return html();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Attributes)) return false;
-
- Attributes that = (Attributes) o;
-
- if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return attributes != null ? attributes.hashCode() : 0;
- }
-
- @Override
- public Attributes clone() {
- if (attributes == null)
- return new Attributes();
-
- Attributes clone;
- try {
- clone = (Attributes) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
- clone.attributes = new LinkedHashMap<String, Attribute>(attributes.size());
- for (Attribute attribute: this)
- clone.attributes.put(attribute.getKey(), attribute.clone());
- return clone;
- }
-
- private class Dataset extends AbstractMap<String, String> {
-
- private Dataset() {
- if (attributes == null)
- attributes = new LinkedHashMap<String, Attribute>(2);
- }
-
- public Set<Entry<String, String>> entrySet() {
- return new EntrySet();
- }
-
- @Override
- public String put(String key, String value) {
- String dataKey = dataKey(key);
- String oldValue = hasKey(dataKey) ? attributes.get(dataKey).getValue() : null;
- Attribute attr = new Attribute(dataKey, value);
- attributes.put(dataKey, attr);
- return oldValue;
- }
-
- private class EntrySet extends AbstractSet<Map.Entry<String, String>> {
- public Iterator<Map.Entry<String, String>> iterator() {
- return new DatasetIterator();
- }
-
- public int size() {
- int count = 0;
- Iterator iter = new DatasetIterator();
- while (iter.hasNext())
- count++;
- return count;
- }
- }
-
- private class DatasetIterator implements Iterator<Map.Entry<String, String>> {
- private Iterator<Attribute> attrIter = attributes.values().iterator();
- private Attribute attr;
- public boolean hasNext() {
- while (attrIter.hasNext()) {
- attr = attrIter.next();
- if (attr.isDataAttribute()) return true;
- }
- return false;
- }
-
- public Entry<String, String> next() {
- return new Attribute(attr.getKey().substring(dataPrefix.length()), attr.getValue());
- }
-
- public void remove() {
- attributes.remove(attr.getKey());
- }
- }
- }
-
- private static String dataKey(String key) {
- return dataPrefix + key;
- }
-}
diff --git a/src/org/jsoup/nodes/Comment.java b/src/org/jsoup/nodes/Comment.java
deleted file mode 100644
index 37fd4368fa..0000000000
--- a/src/org/jsoup/nodes/Comment.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.jsoup.nodes;
-
-/**
- A comment node.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class Comment extends Node {
- private static final String COMMENT_KEY = "comment";
-
- /**
- Create a new comment node.
- @param data The contents of the comment
- @param baseUri base URI
- */
- public Comment(String data, String baseUri) {
- super(baseUri);
- attributes.put(COMMENT_KEY, data);
- }
-
- public String nodeName() {
- return "#comment";
- }
-
- /**
- Get the contents of the comment.
- @return comment content
- */
- public String getData() {
- return attributes.get(COMMENT_KEY);
- }
-
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- if (out.prettyPrint())
- indent(accum, depth, out);
- accum
- .append("<!--")
- .append(getData())
- .append("-->");
- }
-
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {}
-
- public String toString() {
- return outerHtml();
- }
-}
diff --git a/src/org/jsoup/nodes/DataNode.java b/src/org/jsoup/nodes/DataNode.java
deleted file mode 100644
index a64f56f0a4..0000000000
--- a/src/org/jsoup/nodes/DataNode.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.jsoup.nodes;
-
-/**
- A data node, for contents of style, script tags etc, where contents should not show in text().
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class DataNode extends Node{
- private static final String DATA_KEY = "data";
-
- /**
- Create a new DataNode.
- @param data data contents
- @param baseUri base URI
- */
- public DataNode(String data, String baseUri) {
- super(baseUri);
- attributes.put(DATA_KEY, data);
- }
-
- public String nodeName() {
- return "#data";
- }
-
- /**
- Get the data contents of this node. Will be unescaped and with original new lines, space etc.
- @return data
- */
- public String getWholeData() {
- return attributes.get(DATA_KEY);
- }
-
- /**
- * Set the data contents of this node.
- * @param data unencoded data
- * @return this node, for chaining
- */
- public DataNode setWholeData(String data) {
- attributes.put(DATA_KEY, data);
- return this;
- }
-
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- accum.append(getWholeData()); // data is not escaped in return from data nodes, so " in script, style is plain
- }
-
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {}
-
- public String toString() {
- return outerHtml();
- }
-
- /**
- Create a new DataNode from HTML encoded data.
- @param encodedData encoded data
- @param baseUri bass URI
- @return new DataNode
- */
- public static DataNode createFromEncoded(String encodedData, String baseUri) {
- String data = Entities.unescape(encodedData);
- return new DataNode(data, baseUri);
- }
-}
diff --git a/src/org/jsoup/nodes/Document.java b/src/org/jsoup/nodes/Document.java
deleted file mode 100644
index adb371ce14..0000000000
--- a/src/org/jsoup/nodes/Document.java
+++ /dev/null
@@ -1,350 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.parser.Tag;
-import org.jsoup.select.Elements;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetEncoder;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- A HTML Document.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class Document extends Element {
- private OutputSettings outputSettings = new OutputSettings();
- private QuirksMode quirksMode = QuirksMode.noQuirks;
-
- /**
- Create a new, empty Document.
- @param baseUri base URI of document
- @see org.jsoup.Jsoup#parse
- @see #createShell
- */
- public Document(String baseUri) {
- super(Tag.valueOf("#root"), baseUri);
- }
-
- /**
- Create a valid, empty shell of a document, suitable for adding more elements to.
- @param baseUri baseUri of document
- @return document with html, head, and body elements.
- */
- static public Document createShell(String baseUri) {
- Validate.notNull(baseUri);
-
- Document doc = new Document(baseUri);
- Element html = doc.appendElement("html");
- html.appendElement("head");
- html.appendElement("body");
-
- return doc;
- }
-
- /**
- Accessor to the document's {@code head} element.
- @return {@code head}
- */
- public Element head() {
- return findFirstElementByTagName("head", this);
- }
-
- /**
- Accessor to the document's {@code body} element.
- @return {@code body}
- */
- public Element body() {
- return findFirstElementByTagName("body", this);
- }
-
- /**
- Get the string contents of the document's {@code title} element.
- @return Trimmed title, or empty string if none set.
- */
- public String title() {
- Element titleEl = getElementsByTag("title").first();
- return titleEl != null ? titleEl.text().trim() : "";
- }
-
- /**
- Set the document's {@code title} element. Updates the existing element, or adds {@code title} to {@code head} if
- not present
- @param title string to set as title
- */
- public void title(String title) {
- Validate.notNull(title);
- Element titleEl = getElementsByTag("title").first();
- if (titleEl == null) { // add to head
- head().appendElement("title").text(title);
- } else {
- titleEl.text(title);
- }
- }
-
- /**
- Create a new Element, with this document's base uri. Does not make the new element a child of this document.
- @param tagName element tag name (e.g. {@code a})
- @return new element
- */
- public Element createElement(String tagName) {
- return new Element(Tag.valueOf(tagName), this.baseUri());
- }
-
- /**
- Normalise the document. This happens after the parse phase so generally does not need to be called.
- Moves any text content that is not in the body element into the body.
- @return this document after normalisation
- */
- public Document normalise() {
- Element htmlEl = findFirstElementByTagName("html", this);
- if (htmlEl == null)
- htmlEl = appendElement("html");
- if (head() == null)
- htmlEl.prependElement("head");
- if (body() == null)
- htmlEl.appendElement("body");
-
- // pull text nodes out of root, html, and head els, and push into body. non-text nodes are already taken care
- // of. do in inverse order to maintain text order.
- normaliseTextNodes(head());
- normaliseTextNodes(htmlEl);
- normaliseTextNodes(this);
-
- normaliseStructure("head", htmlEl);
- normaliseStructure("body", htmlEl);
-
- return this;
- }
-
- // does not recurse.
- private void normaliseTextNodes(Element element) {
- List<Node> toMove = new ArrayList<Node>();
- for (Node node: element.childNodes) {
- if (node instanceof TextNode) {
- TextNode tn = (TextNode) node;
- if (!tn.isBlank())
- toMove.add(tn);
- }
- }
-
- for (int i = toMove.size()-1; i >= 0; i--) {
- Node node = toMove.get(i);
- element.removeChild(node);
- body().prependChild(new TextNode(" ", ""));
- body().prependChild(node);
- }
- }
-
- // merge multiple <head> or <body> contents into one, delete the remainder, and ensure they are owned by <html>
- private void normaliseStructure(String tag, Element htmlEl) {
- Elements elements = this.getElementsByTag(tag);
- Element master = elements.first(); // will always be available as created above if not existent
- if (elements.size() > 1) { // dupes, move contents to master
- List<Node> toMove = new ArrayList<Node>();
- for (int i = 1; i < elements.size(); i++) {
- Node dupe = elements.get(i);
- for (Node node : dupe.childNodes)
- toMove.add(node);
- dupe.remove();
- }
-
- for (Node dupe : toMove)
- master.appendChild(dupe);
- }
- // ensure parented by <html>
- if (!master.parent().equals(htmlEl)) {
- htmlEl.appendChild(master); // includes remove()
- }
- }
-
- // fast method to get first by tag name, used for html, head, body finders
- private Element findFirstElementByTagName(String tag, Node node) {
- if (node.nodeName().equals(tag))
- return (Element) node;
- else {
- for (Node child: node.childNodes) {
- Element found = findFirstElementByTagName(tag, child);
- if (found != null)
- return found;
- }
- }
- return null;
- }
-
- @Override
- public String outerHtml() {
- return super.html(); // no outer wrapper tag
- }
-
- /**
- Set the text of the {@code body} of this document. Any existing nodes within the body will be cleared.
- @param text unencoded text
- @return this document
- */
- @Override
- public Element text(String text) {
- body().text(text); // overridden to not nuke doc structure
- return this;
- }
-
- @Override
- public String nodeName() {
- return "#document";
- }
-
- @Override
- public Document clone() {
- Document clone = (Document) super.clone();
- clone.outputSettings = this.outputSettings.clone();
- return clone;
- }
-
- /**
- * A Document's output settings control the form of the text() and html() methods.
- */
- public static class OutputSettings implements Cloneable {
- private Entities.EscapeMode escapeMode = Entities.EscapeMode.base;
- private Charset charset = Charset.forName("UTF-8");
- private CharsetEncoder charsetEncoder = charset.newEncoder();
- private boolean prettyPrint = true;
- private int indentAmount = 1;
-
- public OutputSettings() {}
-
- /**
- * Get the document's current HTML escape mode: <code>base</code>, which provides a limited set of named HTML
- * entities and escapes other characters as numbered entities for maximum compatibility; or <code>extended</code>,
- * which uses the complete set of HTML named entities.
- * <p>
- * The default escape mode is <code>base</code>.
- * @return the document's current escape mode
- */
- public Entities.EscapeMode escapeMode() {
- return escapeMode;
- }
-
- /**
- * Set the document's escape mode
- * @param escapeMode the new escape mode to use
- * @return the document's output settings, for chaining
- */
- public OutputSettings escapeMode(Entities.EscapeMode escapeMode) {
- this.escapeMode = escapeMode;
- return this;
- }
-
- /**
- * Get the document's current output charset, which is used to control which characters are escaped when
- * generating HTML (via the <code>html()</code> methods), and which are kept intact.
- * <p>
- * Where possible (when parsing from a URL or File), the document's output charset is automatically set to the
- * input charset. Otherwise, it defaults to UTF-8.
- * @return the document's current charset.
- */
- public Charset charset() {
- return charset;
- }
-
- /**
- * Update the document's output charset.
- * @param charset the new charset to use.
- * @return the document's output settings, for chaining
- */
- public OutputSettings charset(Charset charset) {
- // todo: this should probably update the doc's meta charset
- this.charset = charset;
- charsetEncoder = charset.newEncoder();
- return this;
- }
-
- /**
- * Update the document's output charset.
- * @param charset the new charset (by name) to use.
- * @return the document's output settings, for chaining
- */
- public OutputSettings charset(String charset) {
- charset(Charset.forName(charset));
- return this;
- }
-
- CharsetEncoder encoder() {
- return charsetEncoder;
- }
-
- /**
- * Get if pretty printing is enabled. Default is true. If disabled, the HTML output methods will not re-format
- * the output, and the output will generally look like the input.
- * @return if pretty printing is enabled.
- */
- public boolean prettyPrint() {
- return prettyPrint;
- }
-
- /**
- * Enable or disable pretty printing.
- * @param pretty new pretty print setting
- * @return this, for chaining
- */
- public OutputSettings prettyPrint(boolean pretty) {
- prettyPrint = pretty;
- return this;
- }
-
- /**
- * Get the current tag indent amount, used when pretty printing.
- * @return the current indent amount
- */
- public int indentAmount() {
- return indentAmount;
- }
-
- /**
- * Set the indent amount for pretty printing
- * @param indentAmount number of spaces to use for indenting each level. Must be >= 0.
- * @return this, for chaining
- */
- public OutputSettings indentAmount(int indentAmount) {
- Validate.isTrue(indentAmount >= 0);
- this.indentAmount = indentAmount;
- return this;
- }
-
- @Override
- public OutputSettings clone() {
- OutputSettings clone;
- try {
- clone = (OutputSettings) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
- clone.charset(charset.name()); // new charset and charset encoder
- clone.escapeMode = Entities.EscapeMode.valueOf(escapeMode.name());
- // indentAmount, prettyPrint are primitives so object.clone() will handle
- return clone;
- }
- }
-
- /**
- * Get the document's current output settings.
- * @return the document's current output settings.
- */
- public OutputSettings outputSettings() {
- return outputSettings;
- }
-
- public enum QuirksMode {
- noQuirks, quirks, limitedQuirks;
- }
-
- public QuirksMode quirksMode() {
- return quirksMode;
- }
-
- public Document quirksMode(QuirksMode quirksMode) {
- this.quirksMode = quirksMode;
- return this;
- }
-}
-
diff --git a/src/org/jsoup/nodes/DocumentType.java b/src/org/jsoup/nodes/DocumentType.java
deleted file mode 100644
index f8c79f0d18..0000000000
--- a/src/org/jsoup/nodes/DocumentType.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-
-/**
- * A {@code <!DOCTPYE>} node.
- */
-public class DocumentType extends Node {
- // todo: quirk mode from publicId and systemId
-
- /**
- * Create a new doctype element.
- * @param name the doctype's name
- * @param publicId the doctype's public ID
- * @param systemId the doctype's system ID
- * @param baseUri the doctype's base URI
- */
- public DocumentType(String name, String publicId, String systemId, String baseUri) {
- super(baseUri);
-
- Validate.notEmpty(name);
- attr("name", name);
- attr("publicId", publicId);
- attr("systemId", systemId);
- }
-
- @Override
- public String nodeName() {
- return "#doctype";
- }
-
- @Override
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- accum.append("<!DOCTYPE ").append(attr("name"));
- if (!StringUtil.isBlank(attr("publicId")))
- accum.append(" PUBLIC \"").append(attr("publicId")).append("\"");
- if (!StringUtil.isBlank(attr("systemId")))
- accum.append(" \"").append(attr("systemId")).append("\"");
- accum.append('>');
- }
-
- @Override
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {
- }
-}
diff --git a/src/org/jsoup/nodes/Element.java b/src/org/jsoup/nodes/Element.java
deleted file mode 100644
index 5c1894c934..0000000000
--- a/src/org/jsoup/nodes/Element.java
+++ /dev/null
@@ -1,1119 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-import org.jsoup.parser.Parser;
-import org.jsoup.parser.Tag;
-import org.jsoup.select.Collector;
-import org.jsoup.select.Elements;
-import org.jsoup.select.Evaluator;
-import org.jsoup.select.Selector;
-
-import java.util.*;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * A HTML element consists of a tag name, attributes, and child nodes (including text nodes and
- * other elements).
- *
- * From an Element, you can extract data, traverse the node graph, and manipulate the HTML.
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- */
-public class Element extends Node {
- private Tag tag;
- private Set<String> classNames;
-
- /**
- * Create a new, standalone Element. (Standalone in that is has no parent.)
- *
- * @param tag tag of this element
- * @param baseUri the base URI
- * @param attributes initial attributes
- * @see #appendChild(Node)
- * @see #appendElement(String)
- */
- public Element(Tag tag, String baseUri, Attributes attributes) {
- super(baseUri, attributes);
-
- Validate.notNull(tag);
- this.tag = tag;
- }
-
- /**
- * Create a new Element from a tag and a base URI.
- *
- * @param tag element tag
- * @param baseUri the base URI of this element. It is acceptable for the base URI to be an empty
- * string, but not null.
- * @see Tag#valueOf(String)
- */
- public Element(Tag tag, String baseUri) {
- this(tag, baseUri, new Attributes());
- }
-
- @Override
- public String nodeName() {
- return tag.getName();
- }
-
- /**
- * Get the name of the tag for this element. E.g. {@code div}
- *
- * @return the tag name
- */
- public String tagName() {
- return tag.getName();
- }
-
- /**
- * Change the tag of this element. For example, convert a {@code <span>} to a {@code <div>} with
- * {@code el.tagName("div");}.
- *
- * @param tagName new tag name for this element
- * @return this element, for chaining
- */
- public Element tagName(String tagName) {
- Validate.notEmpty(tagName, "Tag name must not be empty.");
- tag = Tag.valueOf(tagName);
- return this;
- }
-
- /**
- * Get the Tag for this element.
- *
- * @return the tag object
- */
- public Tag tag() {
- return tag;
- }
-
- /**
- * Test if this element is a block-level element. (E.g. {@code <div> == true} or an inline element
- * {@code <p> == false}).
- *
- * @return true if block, false if not (and thus inline)
- */
- public boolean isBlock() {
- return tag.isBlock();
- }
-
- /**
- * Get the {@code id} attribute of this element.
- *
- * @return The id attribute, if present, or an empty string if not.
- */
- public String id() {
- String id = attr("id");
- return id == null ? "" : id;
- }
-
- /**
- * Set an attribute value on this element. If this element already has an attribute with the
- * key, its value is updated; otherwise, a new attribute is added.
- *
- * @return this element
- */
- public Element attr(String attributeKey, String attributeValue) {
- super.attr(attributeKey, attributeValue);
- return this;
- }
-
- /**
- * Get this element's HTML5 custom data attributes. Each attribute in the element that has a key
- * starting with "data-" is included the dataset.
- * <p>
- * E.g., the element {@code <div data-package="jsoup" data-language="Java" class="group">...} has the dataset
- * {@code package=jsoup, language=java}.
- * <p>
- * This map is a filtered view of the element's attribute map. Changes to one map (add, remove, update) are reflected
- * in the other map.
- * <p>
- * You can find elements that have data attributes using the {@code [^data-]} attribute key prefix selector.
- * @return a map of {@code key=value} custom data attributes.
- */
- public Map<String, String> dataset() {
- return attributes.dataset();
- }
-
- @Override
- public final Element parent() {
- return (Element) parentNode;
- }
-
- /**
- * Get this element's parent and ancestors, up to the document root.
- * @return this element's stack of parents, closest first.
- */
- public Elements parents() {
- Elements parents = new Elements();
- accumulateParents(this, parents);
- return parents;
- }
-
- private static void accumulateParents(Element el, Elements parents) {
- Element parent = el.parent();
- if (parent != null && !parent.tagName().equals("#root")) {
- parents.add(parent);
- accumulateParents(parent, parents);
- }
- }
-
- /**
- * Get a child element of this element, by its 0-based index number.
- * <p/>
- * Note that an element can have both mixed Nodes and Elements as children. This method inspects
- * a filtered list of children that are elements, and the index is based on that filtered list.
- *
- * @param index the index number of the element to retrieve
- * @return the child element, if it exists, or {@code null} if absent.
- * @see #childNode(int)
- */
- public Element child(int index) {
- return children().get(index);
- }
-
- /**
- * Get this element's child elements.
- * <p/>
- * This is effectively a filter on {@link #childNodes()} to get Element nodes.
- * @return child elements. If this element has no children, returns an
- * empty list.
- * @see #childNodes()
- */
- public Elements children() {
- // create on the fly rather than maintaining two lists. if gets slow, memoize, and mark dirty on change
- List<Element> elements = new ArrayList<Element>();
- for (Node node : childNodes) {
- if (node instanceof Element)
- elements.add((Element) node);
- }
- return new Elements(elements);
- }
-
- /**
- * Get this element's child text nodes. The list is unmodifiable but the text nodes may be manipulated.
- * <p/>
- * This is effectively a filter on {@link #childNodes()} to get Text nodes.
- * @return child text nodes. If this element has no text nodes, returns an
- * empty list.
- * <p/>
- * For example, with the input HTML: {@code <p>One <span>Two</span> Three <br> Four</p>} with the {@code p} element selected:
- * <ul>
- * <li>{@code p.text()} = {@code "One Two Three Four"}</li>
- * <li>{@code p.ownText()} = {@code "One Three Four"}</li>
- * <li>{@code p.children()} = {@code Elements[<span>, <br>]}</li>
- * <li>{@code p.childNodes()} = {@code List<Node>["One ", <span>, " Three ", <br>, " Four"]}</li>
- * <li>{@code p.textNodes()} = {@code List<TextNode>["One ", " Three ", " Four"]}</li>
- * </ul>
- */
- public List<TextNode> textNodes() {
- List<TextNode> textNodes = new ArrayList<TextNode>();
- for (Node node : childNodes) {
- if (node instanceof TextNode)
- textNodes.add((TextNode) node);
- }
- return Collections.unmodifiableList(textNodes);
- }
-
- /**
- * Get this element's child data nodes. The list is unmodifiable but the data nodes may be manipulated.
- * <p/>
- * This is effectively a filter on {@link #childNodes()} to get Data nodes.
- * @return child data nodes. If this element has no data nodes, returns an
- * empty list.
- * @see #data()
- */
- public List<DataNode> dataNodes() {
- List<DataNode> dataNodes = new ArrayList<DataNode>();
- for (Node node : childNodes) {
- if (node instanceof DataNode)
- dataNodes.add((DataNode) node);
- }
- return Collections.unmodifiableList(dataNodes);
- }
-
- /**
- * Find elements that match the {@link Selector} CSS query, with this element as the starting context. Matched elements
- * may include this element, or any of its children.
- * <p/>
- * This method is generally more powerful to use than the DOM-type {@code getElementBy*} methods, because
- * multiple filters can be combined, e.g.:
- * <ul>
- * <li>{@code el.select("a[href]")} - finds links ({@code a} tags with {@code href} attributes)
- * <li>{@code el.select("a[href*=example.com]")} - finds links pointing to example.com (loosely)
- * </ul>
- * <p/>
- * See the query syntax documentation in {@link org.jsoup.select.Selector}.
- *
- * @param cssQuery a {@link Selector} CSS-like query
- * @return elements that match the query (empty if none match)
- * @see org.jsoup.select.Selector
- */
- public Elements select(String cssQuery) {
- return Selector.select(cssQuery, this);
- }
-
- /**
- * Add a node child node to this element.
- *
- * @param child node to add. Must not already have a parent.
- * @return this element, so that you can add more child nodes or elements.
- */
- public Element appendChild(Node child) {
- Validate.notNull(child);
-
- addChildren(child);
- return this;
- }
-
- /**
- * Add a node to the start of this element's children.
- *
- * @param child node to add. Must not already have a parent.
- * @return this element, so that you can add more child nodes or elements.
- */
- public Element prependChild(Node child) {
- Validate.notNull(child);
-
- addChildren(0, child);
- return this;
- }
-
- /**
- * Create a new element by tag name, and add it as the last child.
- *
- * @param tagName the name of the tag (e.g. {@code div}).
- * @return the new element, to allow you to add content to it, e.g.:
- * {@code parent.appendElement("h1").attr("id", "header").text("Welcome");}
- */
- public Element appendElement(String tagName) {
- Element child = new Element(Tag.valueOf(tagName), baseUri());
- appendChild(child);
- return child;
- }
-
- /**
- * Create a new element by tag name, and add it as the first child.
- *
- * @param tagName the name of the tag (e.g. {@code div}).
- * @return the new element, to allow you to add content to it, e.g.:
- * {@code parent.prependElement("h1").attr("id", "header").text("Welcome");}
- */
- public Element prependElement(String tagName) {
- Element child = new Element(Tag.valueOf(tagName), baseUri());
- prependChild(child);
- return child;
- }
-
- /**
- * Create and append a new TextNode to this element.
- *
- * @param text the unencoded text to add
- * @return this element
- */
- public Element appendText(String text) {
- TextNode node = new TextNode(text, baseUri());
- appendChild(node);
- return this;
- }
-
- /**
- * Create and prepend a new TextNode to this element.
- *
- * @param text the unencoded text to add
- * @return this element
- */
- public Element prependText(String text) {
- TextNode node = new TextNode(text, baseUri());
- prependChild(node);
- return this;
- }
-
- /**
- * Add inner HTML to this element. The supplied HTML will be parsed, and each node appended to the end of the children.
- * @param html HTML to add inside this element, after the existing HTML
- * @return this element
- * @see #html(String)
- */
- public Element append(String html) {
- Validate.notNull(html);
-
- List<Node> nodes = Parser.parseFragment(html, this, baseUri());
- addChildren(nodes.toArray(new Node[nodes.size()]));
- return this;
- }
-
- /**
- * Add inner HTML into this element. The supplied HTML will be parsed, and each node prepended to the start of the element's children.
- * @param html HTML to add inside this element, before the existing HTML
- * @return this element
- * @see #html(String)
- */
- public Element prepend(String html) {
- Validate.notNull(html);
-
- List<Node> nodes = Parser.parseFragment(html, this, baseUri());
- addChildren(0, nodes.toArray(new Node[nodes.size()]));
- return this;
- }
-
- /**
- * Insert the specified HTML into the DOM before this element (i.e. as a preceding sibling).
- *
- * @param html HTML to add before this element
- * @return this element, for chaining
- * @see #after(String)
- */
- @Override
- public Element before(String html) {
- return (Element) super.before(html);
- }
-
- /**
- * Insert the specified node into the DOM before this node (i.e. as a preceding sibling).
- * @param node to add before this element
- * @return this Element, for chaining
- * @see #after(Node)
- */
- @Override
- public Element before(Node node) {
- return (Element) super.before(node);
- }
-
- /**
- * Insert the specified HTML into the DOM after this element (i.e. as a following sibling).
- *
- * @param html HTML to add after this element
- * @return this element, for chaining
- * @see #before(String)
- */
- @Override
- public Element after(String html) {
- return (Element) super.after(html);
- }
-
- /**
- * Insert the specified node into the DOM after this node (i.e. as a following sibling).
- * @param node to add after this element
- * @return this element, for chaining
- * @see #before(Node)
- */
- @Override
- public Element after(Node node) {
- return (Element) super.after(node);
- }
-
- /**
- * Remove all of the element's child nodes. Any attributes are left as-is.
- * @return this element
- */
- public Element empty() {
- childNodes.clear();
- return this;
- }
-
- /**
- * Wrap the supplied HTML around this element.
- *
- * @param html HTML to wrap around this element, e.g. {@code <div class="head"></div>}. Can be arbitrarily deep.
- * @return this element, for chaining.
- */
- @Override
- public Element wrap(String html) {
- return (Element) super.wrap(html);
- }
-
- /**
- * Get sibling elements. If the element has no sibling elements, returns an empty list. An element is not a sibling
- * of itself, so will not be included in the returned list.
- * @return sibling elements
- */
- public Elements siblingElements() {
- if (parentNode == null)
- return new Elements(0);
-
- List<Element> elements = parent().children();
- Elements siblings = new Elements(elements.size() - 1);
- for (Element el: elements)
- if (el != this)
- siblings.add(el);
- return siblings;
- }
-
- /**
- * Gets the next sibling element of this element. E.g., if a {@code div} contains two {@code p}s,
- * the {@code nextElementSibling} of the first {@code p} is the second {@code p}.
- * <p/>
- * This is similar to {@link #nextSibling()}, but specifically finds only Elements
- * @return the next element, or null if there is no next element
- * @see #previousElementSibling()
- */
- public Element nextElementSibling() {
- if (parentNode == null) return null;
- List<Element> siblings = parent().children();
- Integer index = indexInList(this, siblings);
- Validate.notNull(index);
- if (siblings.size() > index+1)
- return siblings.get(index+1);
- else
- return null;
- }
-
- /**
- * Gets the previous element sibling of this element.
- * @return the previous element, or null if there is no previous element
- * @see #nextElementSibling()
- */
- public Element previousElementSibling() {
- if (parentNode == null) return null;
- List<Element> siblings = parent().children();
- Integer index = indexInList(this, siblings);
- Validate.notNull(index);
- if (index > 0)
- return siblings.get(index-1);
- else
- return null;
- }
-
- /**
- * Gets the first element sibling of this element.
- * @return the first sibling that is an element (aka the parent's first element child)
- */
- public Element firstElementSibling() {
- // todo: should firstSibling() exclude this?
- List<Element> siblings = parent().children();
- return siblings.size() > 1 ? siblings.get(0) : null;
- }
-
- /**
- * Get the list index of this element in its element sibling list. I.e. if this is the first element
- * sibling, returns 0.
- * @return position in element sibling list
- */
- public Integer elementSiblingIndex() {
- if (parent() == null) return 0;
- return indexInList(this, parent().children());
- }
-
- /**
- * Gets the last element sibling of this element
- * @return the last sibling that is an element (aka the parent's last element child)
- */
- public Element lastElementSibling() {
- List<Element> siblings = parent().children();
- return siblings.size() > 1 ? siblings.get(siblings.size() - 1) : null;
- }
-
- private static <E extends Element> Integer indexInList(Element search, List<E> elements) {
- Validate.notNull(search);
- Validate.notNull(elements);
-
- for (int i = 0; i < elements.size(); i++) {
- E element = elements.get(i);
- if (element.equals(search))
- return i;
- }
- return null;
- }
-
- // DOM type methods
-
- /**
- * Finds elements, including and recursively under this element, with the specified tag name.
- * @param tagName The tag name to search for (case insensitively).
- * @return a matching unmodifiable list of elements. Will be empty if this element and none of its children match.
- */
- public Elements getElementsByTag(String tagName) {
- Validate.notEmpty(tagName);
- tagName = tagName.toLowerCase().trim();
-
- return Collector.collect(new Evaluator.Tag(tagName), this);
- }
-
- /**
- * Find an element by ID, including or under this element.
- * <p>
- * Note that this finds the first matching ID, starting with this element. If you search down from a different
- * starting point, it is possible to find a different element by ID. For unique element by ID within a Document,
- * use {@link Document#getElementById(String)}
- * @param id The ID to search for.
- * @return The first matching element by ID, starting with this element, or null if none found.
- */
- public Element getElementById(String id) {
- Validate.notEmpty(id);
-
- Elements elements = Collector.collect(new Evaluator.Id(id), this);
- if (elements.size() > 0)
- return elements.get(0);
- else
- return null;
- }
-
- /**
- * Find elements that have this class, including or under this element. Case insensitive.
- * <p>
- * Elements can have multiple classes (e.g. {@code <div class="header round first">}. This method
- * checks each class, so you can find the above with {@code el.getElementsByClass("header");}.
- *
- * @param className the name of the class to search for.
- * @return elements with the supplied class name, empty if none
- * @see #hasClass(String)
- * @see #classNames()
- */
- public Elements getElementsByClass(String className) {
- Validate.notEmpty(className);
-
- return Collector.collect(new Evaluator.Class(className), this);
- }
-
- /**
- * Find elements that have a named attribute set. Case insensitive.
- *
- * @param key name of the attribute, e.g. {@code href}
- * @return elements that have this attribute, empty if none
- */
- public Elements getElementsByAttribute(String key) {
- Validate.notEmpty(key);
- key = key.trim().toLowerCase();
-
- return Collector.collect(new Evaluator.Attribute(key), this);
- }
-
- /**
- * Find elements that have an attribute name starting with the supplied prefix. Use {@code data-} to find elements
- * that have HTML5 datasets.
- * @param keyPrefix name prefix of the attribute e.g. {@code data-}
- * @return elements that have attribute names that start with with the prefix, empty if none.
- */
- public Elements getElementsByAttributeStarting(String keyPrefix) {
- Validate.notEmpty(keyPrefix);
- keyPrefix = keyPrefix.trim().toLowerCase();
-
- return Collector.collect(new Evaluator.AttributeStarting(keyPrefix), this);
- }
-
- /**
- * Find elements that have an attribute with the specific value. Case insensitive.
- *
- * @param key name of the attribute
- * @param value value of the attribute
- * @return elements that have this attribute with this value, empty if none
- */
- public Elements getElementsByAttributeValue(String key, String value) {
- return Collector.collect(new Evaluator.AttributeWithValue(key, value), this);
- }
-
- /**
- * Find elements that either do not have this attribute, or have it with a different value. Case insensitive.
- *
- * @param key name of the attribute
- * @param value value of the attribute
- * @return elements that do not have a matching attribute
- */
- public Elements getElementsByAttributeValueNot(String key, String value) {
- return Collector.collect(new Evaluator.AttributeWithValueNot(key, value), this);
- }
-
- /**
- * Find elements that have attributes that start with the value prefix. Case insensitive.
- *
- * @param key name of the attribute
- * @param valuePrefix start of attribute value
- * @return elements that have attributes that start with the value prefix
- */
- public Elements getElementsByAttributeValueStarting(String key, String valuePrefix) {
- return Collector.collect(new Evaluator.AttributeWithValueStarting(key, valuePrefix), this);
- }
-
- /**
- * Find elements that have attributes that end with the value suffix. Case insensitive.
- *
- * @param key name of the attribute
- * @param valueSuffix end of the attribute value
- * @return elements that have attributes that end with the value suffix
- */
- public Elements getElementsByAttributeValueEnding(String key, String valueSuffix) {
- return Collector.collect(new Evaluator.AttributeWithValueEnding(key, valueSuffix), this);
- }
-
- /**
- * Find elements that have attributes whose value contains the match string. Case insensitive.
- *
- * @param key name of the attribute
- * @param match substring of value to search for
- * @return elements that have attributes containing this text
- */
- public Elements getElementsByAttributeValueContaining(String key, String match) {
- return Collector.collect(new Evaluator.AttributeWithValueContaining(key, match), this);
- }
-
- /**
- * Find elements that have attributes whose values match the supplied regular expression.
- * @param key name of the attribute
- * @param pattern compiled regular expression to match against attribute values
- * @return elements that have attributes matching this regular expression
- */
- public Elements getElementsByAttributeValueMatching(String key, Pattern pattern) {
- return Collector.collect(new Evaluator.AttributeWithValueMatching(key, pattern), this);
-
- }
-
- /**
- * Find elements that have attributes whose values match the supplied regular expression.
- * @param key name of the attribute
- * @param regex regular expression to match against attribute values. You can use <a href="http://java.sun.com/docs/books/tutorial/essential/regex/pattern.html#embedded">embedded flags</a> (such as (?i) and (?m) to control regex options.
- * @return elements that have attributes matching this regular expression
- */
- public Elements getElementsByAttributeValueMatching(String key, String regex) {
- Pattern pattern;
- try {
- pattern = Pattern.compile(regex);
- } catch (PatternSyntaxException e) {
- throw new IllegalArgumentException("Pattern syntax error: " + regex, e);
- }
- return getElementsByAttributeValueMatching(key, pattern);
- }
-
- /**
- * Find elements whose sibling index is less than the supplied index.
- * @param index 0-based index
- * @return elements less than index
- */
- public Elements getElementsByIndexLessThan(int index) {
- return Collector.collect(new Evaluator.IndexLessThan(index), this);
- }
-
- /**
- * Find elements whose sibling index is greater than the supplied index.
- * @param index 0-based index
- * @return elements greater than index
- */
- public Elements getElementsByIndexGreaterThan(int index) {
- return Collector.collect(new Evaluator.IndexGreaterThan(index), this);
- }
-
- /**
- * Find elements whose sibling index is equal to the supplied index.
- * @param index 0-based index
- * @return elements equal to index
- */
- public Elements getElementsByIndexEquals(int index) {
- return Collector.collect(new Evaluator.IndexEquals(index), this);
- }
-
- /**
- * Find elements that contain the specified string. The search is case insensitive. The text may appear directly
- * in the element, or in any of its descendants.
- * @param searchText to look for in the element's text
- * @return elements that contain the string, case insensitive.
- * @see Element#text()
- */
- public Elements getElementsContainingText(String searchText) {
- return Collector.collect(new Evaluator.ContainsText(searchText), this);
- }
-
- /**
- * Find elements that directly contain the specified string. The search is case insensitive. The text must appear directly
- * in the element, not in any of its descendants.
- * @param searchText to look for in the element's own text
- * @return elements that contain the string, case insensitive.
- * @see Element#ownText()
- */
- public Elements getElementsContainingOwnText(String searchText) {
- return Collector.collect(new Evaluator.ContainsOwnText(searchText), this);
- }
-
- /**
- * Find elements whose text matches the supplied regular expression.
- * @param pattern regular expression to match text against
- * @return elements matching the supplied regular expression.
- * @see Element#text()
- */
- public Elements getElementsMatchingText(Pattern pattern) {
- return Collector.collect(new Evaluator.Matches(pattern), this);
- }
-
- /**
- * Find elements whose text matches the supplied regular expression.
- * @param regex regular expression to match text against. You can use <a href="http://java.sun.com/docs/books/tutorial/essential/regex/pattern.html#embedded">embedded flags</a> (such as (?i) and (?m) to control regex options.
- * @return elements matching the supplied regular expression.
- * @see Element#text()
- */
- public Elements getElementsMatchingText(String regex) {
- Pattern pattern;
- try {
- pattern = Pattern.compile(regex);
- } catch (PatternSyntaxException e) {
- throw new IllegalArgumentException("Pattern syntax error: " + regex, e);
- }
- return getElementsMatchingText(pattern);
- }
-
- /**
- * Find elements whose own text matches the supplied regular expression.
- * @param pattern regular expression to match text against
- * @return elements matching the supplied regular expression.
- * @see Element#ownText()
- */
- public Elements getElementsMatchingOwnText(Pattern pattern) {
- return Collector.collect(new Evaluator.MatchesOwn(pattern), this);
- }
-
- /**
- * Find elements whose text matches the supplied regular expression.
- * @param regex regular expression to match text against. You can use <a href="http://java.sun.com/docs/books/tutorial/essential/regex/pattern.html#embedded">embedded flags</a> (such as (?i) and (?m) to control regex options.
- * @return elements matching the supplied regular expression.
- * @see Element#ownText()
- */
- public Elements getElementsMatchingOwnText(String regex) {
- Pattern pattern;
- try {
- pattern = Pattern.compile(regex);
- } catch (PatternSyntaxException e) {
- throw new IllegalArgumentException("Pattern syntax error: " + regex, e);
- }
- return getElementsMatchingOwnText(pattern);
- }
-
- /**
- * Find all elements under this element (including self, and children of children).
- *
- * @return all elements
- */
- public Elements getAllElements() {
- return Collector.collect(new Evaluator.AllElements(), this);
- }
-
- /**
- * Gets the combined text of this element and all its children.
- * <p>
- * For example, given HTML {@code <p>Hello <b>there</b> now!</p>}, {@code p.text()} returns {@code "Hello there now!"}
- *
- * @return unencoded text, or empty string if none.
- * @see #ownText()
- * @see #textNodes()
- */
- public String text() {
- StringBuilder sb = new StringBuilder();
- text(sb);
- return sb.toString().trim();
- }
-
- private void text(StringBuilder accum) {
- appendWhitespaceIfBr(this, accum);
-
- for (Node child : childNodes) {
- if (child instanceof TextNode) {
- TextNode textNode = (TextNode) child;
- appendNormalisedText(accum, textNode);
- } else if (child instanceof Element) {
- Element element = (Element) child;
- if (accum.length() > 0 && element.isBlock() && !TextNode.lastCharIsWhitespace(accum))
- accum.append(" ");
- element.text(accum);
- }
- }
- }
-
- /**
- * Gets the text owned by this element only; does not get the combined text of all children.
- * <p>
- * For example, given HTML {@code <p>Hello <b>there</b> now!</p>}, {@code p.ownText()} returns {@code "Hello now!"},
- * whereas {@code p.text()} returns {@code "Hello there now!"}.
- * Note that the text within the {@code b} element is not returned, as it is not a direct child of the {@code p} element.
- *
- * @return unencoded text, or empty string if none.
- * @see #text()
- * @see #textNodes()
- */
- public String ownText() {
- StringBuilder sb = new StringBuilder();
- ownText(sb);
- return sb.toString().trim();
- }
-
- private void ownText(StringBuilder accum) {
- for (Node child : childNodes) {
- if (child instanceof TextNode) {
- TextNode textNode = (TextNode) child;
- appendNormalisedText(accum, textNode);
- } else if (child instanceof Element) {
- appendWhitespaceIfBr((Element) child, accum);
- }
- }
- }
-
- private void appendNormalisedText(StringBuilder accum, TextNode textNode) {
- String text = textNode.getWholeText();
-
- if (!preserveWhitespace()) {
- text = TextNode.normaliseWhitespace(text);
- if (TextNode.lastCharIsWhitespace(accum))
- text = TextNode.stripLeadingWhitespace(text);
- }
- accum.append(text);
- }
-
- private static void appendWhitespaceIfBr(Element element, StringBuilder accum) {
- if (element.tag.getName().equals("br") && !TextNode.lastCharIsWhitespace(accum))
- accum.append(" ");
- }
-
- boolean preserveWhitespace() {
- return tag.preserveWhitespace() || parent() != null && parent().preserveWhitespace();
- }
-
- /**
- * Set the text of this element. Any existing contents (text or elements) will be cleared
- * @param text unencoded text
- * @return this element
- */
- public Element text(String text) {
- Validate.notNull(text);
-
- empty();
- TextNode textNode = new TextNode(text, baseUri);
- appendChild(textNode);
-
- return this;
- }
-
- /**
- Test if this element has any text content (that is not just whitespace).
- @return true if element has non-blank text content.
- */
- public boolean hasText() {
- for (Node child: childNodes) {
- if (child instanceof TextNode) {
- TextNode textNode = (TextNode) child;
- if (!textNode.isBlank())
- return true;
- } else if (child instanceof Element) {
- Element el = (Element) child;
- if (el.hasText())
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the combined data of this element. Data is e.g. the inside of a {@code script} tag.
- * @return the data, or empty string if none
- *
- * @see #dataNodes()
- */
- public String data() {
- StringBuilder sb = new StringBuilder();
-
- for (Node childNode : childNodes) {
- if (childNode instanceof DataNode) {
- DataNode data = (DataNode) childNode;
- sb.append(data.getWholeData());
- } else if (childNode instanceof Element) {
- Element element = (Element) childNode;
- String elementData = element.data();
- sb.append(elementData);
- }
- }
- return sb.toString();
- }
-
- /**
- * Gets the literal value of this element's "class" attribute, which may include multiple class names, space
- * separated. (E.g. on <code>&lt;div class="header gray"></code> returns, "<code>header gray</code>")
- * @return The literal class attribute, or <b>empty string</b> if no class attribute set.
- */
- public String className() {
- return attr("class");
- }
-
- /**
- * Get all of the element's class names. E.g. on element {@code <div class="header gray"}>},
- * returns a set of two elements {@code "header", "gray"}. Note that modifications to this set are not pushed to
- * the backing {@code class} attribute; use the {@link #classNames(java.util.Set)} method to persist them.
- * @return set of classnames, empty if no class attribute
- */
- public Set<String> classNames() {
- if (classNames == null) {
- String[] names = className().split("\\s+");
- classNames = new LinkedHashSet<String>(Arrays.asList(names));
- }
- return classNames;
- }
-
- /**
- Set the element's {@code class} attribute to the supplied class names.
- @param classNames set of classes
- @return this element, for chaining
- */
- public Element classNames(Set<String> classNames) {
- Validate.notNull(classNames);
- attributes.put("class", StringUtil.join(classNames, " "));
- return this;
- }
-
- /**
- * Tests if this element has a class. Case insensitive.
- * @param className name of class to check for
- * @return true if it does, false if not
- */
- public boolean hasClass(String className) {
- Set<String> classNames = classNames();
- for (String name : classNames) {
- if (className.equalsIgnoreCase(name))
- return true;
- }
- return false;
- }
-
- /**
- Add a class name to this element's {@code class} attribute.
- @param className class name to add
- @return this element
- */
- public Element addClass(String className) {
- Validate.notNull(className);
-
- Set<String> classes = classNames();
- classes.add(className);
- classNames(classes);
-
- return this;
- }
-
- /**
- Remove a class name from this element's {@code class} attribute.
- @param className class name to remove
- @return this element
- */
- public Element removeClass(String className) {
- Validate.notNull(className);
-
- Set<String> classes = classNames();
- classes.remove(className);
- classNames(classes);
-
- return this;
- }
-
- /**
- Toggle a class name on this element's {@code class} attribute: if present, remove it; otherwise add it.
- @param className class name to toggle
- @return this element
- */
- public Element toggleClass(String className) {
- Validate.notNull(className);
-
- Set<String> classes = classNames();
- if (classes.contains(className))
- classes.remove(className);
- else
- classes.add(className);
- classNames(classes);
-
- return this;
- }
-
- /**
- * Get the value of a form element (input, textarea, etc).
- * @return the value of the form element, or empty string if not set.
- */
- public String val() {
- if (tagName().equals("textarea"))
- return text();
- else
- return attr("value");
- }
-
- /**
- * Set the value of a form element (input, textarea, etc).
- * @param value value to set
- * @return this element (for chaining)
- */
- public Element val(String value) {
- if (tagName().equals("textarea"))
- text(value);
- else
- attr("value", value);
- return this;
- }
-
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- if (accum.length() > 0 && out.prettyPrint() && (tag.formatAsBlock() || (parent() != null && parent().tag().formatAsBlock())))
- indent(accum, depth, out);
- accum
- .append("<")
- .append(tagName());
- attributes.html(accum, out);
-
- if (childNodes.isEmpty() && tag.isSelfClosing())
- accum.append(" />");
- else
- accum.append(">");
- }
-
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {
- if (!(childNodes.isEmpty() && tag.isSelfClosing())) {
- if (out.prettyPrint() && !childNodes.isEmpty() && tag.formatAsBlock())
- indent(accum, depth, out);
- accum.append("</").append(tagName()).append(">");
- }
- }
-
- /**
- * Retrieves the element's inner HTML. E.g. on a {@code <div>} with one empty {@code <p>}, would return
- * {@code <p></p>}. (Whereas {@link #outerHtml()} would return {@code <div><p></p></div>}.)
- *
- * @return String of HTML.
- * @see #outerHtml()
- */
- public String html() {
- StringBuilder accum = new StringBuilder();
- html(accum);
- return accum.toString().trim();
- }
-
- private void html(StringBuilder accum) {
- for (Node node : childNodes)
- node.outerHtml(accum);
- }
-
- /**
- * Set this element's inner HTML. Clears the existing HTML first.
- * @param html HTML to parse and set into this element
- * @return this element
- * @see #append(String)
- */
- public Element html(String html) {
- empty();
- append(html);
- return this;
- }
-
- public String toString() {
- return outerHtml();
- }
-
- @Override
- public boolean equals(Object o) {
- return this == o;
- }
-
- @Override
- public int hashCode() {
- // todo: fixup, not very useful
- int result = super.hashCode();
- result = 31 * result + (tag != null ? tag.hashCode() : 0);
- return result;
- }
-
- @Override
- public Element clone() {
- Element clone = (Element) super.clone();
- clone.classNames(); // creates linked set of class names from class attribute
- return clone;
- }
-}
diff --git a/src/org/jsoup/nodes/Entities.java b/src/org/jsoup/nodes/Entities.java
deleted file mode 100644
index 0ae83e1fc0..0000000000
--- a/src/org/jsoup/nodes/Entities.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package org.jsoup.nodes;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.CharsetEncoder;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * HTML entities, and escape routines.
- * Source: <a href="http://www.w3.org/TR/html5/named-character-references.html#named-character-references">W3C HTML
- * named character references</a>.
- */
-public class Entities {
- public enum EscapeMode {
- /** Restricted entities suitable for XHTML output: lt, gt, amp, apos, and quot only. */
- xhtml(xhtmlByVal),
- /** Default HTML output entities. */
- base(baseByVal),
- /** Complete HTML entities. */
- extended(fullByVal);
-
- private Map<Character, String> map;
-
- EscapeMode(Map<Character, String> map) {
- this.map = map;
- }
-
- public Map<Character, String> getMap() {
- return map;
- }
- }
-
- private static final Map<String, Character> full;
- private static final Map<Character, String> xhtmlByVal;
- private static final Map<Character, String> baseByVal;
- private static final Map<Character, String> fullByVal;
- private static final Pattern unescapePattern = Pattern.compile("&(#(x|X)?([0-9a-fA-F]+)|[a-zA-Z]+\\d*);?");
- private static final Pattern strictUnescapePattern = Pattern.compile("&(#(x|X)?([0-9a-fA-F]+)|[a-zA-Z]+\\d*);");
-
- private Entities() {}
-
- /**
- * Check if the input is a known named entity
- * @param name the possible entity name (e.g. "lt" or "amp"
- * @return true if a known named entity
- */
- public static boolean isNamedEntity(String name) {
- return full.containsKey(name);
- }
-
- /**
- * Get the Character value of the named entity
- * @param name named entity (e.g. "lt" or "amp")
- * @return the Character value of the named entity (e.g. '<' or '&')
- */
- public static Character getCharacterByName(String name) {
- return full.get(name);
- }
-
- static String escape(String string, Document.OutputSettings out) {
- return escape(string, out.encoder(), out.escapeMode());
- }
-
- static String escape(String string, CharsetEncoder encoder, EscapeMode escapeMode) {
- StringBuilder accum = new StringBuilder(string.length() * 2);
- Map<Character, String> map = escapeMode.getMap();
-
- for (int pos = 0; pos < string.length(); pos++) {
- Character c = string.charAt(pos);
- if (map.containsKey(c))
- accum.append('&').append(map.get(c)).append(';');
- else if (encoder.canEncode(c))
- accum.append(c.charValue());
- else
- accum.append("&#").append((int) c).append(';');
- }
-
- return accum.toString();
- }
-
- static String unescape(String string) {
- return unescape(string, false);
- }
-
- /**
- * Unescape the input string.
- * @param string
- * @param strict if "strict" (that is, requires trailing ';' char, otherwise that's optional)
- * @return
- */
- static String unescape(String string, boolean strict) {
- // todo: change this method to use Tokeniser.consumeCharacterReference
- if (!string.contains("&"))
- return string;
-
- Matcher m = strict? strictUnescapePattern.matcher(string) : unescapePattern.matcher(string); // &(#(x|X)?([0-9a-fA-F]+)|[a-zA-Z]\\d*);?
- StringBuffer accum = new StringBuffer(string.length()); // pity matcher can't use stringbuilder, avoid syncs
- // todo: replace m.appendReplacement with own impl, so StringBuilder and quoteReplacement not required
-
- while (m.find()) {
- int charval = -1;
- String num = m.group(3);
- if (num != null) {
- try {
- int base = m.group(2) != null ? 16 : 10; // 2 is hex indicator
- charval = Integer.valueOf(num, base);
- } catch (NumberFormatException e) {
- } // skip
- } else {
- String name = m.group(1);
- if (full.containsKey(name))
- charval = full.get(name);
- }
-
- if (charval != -1 || charval > 0xFFFF) { // out of range
- String c = Character.toString((char) charval);
- m.appendReplacement(accum, Matcher.quoteReplacement(c));
- } else {
- m.appendReplacement(accum, Matcher.quoteReplacement(m.group(0))); // replace with original string
- }
- }
- m.appendTail(accum);
- return accum.toString();
- }
-
- // xhtml has restricted entities
- private static final Object[][] xhtmlArray = {
- {"quot", 0x00022},
- {"amp", 0x00026},
- {"apos", 0x00027},
- {"lt", 0x0003C},
- {"gt", 0x0003E}
- };
-
- static {
- xhtmlByVal = new HashMap<Character, String>();
- baseByVal = toCharacterKey(loadEntities("entities-base.properties")); // most common / default
- full = loadEntities("entities-full.properties"); // extended and overblown.
- fullByVal = toCharacterKey(full);
-
- for (Object[] entity : xhtmlArray) {
- Character c = Character.valueOf((char) ((Integer) entity[1]).intValue());
- xhtmlByVal.put(c, ((String) entity[0]));
- }
- }
-
- private static Map<String, Character> loadEntities(String filename) {
- Properties properties = new Properties();
- Map<String, Character> entities = new HashMap<String, Character>();
- try {
- InputStream in = Entities.class.getResourceAsStream(filename);
- properties.load(in);
- in.close();
- } catch (IOException e) {
- throw new MissingResourceException("Error loading entities resource: " + e.getMessage(), "Entities", filename);
- }
-
- for (Map.Entry entry: properties.entrySet()) {
- Character val = Character.valueOf((char) Integer.parseInt((String) entry.getValue(), 16));
- String name = (String) entry.getKey();
- entities.put(name, val);
- }
- return entities;
- }
-
- private static Map<Character, String> toCharacterKey(Map<String, Character> inMap) {
- Map<Character, String> outMap = new HashMap<Character, String>();
- for (Map.Entry<String, Character> entry: inMap.entrySet()) {
- Character character = entry.getValue();
- String name = entry.getKey();
-
- if (outMap.containsKey(character)) {
- // dupe, prefer the lower case version
- if (name.toLowerCase().equals(name))
- outMap.put(character, name);
- } else {
- outMap.put(character, name);
- }
- }
- return outMap;
- }
-}
diff --git a/src/org/jsoup/nodes/Node.java b/src/org/jsoup/nodes/Node.java
deleted file mode 100644
index eb2b40ee73..0000000000
--- a/src/org/jsoup/nodes/Node.java
+++ /dev/null
@@ -1,615 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-import org.jsoup.parser.Parser;
-import org.jsoup.select.NodeTraversor;
-import org.jsoup.select.NodeVisitor;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- The base, abstract Node model. Elements, Documents, Comments etc are all Node instances.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public abstract class Node implements Cloneable {
- Node parentNode;
- List<Node> childNodes;
- Attributes attributes;
- String baseUri;
- int siblingIndex;
-
- /**
- Create a new Node.
- @param baseUri base URI
- @param attributes attributes (not null, but may be empty)
- */
- protected Node(String baseUri, Attributes attributes) {
- Validate.notNull(baseUri);
- Validate.notNull(attributes);
-
- childNodes = new ArrayList<Node>(4);
- this.baseUri = baseUri.trim();
- this.attributes = attributes;
- }
-
- protected Node(String baseUri) {
- this(baseUri, new Attributes());
- }
-
- /**
- * Default constructor. Doesn't setup base uri, children, or attributes; use with caution.
- */
- protected Node() {
- childNodes = Collections.emptyList();
- attributes = null;
- }
-
- /**
- Get the node name of this node. Use for debugging purposes and not logic switching (for that, use instanceof).
- @return node name
- */
- public abstract String nodeName();
-
- /**
- * Get an attribute's value by its key.
- * <p/>
- * To get an absolute URL from an attribute that may be a relative URL, prefix the key with <code><b>abs</b></code>,
- * which is a shortcut to the {@link #absUrl} method.
- * E.g.: <blockquote><code>String url = a.attr("abs:href");</code></blockquote>
- * @param attributeKey The attribute key.
- * @return The attribute, or empty string if not present (to avoid nulls).
- * @see #attributes()
- * @see #hasAttr(String)
- * @see #absUrl(String)
- */
- public String attr(String attributeKey) {
- Validate.notNull(attributeKey);
-
- if (attributes.hasKey(attributeKey))
- return attributes.get(attributeKey);
- else if (attributeKey.toLowerCase().startsWith("abs:"))
- return absUrl(attributeKey.substring("abs:".length()));
- else return "";
- }
-
- /**
- * Get all of the element's attributes.
- * @return attributes (which implements iterable, in same order as presented in original HTML).
- */
- public Attributes attributes() {
- return attributes;
- }
-
- /**
- * Set an attribute (key=value). If the attribute already exists, it is replaced.
- * @param attributeKey The attribute key.
- * @param attributeValue The attribute value.
- * @return this (for chaining)
- */
- public Node attr(String attributeKey, String attributeValue) {
- attributes.put(attributeKey, attributeValue);
- return this;
- }
-
- /**
- * Test if this element has an attribute.
- * @param attributeKey The attribute key to check.
- * @return true if the attribute exists, false if not.
- */
- public boolean hasAttr(String attributeKey) {
- Validate.notNull(attributeKey);
-
- if (attributeKey.toLowerCase().startsWith("abs:")) {
- String key = attributeKey.substring("abs:".length());
- if (attributes.hasKey(key) && !absUrl(key).equals(""))
- return true;
- }
- return attributes.hasKey(attributeKey);
- }
-
- /**
- * Remove an attribute from this element.
- * @param attributeKey The attribute to remove.
- * @return this (for chaining)
- */
- public Node removeAttr(String attributeKey) {
- Validate.notNull(attributeKey);
- attributes.remove(attributeKey);
- return this;
- }
-
- /**
- Get the base URI of this node.
- @return base URI
- */
- public String baseUri() {
- return baseUri;
- }
-
- /**
- Update the base URI of this node and all of its descendants.
- @param baseUri base URI to set
- */
- public void setBaseUri(final String baseUri) {
- Validate.notNull(baseUri);
-
- traverse(new NodeVisitor() {
- public void head(Node node, int depth) {
- node.baseUri = baseUri;
- }
-
- public void tail(Node node, int depth) {
- }
- });
- }
-
- /**
- * Get an absolute URL from a URL attribute that may be relative (i.e. an <code>&lt;a href></code> or
- * <code>&lt;img src></code>).
- * <p/>
- * E.g.: <code>String absUrl = linkEl.absUrl("href");</code>
- * <p/>
- * If the attribute value is already absolute (i.e. it starts with a protocol, like
- * <code>http://</code> or <code>https://</code> etc), and it successfully parses as a URL, the attribute is
- * returned directly. Otherwise, it is treated as a URL relative to the element's {@link #baseUri}, and made
- * absolute using that.
- * <p/>
- * As an alternate, you can use the {@link #attr} method with the <code>abs:</code> prefix, e.g.:
- * <code>String absUrl = linkEl.attr("abs:href");</code>
- *
- * @param attributeKey The attribute key
- * @return An absolute URL if one could be made, or an empty string (not null) if the attribute was missing or
- * could not be made successfully into a URL.
- * @see #attr
- * @see java.net.URL#URL(java.net.URL, String)
- */
- public String absUrl(String attributeKey) {
- Validate.notEmpty(attributeKey);
-
- String relUrl = attr(attributeKey);
- if (!hasAttr(attributeKey)) {
- return ""; // nothing to make absolute with
- } else {
- URL base;
- try {
- try {
- base = new URL(baseUri);
- } catch (MalformedURLException e) {
- // the base is unsuitable, but the attribute may be abs on its own, so try that
- URL abs = new URL(relUrl);
- return abs.toExternalForm();
- }
- // workaround: java resolves '//path/file + ?foo' to '//path/?foo', not '//path/file?foo' as desired
- if (relUrl.startsWith("?"))
- relUrl = base.getPath() + relUrl;
- URL abs = new URL(base, relUrl);
- return abs.toExternalForm();
- } catch (MalformedURLException e) {
- return "";
- }
- }
- }
-
- /**
- Get a child node by index
- @param index index of child node
- @return the child node at this index.
- */
- public Node childNode(int index) {
- return childNodes.get(index);
- }
-
- /**
- Get this node's children. Presented as an unmodifiable list: new children can not be added, but the child nodes
- themselves can be manipulated.
- @return list of children. If no children, returns an empty list.
- */
- public List<Node> childNodes() {
- return Collections.unmodifiableList(childNodes);
- }
-
- protected Node[] childNodesAsArray() {
- return childNodes.toArray(new Node[childNodes().size()]);
- }
-
- /**
- Gets this node's parent node.
- @return parent node; or null if no parent.
- */
- public Node parent() {
- return parentNode;
- }
-
- /**
- * Gets the Document associated with this Node.
- * @return the Document associated with this Node, or null if there is no such Document.
- */
- public Document ownerDocument() {
- if (this instanceof Document)
- return (Document) this;
- else if (parentNode == null)
- return null;
- else
- return parentNode.ownerDocument();
- }
-
- /**
- * Remove (delete) this node from the DOM tree. If this node has children, they are also removed.
- */
- public void remove() {
- Validate.notNull(parentNode);
- parentNode.removeChild(this);
- }
-
- /**
- * Insert the specified HTML into the DOM before this node (i.e. as a preceding sibling).
- * @param html HTML to add before this node
- * @return this node, for chaining
- * @see #after(String)
- */
- public Node before(String html) {
- addSiblingHtml(siblingIndex(), html);
- return this;
- }
-
- /**
- * Insert the specified node into the DOM before this node (i.e. as a preceding sibling).
- * @param node to add before this node
- * @return this node, for chaining
- * @see #after(Node)
- */
- public Node before(Node node) {
- Validate.notNull(node);
- Validate.notNull(parentNode);
-
- parentNode.addChildren(siblingIndex(), node);
- return this;
- }
-
- /**
- * Insert the specified HTML into the DOM after this node (i.e. as a following sibling).
- * @param html HTML to add after this node
- * @return this node, for chaining
- * @see #before(String)
- */
- public Node after(String html) {
- addSiblingHtml(siblingIndex()+1, html);
- return this;
- }
-
- /**
- * Insert the specified node into the DOM after this node (i.e. as a following sibling).
- * @param node to add after this node
- * @return this node, for chaining
- * @see #before(Node)
- */
- public Node after(Node node) {
- Validate.notNull(node);
- Validate.notNull(parentNode);
-
- parentNode.addChildren(siblingIndex()+1, node);
- return this;
- }
-
- private void addSiblingHtml(int index, String html) {
- Validate.notNull(html);
- Validate.notNull(parentNode);
-
- Element context = parent() instanceof Element ? (Element) parent() : null;
- List<Node> nodes = Parser.parseFragment(html, context, baseUri());
- parentNode.addChildren(index, nodes.toArray(new Node[nodes.size()]));
- }
-
- /**
- Wrap the supplied HTML around this node.
- @param html HTML to wrap around this element, e.g. {@code <div class="head"></div>}. Can be arbitrarily deep.
- @return this node, for chaining.
- */
- public Node wrap(String html) {
- Validate.notEmpty(html);
-
- Element context = parent() instanceof Element ? (Element) parent() : null;
- List<Node> wrapChildren = Parser.parseFragment(html, context, baseUri());
- Node wrapNode = wrapChildren.get(0);
- if (wrapNode == null || !(wrapNode instanceof Element)) // nothing to wrap with; noop
- return null;
-
- Element wrap = (Element) wrapNode;
- Element deepest = getDeepChild(wrap);
- parentNode.replaceChild(this, wrap);
- deepest.addChildren(this);
-
- // remainder (unbalanced wrap, like <div></div><p></p> -- The <p> is remainder
- if (wrapChildren.size() > 0) {
- for (int i = 0; i < wrapChildren.size(); i++) {
- Node remainder = wrapChildren.get(i);
- remainder.parentNode.removeChild(remainder);
- wrap.appendChild(remainder);
- }
- }
- return this;
- }
-
- /**
- * Removes this node from the DOM, and moves its children up into the node's parent. This has the effect of dropping
- * the node but keeping its children.
- * <p/>
- * For example, with the input html:<br/>
- * {@code <div>One <span>Two <b>Three</b></span></div>}<br/>
- * Calling {@code element.unwrap()} on the {@code span} element will result in the html:<br/>
- * {@code <div>One Two <b>Three</b></div>}<br/>
- * and the {@code "Two "} {@link TextNode} being returned.
- * @return the first child of this node, after the node has been unwrapped. Null if the node had no children.
- * @see #remove()
- * @see #wrap(String)
- */
- public Node unwrap() {
- Validate.notNull(parentNode);
-
- int index = siblingIndex;
- Node firstChild = childNodes.size() > 0 ? childNodes.get(0) : null;
- parentNode.addChildren(index, this.childNodesAsArray());
- this.remove();
-
- return firstChild;
- }
-
- private Element getDeepChild(Element el) {
- List<Element> children = el.children();
- if (children.size() > 0)
- return getDeepChild(children.get(0));
- else
- return el;
- }
-
- /**
- * Replace this node in the DOM with the supplied node.
- * @param in the node that will will replace the existing node.
- */
- public void replaceWith(Node in) {
- Validate.notNull(in);
- Validate.notNull(parentNode);
- parentNode.replaceChild(this, in);
- }
-
- protected void setParentNode(Node parentNode) {
- if (this.parentNode != null)
- this.parentNode.removeChild(this);
- this.parentNode = parentNode;
- }
-
- protected void replaceChild(Node out, Node in) {
- Validate.isTrue(out.parentNode == this);
- Validate.notNull(in);
- if (in.parentNode != null)
- in.parentNode.removeChild(in);
-
- Integer index = out.siblingIndex();
- childNodes.set(index, in);
- in.parentNode = this;
- in.setSiblingIndex(index);
- out.parentNode = null;
- }
-
- protected void removeChild(Node out) {
- Validate.isTrue(out.parentNode == this);
- int index = out.siblingIndex();
- childNodes.remove(index);
- reindexChildren();
- out.parentNode = null;
- }
-
- protected void addChildren(Node... children) {
- //most used. short circuit addChildren(int), which hits reindex children and array copy
- for (Node child: children) {
- reparentChild(child);
- childNodes.add(child);
- child.setSiblingIndex(childNodes.size()-1);
- }
- }
-
- protected void addChildren(int index, Node... children) {
- Validate.noNullElements(children);
- for (int i = children.length - 1; i >= 0; i--) {
- Node in = children[i];
- reparentChild(in);
- childNodes.add(index, in);
- }
- reindexChildren();
- }
-
- private void reparentChild(Node child) {
- if (child.parentNode != null)
- child.parentNode.removeChild(child);
- child.setParentNode(this);
- }
-
- private void reindexChildren() {
- for (int i = 0; i < childNodes.size(); i++) {
- childNodes.get(i).setSiblingIndex(i);
- }
- }
-
- /**
- Retrieves this node's sibling nodes. Similar to {@link #childNodes() node.parent.childNodes()}, but does not
- include this node (a node is not a sibling of itself).
- @return node siblings. If the node has no parent, returns an empty list.
- */
- public List<Node> siblingNodes() {
- if (parentNode == null)
- return Collections.emptyList();
-
- List<Node> nodes = parentNode.childNodes;
- List<Node> siblings = new ArrayList<Node>(nodes.size() - 1);
- for (Node node: nodes)
- if (node != this)
- siblings.add(node);
- return siblings;
- }
-
- /**
- Get this node's next sibling.
- @return next sibling, or null if this is the last sibling
- */
- public Node nextSibling() {
- if (parentNode == null)
- return null; // root
-
- List<Node> siblings = parentNode.childNodes;
- Integer index = siblingIndex();
- Validate.notNull(index);
- if (siblings.size() > index+1)
- return siblings.get(index+1);
- else
- return null;
- }
-
- /**
- Get this node's previous sibling.
- @return the previous sibling, or null if this is the first sibling
- */
- public Node previousSibling() {
- if (parentNode == null)
- return null; // root
-
- List<Node> siblings = parentNode.childNodes;
- Integer index = siblingIndex();
- Validate.notNull(index);
- if (index > 0)
- return siblings.get(index-1);
- else
- return null;
- }
-
- /**
- * Get the list index of this node in its node sibling list. I.e. if this is the first node
- * sibling, returns 0.
- * @return position in node sibling list
- * @see org.jsoup.nodes.Element#elementSiblingIndex()
- */
- public int siblingIndex() {
- return siblingIndex;
- }
-
- protected void setSiblingIndex(int siblingIndex) {
- this.siblingIndex = siblingIndex;
- }
-
- /**
- * Perform a depth-first traversal through this node and its descendants.
- * @param nodeVisitor the visitor callbacks to perform on each node
- * @return this node, for chaining
- */
- public Node traverse(NodeVisitor nodeVisitor) {
- Validate.notNull(nodeVisitor);
- NodeTraversor traversor = new NodeTraversor(nodeVisitor);
- traversor.traverse(this);
- return this;
- }
-
- /**
- Get the outer HTML of this node.
- @return HTML
- */
- public String outerHtml() {
- StringBuilder accum = new StringBuilder(128);
- outerHtml(accum);
- return accum.toString();
- }
-
- protected void outerHtml(StringBuilder accum) {
- new NodeTraversor(new OuterHtmlVisitor(accum, getOutputSettings())).traverse(this);
- }
-
- // if this node has no document (or parent), retrieve the default output settings
- private Document.OutputSettings getOutputSettings() {
- return ownerDocument() != null ? ownerDocument().outputSettings() : (new Document("")).outputSettings();
- }
-
- /**
- Get the outer HTML of this node.
- @param accum accumulator to place HTML into
- */
- abstract void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out);
-
- abstract void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out);
-
- public String toString() {
- return outerHtml();
- }
-
- protected void indent(StringBuilder accum, int depth, Document.OutputSettings out) {
- accum.append("\n").append(StringUtil.padding(depth * out.indentAmount()));
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- // todo: have nodes hold a child index, compare against that and parent (not children)
- return false;
- }
-
- @Override
- public int hashCode() {
- int result = parentNode != null ? parentNode.hashCode() : 0;
- // not children, or will block stack as they go back up to parent)
- result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
- return result;
- }
-
- /**
- * Create a stand-alone, deep copy of this node, and all of its children. The cloned node will have no siblings or
- * parent node. As a stand-alone object, any changes made to the clone or any of its children will not impact the
- * original node.
- * <p>
- * The cloned node may be adopted into another Document or node structure using {@link Element#appendChild(Node)}.
- * @return stand-alone cloned node
- */
- @Override
- public Node clone() {
- return doClone(null); // splits for orphan
- }
-
- protected Node doClone(Node parent) {
- Node clone;
- try {
- clone = (Node) super.clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException(e);
- }
-
- clone.parentNode = parent; // can be null, to create an orphan split
- clone.siblingIndex = parent == null ? 0 : siblingIndex;
- clone.attributes = attributes != null ? attributes.clone() : null;
- clone.baseUri = baseUri;
- clone.childNodes = new ArrayList<Node>(childNodes.size());
- for (Node child: childNodes)
- clone.childNodes.add(child.doClone(clone)); // clone() creates orphans, doClone() keeps parent
-
- return clone;
- }
-
- private static class OuterHtmlVisitor implements NodeVisitor {
- private StringBuilder accum;
- private Document.OutputSettings out;
-
- OuterHtmlVisitor(StringBuilder accum, Document.OutputSettings out) {
- this.accum = accum;
- this.out = out;
- }
-
- public void head(Node node, int depth) {
- node.outerHtmlHead(accum, depth, out);
- }
-
- public void tail(Node node, int depth) {
- if (!node.nodeName().equals("#text")) // saves a void hit.
- node.outerHtmlTail(accum, depth, out);
- }
- }
-}
diff --git a/src/org/jsoup/nodes/TextNode.java b/src/org/jsoup/nodes/TextNode.java
deleted file mode 100644
index 9fd0feac8f..0000000000
--- a/src/org/jsoup/nodes/TextNode.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.jsoup.nodes;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-
-/**
- A text node.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class TextNode extends Node {
- /*
- TextNode is a node, and so by default comes with attributes and children. The attributes are seldom used, but use
- memory, and the child nodes are never used. So we don't have them, and override accessors to attributes to create
- them as needed on the fly.
- */
- private static final String TEXT_KEY = "text";
- String text;
-
- /**
- Create a new TextNode representing the supplied (unencoded) text).
-
- @param text raw text
- @param baseUri base uri
- @see #createFromEncoded(String, String)
- */
- public TextNode(String text, String baseUri) {
- this.baseUri = baseUri;
- this.text = text;
- }
-
- public String nodeName() {
- return "#text";
- }
-
- /**
- * Get the text content of this text node.
- * @return Unencoded, normalised text.
- * @see TextNode#getWholeText()
- */
- public String text() {
- return normaliseWhitespace(getWholeText());
- }
-
- /**
- * Set the text content of this text node.
- * @param text unencoded text
- * @return this, for chaining
- */
- public TextNode text(String text) {
- this.text = text;
- if (attributes != null)
- attributes.put(TEXT_KEY, text);
- return this;
- }
-
- /**
- Get the (unencoded) text of this text node, including any newlines and spaces present in the original.
- @return text
- */
- public String getWholeText() {
- return attributes == null ? text : attributes.get(TEXT_KEY);
- }
-
- /**
- Test if this text node is blank -- that is, empty or only whitespace (including newlines).
- @return true if this document is empty or only whitespace, false if it contains any text content.
- */
- public boolean isBlank() {
- return StringUtil.isBlank(getWholeText());
- }
-
- /**
- * Split this text node into two nodes at the specified string offset. After splitting, this node will contain the
- * original text up to the offset, and will have a new text node sibling containing the text after the offset.
- * @param offset string offset point to split node at.
- * @return the newly created text node containing the text after the offset.
- */
- public TextNode splitText(int offset) {
- Validate.isTrue(offset >= 0, "Split offset must be not be negative");
- Validate.isTrue(offset < text.length(), "Split offset must not be greater than current text length");
-
- String head = getWholeText().substring(0, offset);
- String tail = getWholeText().substring(offset);
- text(head);
- TextNode tailNode = new TextNode(tail, this.baseUri());
- if (parent() != null)
- parent().addChildren(siblingIndex()+1, tailNode);
-
- return tailNode;
- }
-
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- String html = Entities.escape(getWholeText(), out);
- if (out.prettyPrint() && parent() instanceof Element && !((Element) parent()).preserveWhitespace()) {
- html = normaliseWhitespace(html);
- }
-
- if (out.prettyPrint() && siblingIndex() == 0 && parentNode instanceof Element && ((Element) parentNode).tag().formatAsBlock() && !isBlank())
- indent(accum, depth, out);
- accum.append(html);
- }
-
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {}
-
- public String toString() {
- return outerHtml();
- }
-
- /**
- * Create a new TextNode from HTML encoded (aka escaped) data.
- * @param encodedText Text containing encoded HTML (e.g. &amp;lt;)
- * @return TextNode containing unencoded data (e.g. &lt;)
- */
- public static TextNode createFromEncoded(String encodedText, String baseUri) {
- String text = Entities.unescape(encodedText);
- return new TextNode(text, baseUri);
- }
-
- static String normaliseWhitespace(String text) {
- text = StringUtil.normaliseWhitespace(text);
- return text;
- }
-
- static String stripLeadingWhitespace(String text) {
- return text.replaceFirst("^\\s+", "");
- }
-
- static boolean lastCharIsWhitespace(StringBuilder sb) {
- return sb.length() != 0 && sb.charAt(sb.length() - 1) == ' ';
- }
-
- // attribute fiddling. create on first access.
- private void ensureAttributes() {
- if (attributes == null) {
- attributes = new Attributes();
- attributes.put(TEXT_KEY, text);
- }
- }
-
- @Override
- public String attr(String attributeKey) {
- ensureAttributes();
- return super.attr(attributeKey);
- }
-
- @Override
- public Attributes attributes() {
- ensureAttributes();
- return super.attributes();
- }
-
- @Override
- public Node attr(String attributeKey, String attributeValue) {
- ensureAttributes();
- return super.attr(attributeKey, attributeValue);
- }
-
- @Override
- public boolean hasAttr(String attributeKey) {
- ensureAttributes();
- return super.hasAttr(attributeKey);
- }
-
- @Override
- public Node removeAttr(String attributeKey) {
- ensureAttributes();
- return super.removeAttr(attributeKey);
- }
-
- @Override
- public String absUrl(String attributeKey) {
- ensureAttributes();
- return super.absUrl(attributeKey);
- }
-}
diff --git a/src/org/jsoup/nodes/XmlDeclaration.java b/src/org/jsoup/nodes/XmlDeclaration.java
deleted file mode 100644
index 80d4a0152f..0000000000
--- a/src/org/jsoup/nodes/XmlDeclaration.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.jsoup.nodes;
-
-/**
- An XML Declaration.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class XmlDeclaration extends Node {
- private static final String DECL_KEY = "declaration";
- private final boolean isProcessingInstruction; // <! if true, <? if false, declaration (and last data char should be ?)
-
- /**
- Create a new XML declaration
- @param data data
- @param baseUri base uri
- @param isProcessingInstruction is processing instruction
- */
- public XmlDeclaration(String data, String baseUri, boolean isProcessingInstruction) {
- super(baseUri);
- attributes.put(DECL_KEY, data);
- this.isProcessingInstruction = isProcessingInstruction;
- }
-
- public String nodeName() {
- return "#declaration";
- }
-
- /**
- Get the unencoded XML declaration.
- @return XML declaration
- */
- public String getWholeDeclaration() {
- return attributes.get(DECL_KEY);
- }
-
- void outerHtmlHead(StringBuilder accum, int depth, Document.OutputSettings out) {
- accum
- .append("<")
- .append(isProcessingInstruction ? "!" : "?")
- .append(getWholeDeclaration())
- .append(">");
- }
-
- void outerHtmlTail(StringBuilder accum, int depth, Document.OutputSettings out) {}
-
- public String toString() {
- return outerHtml();
- }
-}
diff --git a/src/org/jsoup/nodes/entities-base.properties b/src/org/jsoup/nodes/entities-base.properties
deleted file mode 100644
index 3d1d11e6c4..0000000000
--- a/src/org/jsoup/nodes/entities-base.properties
+++ /dev/null
@@ -1,106 +0,0 @@
-AElig=000C6
-AMP=00026
-Aacute=000C1
-Acirc=000C2
-Agrave=000C0
-Aring=000C5
-Atilde=000C3
-Auml=000C4
-COPY=000A9
-Ccedil=000C7
-ETH=000D0
-Eacute=000C9
-Ecirc=000CA
-Egrave=000C8
-Euml=000CB
-GT=0003E
-Iacute=000CD
-Icirc=000CE
-Igrave=000CC
-Iuml=000CF
-LT=0003C
-Ntilde=000D1
-Oacute=000D3
-Ocirc=000D4
-Ograve=000D2
-Oslash=000D8
-Otilde=000D5
-Ouml=000D6
-QUOT=00022
-REG=000AE
-THORN=000DE
-Uacute=000DA
-Ucirc=000DB
-Ugrave=000D9
-Uuml=000DC
-Yacute=000DD
-aacute=000E1
-acirc=000E2
-acute=000B4
-aelig=000E6
-agrave=000E0
-amp=00026
-aring=000E5
-atilde=000E3
-auml=000E4
-brvbar=000A6
-ccedil=000E7
-cedil=000B8
-cent=000A2
-copy=000A9
-curren=000A4
-deg=000B0
-divide=000F7
-eacute=000E9
-ecirc=000EA
-egrave=000E8
-eth=000F0
-euml=000EB
-frac12=000BD
-frac14=000BC
-frac34=000BE
-gt=0003E
-iacute=000ED
-icirc=000EE
-iexcl=000A1
-igrave=000EC
-iquest=000BF
-iuml=000EF
-laquo=000AB
-lt=0003C
-macr=000AF
-micro=000B5
-middot=000B7
-nbsp=000A0
-not=000AC
-ntilde=000F1
-oacute=000F3
-ocirc=000F4
-ograve=000F2
-ordf=000AA
-ordm=000BA
-oslash=000F8
-otilde=000F5
-ouml=000F6
-para=000B6
-plusmn=000B1
-pound=000A3
-quot=00022
-raquo=000BB
-reg=000AE
-sect=000A7
-shy=000AD
-sup1=000B9
-sup2=000B2
-sup3=000B3
-szlig=000DF
-thorn=000FE
-times=000D7
-uacute=000FA
-ucirc=000FB
-ugrave=000F9
-uml=000A8
-uuml=000FC
-yacute=000FD
-yen=000A5
-yuml=000FF
diff --git a/src/org/jsoup/nodes/entities-full.properties b/src/org/jsoup/nodes/entities-full.properties
deleted file mode 100644
index 92f124f408..0000000000
--- a/src/org/jsoup/nodes/entities-full.properties
+++ /dev/null
@@ -1,2032 +0,0 @@
-AElig=000C6
-AMP=00026
-Aacute=000C1
-Abreve=00102
-Acirc=000C2
-Acy=00410
-Afr=1D504
-Agrave=000C0
-Alpha=00391
-Amacr=00100
-And=02A53
-Aogon=00104
-Aopf=1D538
-ApplyFunction=02061
-Aring=000C5
-Ascr=1D49C
-Assign=02254
-Atilde=000C3
-Auml=000C4
-Backslash=02216
-Barv=02AE7
-Barwed=02306
-Bcy=00411
-Because=02235
-Bernoullis=0212C
-Beta=00392
-Bfr=1D505
-Bopf=1D539
-Breve=002D8
-Bscr=0212C
-Bumpeq=0224E
-CHcy=00427
-COPY=000A9
-Cacute=00106
-Cap=022D2
-CapitalDifferentialD=02145
-Cayleys=0212D
-Ccaron=0010C
-Ccedil=000C7
-Ccirc=00108
-Cconint=02230
-Cdot=0010A
-Cedilla=000B8
-CenterDot=000B7
-Cfr=0212D
-Chi=003A7
-CircleDot=02299
-CircleMinus=02296
-CirclePlus=02295
-CircleTimes=02297
-ClockwiseContourIntegral=02232
-CloseCurlyDoubleQuote=0201D
-CloseCurlyQuote=02019
-Colon=02237
-Colone=02A74
-Congruent=02261
-Conint=0222F
-ContourIntegral=0222E
-Copf=02102
-Coproduct=02210
-CounterClockwiseContourIntegral=02233
-Cross=02A2F
-Cscr=1D49E
-Cup=022D3
-CupCap=0224D
-DD=02145
-DDotrahd=02911
-DJcy=00402
-DScy=00405
-DZcy=0040F
-Dagger=02021
-Darr=021A1
-Dashv=02AE4
-Dcaron=0010E
-Dcy=00414
-Del=02207
-Delta=00394
-Dfr=1D507
-DiacriticalAcute=000B4
-DiacriticalDot=002D9
-DiacriticalDoubleAcute=002DD
-DiacriticalGrave=00060
-DiacriticalTilde=002DC
-Diamond=022C4
-DifferentialD=02146
-Dopf=1D53B
-Dot=000A8
-DotDot=020DC
-DotEqual=02250
-DoubleContourIntegral=0222F
-DoubleDot=000A8
-DoubleDownArrow=021D3
-DoubleLeftArrow=021D0
-DoubleLeftRightArrow=021D4
-DoubleLeftTee=02AE4
-DoubleLongLeftArrow=027F8
-DoubleLongLeftRightArrow=027FA
-DoubleLongRightArrow=027F9
-DoubleRightArrow=021D2
-DoubleRightTee=022A8
-DoubleUpArrow=021D1
-DoubleUpDownArrow=021D5
-DoubleVerticalBar=02225
-DownArrow=02193
-DownArrowBar=02913
-DownArrowUpArrow=021F5
-DownBreve=00311
-DownLeftRightVector=02950
-DownLeftTeeVector=0295E
-DownLeftVector=021BD
-DownLeftVectorBar=02956
-DownRightTeeVector=0295F
-DownRightVector=021C1
-DownRightVectorBar=02957
-DownTee=022A4
-DownTeeArrow=021A7
-Downarrow=021D3
-Dscr=1D49F
-Dstrok=00110
-ENG=0014A
-ETH=000D0
-Eacute=000C9
-Ecaron=0011A
-Ecirc=000CA
-Ecy=0042D
-Edot=00116
-Efr=1D508
-Egrave=000C8
-Element=02208
-Emacr=00112
-EmptySmallSquare=025FB
-EmptyVerySmallSquare=025AB
-Eogon=00118
-Eopf=1D53C
-Epsilon=00395
-Equal=02A75
-EqualTilde=02242
-Equilibrium=021CC
-Escr=02130
-Esim=02A73
-Eta=00397
-Euml=000CB
-Exists=02203
-ExponentialE=02147
-Fcy=00424
-Ffr=1D509
-FilledSmallSquare=025FC
-FilledVerySmallSquare=025AA
-Fopf=1D53D
-ForAll=02200
-Fouriertrf=02131
-Fscr=02131
-GJcy=00403
-GT=0003E
-Gamma=00393
-Gammad=003DC
-Gbreve=0011E
-Gcedil=00122
-Gcirc=0011C
-Gcy=00413
-Gdot=00120
-Gfr=1D50A
-Gg=022D9
-Gopf=1D53E
-GreaterEqual=02265
-GreaterEqualLess=022DB
-GreaterFullEqual=02267
-GreaterGreater=02AA2
-GreaterLess=02277
-GreaterSlantEqual=02A7E
-GreaterTilde=02273
-Gscr=1D4A2
-Gt=0226B
-HARDcy=0042A
-Hacek=002C7
-Hat=0005E
-Hcirc=00124
-Hfr=0210C
-HilbertSpace=0210B
-Hopf=0210D
-HorizontalLine=02500
-Hscr=0210B
-Hstrok=00126
-HumpDownHump=0224E
-HumpEqual=0224F
-IEcy=00415
-IJlig=00132
-IOcy=00401
-Iacute=000CD
-Icirc=000CE
-Icy=00418
-Idot=00130
-Ifr=02111
-Igrave=000CC
-Im=02111
-Imacr=0012A
-ImaginaryI=02148
-Implies=021D2
-Int=0222C
-Integral=0222B
-Intersection=022C2
-InvisibleComma=02063
-InvisibleTimes=02062
-Iogon=0012E
-Iopf=1D540
-Iota=00399
-Iscr=02110
-Itilde=00128
-Iukcy=00406
-Iuml=000CF
-Jcirc=00134
-Jcy=00419
-Jfr=1D50D
-Jopf=1D541
-Jscr=1D4A5
-Jsercy=00408
-Jukcy=00404
-KHcy=00425
-KJcy=0040C
-Kappa=0039A
-Kcedil=00136
-Kcy=0041A
-Kfr=1D50E
-Kopf=1D542
-Kscr=1D4A6
-LJcy=00409
-LT=0003C
-Lacute=00139
-Lambda=0039B
-Lang=027EA
-Laplacetrf=02112
-Larr=0219E
-Lcaron=0013D
-Lcedil=0013B
-Lcy=0041B
-LeftAngleBracket=027E8
-LeftArrow=02190
-LeftArrowBar=021E4
-LeftArrowRightArrow=021C6
-LeftCeiling=02308
-LeftDoubleBracket=027E6
-LeftDownTeeVector=02961
-LeftDownVector=021C3
-LeftDownVectorBar=02959
-LeftFloor=0230A
-LeftRightArrow=02194
-LeftRightVector=0294E
-LeftTee=022A3
-LeftTeeArrow=021A4
-LeftTeeVector=0295A
-LeftTriangle=022B2
-LeftTriangleBar=029CF
-LeftTriangleEqual=022B4
-LeftUpDownVector=02951
-LeftUpTeeVector=02960
-LeftUpVector=021BF
-LeftUpVectorBar=02958
-LeftVector=021BC
-LeftVectorBar=02952
-Leftarrow=021D0
-Leftrightarrow=021D4
-LessEqualGreater=022DA
-LessFullEqual=02266
-LessGreater=02276
-LessLess=02AA1
-LessSlantEqual=02A7D
-LessTilde=02272
-Lfr=1D50F
-Ll=022D8
-Lleftarrow=021DA
-Lmidot=0013F
-LongLeftArrow=027F5
-LongLeftRightArrow=027F7
-LongRightArrow=027F6
-Longleftarrow=027F8
-Longleftrightarrow=027FA
-Longrightarrow=027F9
-Lopf=1D543
-LowerLeftArrow=02199
-LowerRightArrow=02198
-Lscr=02112
-Lsh=021B0
-Lstrok=00141
-Lt=0226A
-Map=02905
-Mcy=0041C
-MediumSpace=0205F
-Mellintrf=02133
-Mfr=1D510
-MinusPlus=02213
-Mopf=1D544
-Mscr=02133
-Mu=0039C
-NJcy=0040A
-Nacute=00143
-Ncaron=00147
-Ncedil=00145
-Ncy=0041D
-NegativeMediumSpace=0200B
-NegativeThickSpace=0200B
-NegativeThinSpace=0200B
-NegativeVeryThinSpace=0200B
-NestedGreaterGreater=0226B
-NestedLessLess=0226A
-NewLine=0000A
-Nfr=1D511
-NoBreak=02060
-NonBreakingSpace=000A0
-Nopf=02115
-Not=02AEC
-NotCongruent=02262
-NotCupCap=0226D
-NotDoubleVerticalBar=02226
-NotElement=02209
-NotEqual=02260
-NotExists=02204
-NotGreater=0226F
-NotGreaterEqual=02271
-NotGreaterLess=02279
-NotGreaterTilde=02275
-NotLeftTriangle=022EA
-NotLeftTriangleEqual=022EC
-NotLess=0226E
-NotLessEqual=02270
-NotLessGreater=02278
-NotLessTilde=02274
-NotPrecedes=02280
-NotPrecedesSlantEqual=022E0
-NotReverseElement=0220C
-NotRightTriangle=022EB
-NotRightTriangleEqual=022ED
-NotSquareSubsetEqual=022E2
-NotSquareSupersetEqual=022E3
-NotSubsetEqual=02288
-NotSucceeds=02281
-NotSucceedsSlantEqual=022E1
-NotSupersetEqual=02289
-NotTilde=02241
-NotTildeEqual=02244
-NotTildeFullEqual=02247
-NotTildeTilde=02249
-NotVerticalBar=02224
-Nscr=1D4A9
-Ntilde=000D1
-Nu=0039D
-OElig=00152
-Oacute=000D3
-Ocirc=000D4
-Ocy=0041E
-Odblac=00150
-Ofr=1D512
-Ograve=000D2
-Omacr=0014C
-Omega=003A9
-Omicron=0039F
-Oopf=1D546
-OpenCurlyDoubleQuote=0201C
-OpenCurlyQuote=02018
-Or=02A54
-Oscr=1D4AA
-Oslash=000D8
-Otilde=000D5
-Otimes=02A37
-Ouml=000D6
-OverBar=0203E
-OverBrace=023DE
-OverBracket=023B4
-OverParenthesis=023DC
-PartialD=02202
-Pcy=0041F
-Pfr=1D513
-Phi=003A6
-Pi=003A0
-PlusMinus=000B1
-Poincareplane=0210C
-Popf=02119
-Pr=02ABB
-Precedes=0227A
-PrecedesEqual=02AAF
-PrecedesSlantEqual=0227C
-PrecedesTilde=0227E
-Prime=02033
-Product=0220F
-Proportion=02237
-Proportional=0221D
-Pscr=1D4AB
-Psi=003A8
-QUOT=00022
-Qfr=1D514
-Qopf=0211A
-Qscr=1D4AC
-RBarr=02910
-REG=000AE
-Racute=00154
-Rang=027EB
-Rarr=021A0
-Rarrtl=02916
-Rcaron=00158
-Rcedil=00156
-Rcy=00420
-Re=0211C
-ReverseElement=0220B
-ReverseEquilibrium=021CB
-ReverseUpEquilibrium=0296F
-Rfr=0211C
-Rho=003A1
-RightAngleBracket=027E9
-RightArrow=02192
-RightArrowBar=021E5
-RightArrowLeftArrow=021C4
-RightCeiling=02309
-RightDoubleBracket=027E7
-RightDownTeeVector=0295D
-RightDownVector=021C2
-RightDownVectorBar=02955
-RightFloor=0230B
-RightTee=022A2
-RightTeeArrow=021A6
-RightTeeVector=0295B
-RightTriangle=022B3
-RightTriangleBar=029D0
-RightTriangleEqual=022B5
-RightUpDownVector=0294F
-RightUpTeeVector=0295C
-RightUpVector=021BE
-RightUpVectorBar=02954
-RightVector=021C0
-RightVectorBar=02953
-Rightarrow=021D2
-Ropf=0211D
-RoundImplies=02970
-Rrightarrow=021DB
-Rscr=0211B
-Rsh=021B1
-RuleDelayed=029F4
-SHCHcy=00429
-SHcy=00428
-SOFTcy=0042C
-Sacute=0015A
-Sc=02ABC
-Scaron=00160
-Scedil=0015E
-Scirc=0015C
-Scy=00421
-Sfr=1D516
-ShortDownArrow=02193
-ShortLeftArrow=02190
-ShortRightArrow=02192
-ShortUpArrow=02191
-Sigma=003A3
-SmallCircle=02218
-Sopf=1D54A
-Sqrt=0221A
-Square=025A1
-SquareIntersection=02293
-SquareSubset=0228F
-SquareSubsetEqual=02291
-SquareSuperset=02290
-SquareSupersetEqual=02292
-SquareUnion=02294
-Sscr=1D4AE
-Star=022C6
-Sub=022D0
-Subset=022D0
-SubsetEqual=02286
-Succeeds=0227B
-SucceedsEqual=02AB0
-SucceedsSlantEqual=0227D
-SucceedsTilde=0227F
-SuchThat=0220B
-Sum=02211
-Sup=022D1
-Superset=02283
-SupersetEqual=02287
-Supset=022D1
-THORN=000DE
-TRADE=02122
-TSHcy=0040B
-TScy=00426
-Tab=00009
-Tau=003A4
-Tcaron=00164
-Tcedil=00162
-Tcy=00422
-Tfr=1D517
-Therefore=02234
-Theta=00398
-ThinSpace=02009
-Tilde=0223C
-TildeEqual=02243
-TildeFullEqual=02245
-TildeTilde=02248
-Topf=1D54B
-TripleDot=020DB
-Tscr=1D4AF
-Tstrok=00166
-Uacute=000DA
-Uarr=0219F
-Uarrocir=02949
-Ubrcy=0040E
-Ubreve=0016C
-Ucirc=000DB
-Ucy=00423
-Udblac=00170
-Ufr=1D518
-Ugrave=000D9
-Umacr=0016A
-UnderBar=0005F
-UnderBrace=023DF
-UnderBracket=023B5
-UnderParenthesis=023DD
-Union=022C3
-UnionPlus=0228E
-Uogon=00172
-Uopf=1D54C
-UpArrow=02191
-UpArrowBar=02912
-UpArrowDownArrow=021C5
-UpDownArrow=02195
-UpEquilibrium=0296E
-UpTee=022A5
-UpTeeArrow=021A5
-Uparrow=021D1
-Updownarrow=021D5
-UpperLeftArrow=02196
-UpperRightArrow=02197
-Upsi=003D2
-Upsilon=003A5
-Uring=0016E
-Uscr=1D4B0
-Utilde=00168
-Uuml=000DC
-VDash=022AB
-Vbar=02AEB
-Vcy=00412
-Vdash=022A9
-Vdashl=02AE6
-Vee=022C1
-Verbar=02016
-Vert=02016
-VerticalBar=02223
-VerticalLine=0007C
-VerticalSeparator=02758
-VerticalTilde=02240
-VeryThinSpace=0200A
-Vfr=1D519
-Vopf=1D54D
-Vscr=1D4B1
-Vvdash=022AA
-Wcirc=00174
-Wedge=022C0
-Wfr=1D51A
-Wopf=1D54E
-Wscr=1D4B2
-Xfr=1D51B
-Xi=0039E
-Xopf=1D54F
-Xscr=1D4B3
-YAcy=0042F
-YIcy=00407
-YUcy=0042E
-Yacute=000DD
-Ycirc=00176
-Ycy=0042B
-Yfr=1D51C
-Yopf=1D550
-Yscr=1D4B4
-Yuml=00178
-ZHcy=00416
-Zacute=00179
-Zcaron=0017D
-Zcy=00417
-Zdot=0017B
-ZeroWidthSpace=0200B
-Zeta=00396
-Zfr=02128
-Zopf=02124
-Zscr=1D4B5
-aacute=000E1
-abreve=00103
-ac=0223E
-acd=0223F
-acirc=000E2
-acute=000B4
-acy=00430
-aelig=000E6
-af=02061
-afr=1D51E
-agrave=000E0
-alefsym=02135
-aleph=02135
-alpha=003B1
-amacr=00101
-amalg=02A3F
-amp=00026
-and=02227
-andand=02A55
-andd=02A5C
-andslope=02A58
-andv=02A5A
-ang=02220
-ange=029A4
-angle=02220
-angmsd=02221
-angmsdaa=029A8
-angmsdab=029A9
-angmsdac=029AA
-angmsdad=029AB
-angmsdae=029AC
-angmsdaf=029AD
-angmsdag=029AE
-angmsdah=029AF
-angrt=0221F
-angrtvb=022BE
-angrtvbd=0299D
-angsph=02222
-angst=000C5
-angzarr=0237C
-aogon=00105
-aopf=1D552
-ap=02248
-apE=02A70
-apacir=02A6F
-ape=0224A
-apid=0224B
-apos=00027
-approx=02248
-approxeq=0224A
-aring=000E5
-ascr=1D4B6
-ast=0002A
-asymp=02248
-asympeq=0224D
-atilde=000E3
-auml=000E4
-awconint=02233
-awint=02A11
-bNot=02AED
-backcong=0224C
-backepsilon=003F6
-backprime=02035
-backsim=0223D
-backsimeq=022CD
-barvee=022BD
-barwed=02305
-barwedge=02305
-bbrk=023B5
-bbrktbrk=023B6
-bcong=0224C
-bcy=00431
-bdquo=0201E
-becaus=02235
-because=02235
-bemptyv=029B0
-bepsi=003F6
-bernou=0212C
-beta=003B2
-beth=02136
-between=0226C
-bfr=1D51F
-bigcap=022C2
-bigcirc=025EF
-bigcup=022C3
-bigodot=02A00
-bigoplus=02A01
-bigotimes=02A02
-bigsqcup=02A06
-bigstar=02605
-bigtriangledown=025BD
-bigtriangleup=025B3
-biguplus=02A04
-bigvee=022C1
-bigwedge=022C0
-bkarow=0290D
-blacklozenge=029EB
-blacksquare=025AA
-blacktriangle=025B4
-blacktriangledown=025BE
-blacktriangleleft=025C2
-blacktriangleright=025B8
-blank=02423
-blk12=02592
-blk14=02591
-blk34=02593
-block=02588
-bnot=02310
-bopf=1D553
-bot=022A5
-bottom=022A5
-bowtie=022C8
-boxDL=02557
-boxDR=02554
-boxDl=02556
-boxDr=02553
-boxH=02550
-boxHD=02566
-boxHU=02569
-boxHd=02564
-boxHu=02567
-boxUL=0255D
-boxUR=0255A
-boxUl=0255C
-boxUr=02559
-boxV=02551
-boxVH=0256C
-boxVL=02563
-boxVR=02560
-boxVh=0256B
-boxVl=02562
-boxVr=0255F
-boxbox=029C9
-boxdL=02555
-boxdR=02552
-boxdl=02510
-boxdr=0250C
-boxh=02500
-boxhD=02565
-boxhU=02568
-boxhd=0252C
-boxhu=02534
-boxminus=0229F
-boxplus=0229E
-boxtimes=022A0
-boxuL=0255B
-boxuR=02558
-boxul=02518
-boxur=02514
-boxv=02502
-boxvH=0256A
-boxvL=02561
-boxvR=0255E
-boxvh=0253C
-boxvl=02524
-boxvr=0251C
-bprime=02035
-breve=002D8
-brvbar=000A6
-bscr=1D4B7
-bsemi=0204F
-bsim=0223D
-bsime=022CD
-bsol=0005C
-bsolb=029C5
-bsolhsub=027C8
-bull=02022
-bullet=02022
-bump=0224E
-bumpE=02AAE
-bumpe=0224F
-bumpeq=0224F
-cacute=00107
-cap=02229
-capand=02A44
-capbrcup=02A49
-capcap=02A4B
-capcup=02A47
-capdot=02A40
-caret=02041
-caron=002C7
-ccaps=02A4D
-ccaron=0010D
-ccedil=000E7
-ccirc=00109
-ccups=02A4C
-ccupssm=02A50
-cdot=0010B
-cedil=000B8
-cemptyv=029B2
-cent=000A2
-centerdot=000B7
-cfr=1D520
-chcy=00447
-check=02713
-checkmark=02713
-chi=003C7
-cir=025CB
-cirE=029C3
-circ=002C6
-circeq=02257
-circlearrowleft=021BA
-circlearrowright=021BB
-circledR=000AE
-circledS=024C8
-circledast=0229B
-circledcirc=0229A
-circleddash=0229D
-cire=02257
-cirfnint=02A10
-cirmid=02AEF
-cirscir=029C2
-clubs=02663
-clubsuit=02663
-colon=0003A
-colone=02254
-coloneq=02254
-comma=0002C
-commat=00040
-comp=02201
-compfn=02218
-complement=02201
-complexes=02102
-cong=02245
-congdot=02A6D
-conint=0222E
-copf=1D554
-coprod=02210
-copy=000A9
-copysr=02117
-crarr=021B5
-cross=02717
-cscr=1D4B8
-csub=02ACF
-csube=02AD1
-csup=02AD0
-csupe=02AD2
-ctdot=022EF
-cudarrl=02938
-cudarrr=02935
-cuepr=022DE
-cuesc=022DF
-cularr=021B6
-cularrp=0293D
-cup=0222A
-cupbrcap=02A48
-cupcap=02A46
-cupcup=02A4A
-cupdot=0228D
-cupor=02A45
-curarr=021B7
-curarrm=0293C
-curlyeqprec=022DE
-curlyeqsucc=022DF
-curlyvee=022CE
-curlywedge=022CF
-curren=000A4
-curvearrowleft=021B6
-curvearrowright=021B7
-cuvee=022CE
-cuwed=022CF
-cwconint=02232
-cwint=02231
-cylcty=0232D
-dArr=021D3
-dHar=02965
-dagger=02020
-daleth=02138
-darr=02193
-dash=02010
-dashv=022A3
-dbkarow=0290F
-dblac=002DD
-dcaron=0010F
-dcy=00434
-dd=02146
-ddagger=02021
-ddarr=021CA
-ddotseq=02A77
-deg=000B0
-delta=003B4
-demptyv=029B1
-dfisht=0297F
-dfr=1D521
-dharl=021C3
-dharr=021C2
-diam=022C4
-diamond=022C4
-diamondsuit=02666
-diams=02666
-die=000A8
-digamma=003DD
-disin=022F2
-div=000F7
-divide=000F7
-divideontimes=022C7
-divonx=022C7
-djcy=00452
-dlcorn=0231E
-dlcrop=0230D
-dollar=00024
-dopf=1D555
-dot=002D9
-doteq=02250
-doteqdot=02251
-dotminus=02238
-dotplus=02214
-dotsquare=022A1
-doublebarwedge=02306
-downarrow=02193
-downdownarrows=021CA
-downharpoonleft=021C3
-downharpoonright=021C2
-drbkarow=02910
-drcorn=0231F
-drcrop=0230C
-dscr=1D4B9
-dscy=00455
-dsol=029F6
-dstrok=00111
-dtdot=022F1
-dtri=025BF
-dtrif=025BE
-duarr=021F5
-duhar=0296F
-dwangle=029A6
-dzcy=0045F
-dzigrarr=027FF
-eDDot=02A77
-eDot=02251
-eacute=000E9
-easter=02A6E
-ecaron=0011B
-ecir=02256
-ecirc=000EA
-ecolon=02255
-ecy=0044D
-edot=00117
-ee=02147
-efDot=02252
-efr=1D522
-eg=02A9A
-egrave=000E8
-egs=02A96
-egsdot=02A98
-el=02A99
-elinters=023E7
-ell=02113
-els=02A95
-elsdot=02A97
-emacr=00113
-empty=02205
-emptyset=02205
-emptyv=02205
-emsp13=02004
-emsp14=02005
-emsp=02003
-eng=0014B
-ensp=02002
-eogon=00119
-eopf=1D556
-epar=022D5
-eparsl=029E3
-eplus=02A71
-epsi=003B5
-epsilon=003B5
-epsiv=003F5
-eqcirc=02256
-eqcolon=02255
-eqsim=02242
-eqslantgtr=02A96
-eqslantless=02A95
-equals=0003D
-equest=0225F
-equiv=02261
-equivDD=02A78
-eqvparsl=029E5
-erDot=02253
-erarr=02971
-escr=0212F
-esdot=02250
-esim=02242
-eta=003B7
-eth=000F0
-euml=000EB
-euro=020AC
-excl=00021
-exist=02203
-expectation=02130
-exponentiale=02147
-fallingdotseq=02252
-fcy=00444
-female=02640
-ffilig=0FB03
-fflig=0FB00
-ffllig=0FB04
-ffr=1D523
-filig=0FB01
-flat=0266D
-fllig=0FB02
-fltns=025B1
-fnof=00192
-fopf=1D557
-forall=02200
-fork=022D4
-forkv=02AD9
-fpartint=02A0D
-frac12=000BD
-frac13=02153
-frac14=000BC
-frac15=02155
-frac16=02159
-frac18=0215B
-frac23=02154
-frac25=02156
-frac34=000BE
-frac35=02157
-frac38=0215C
-frac45=02158
-frac56=0215A
-frac58=0215D
-frac78=0215E
-frasl=02044
-frown=02322
-fscr=1D4BB
-gE=02267
-gEl=02A8C
-gacute=001F5
-gamma=003B3
-gammad=003DD
-gap=02A86
-gbreve=0011F
-gcirc=0011D
-gcy=00433
-gdot=00121
-ge=02265
-gel=022DB
-geq=02265
-geqq=02267
-geqslant=02A7E
-ges=02A7E
-gescc=02AA9
-gesdot=02A80
-gesdoto=02A82
-gesdotol=02A84
-gesles=02A94
-gfr=1D524
-gg=0226B
-ggg=022D9
-gimel=02137
-gjcy=00453
-gl=02277
-glE=02A92
-gla=02AA5
-glj=02AA4
-gnE=02269
-gnap=02A8A
-gnapprox=02A8A
-gne=02A88
-gneq=02A88
-gneqq=02269
-gnsim=022E7
-gopf=1D558
-grave=00060
-gscr=0210A
-gsim=02273
-gsime=02A8E
-gsiml=02A90
-gt=0003E
-gtcc=02AA7
-gtcir=02A7A
-gtdot=022D7
-gtlPar=02995
-gtquest=02A7C
-gtrapprox=02A86
-gtrarr=02978
-gtrdot=022D7
-gtreqless=022DB
-gtreqqless=02A8C
-gtrless=02277
-gtrsim=02273
-hArr=021D4
-hairsp=0200A
-half=000BD
-hamilt=0210B
-hardcy=0044A
-harr=02194
-harrcir=02948
-harrw=021AD
-hbar=0210F
-hcirc=00125
-hearts=02665
-heartsuit=02665
-hellip=02026
-hercon=022B9
-hfr=1D525
-hksearow=02925
-hkswarow=02926
-hoarr=021FF
-homtht=0223B
-hookleftarrow=021A9
-hookrightarrow=021AA
-hopf=1D559
-horbar=02015
-hscr=1D4BD
-hslash=0210F
-hstrok=00127
-hybull=02043
-hyphen=02010
-iacute=000ED
-ic=02063
-icirc=000EE
-icy=00438
-iecy=00435
-iexcl=000A1
-iff=021D4
-ifr=1D526
-igrave=000EC
-ii=02148
-iiiint=02A0C
-iiint=0222D
-iinfin=029DC
-iiota=02129
-ijlig=00133
-imacr=0012B
-image=02111
-imagline=02110
-imagpart=02111
-imath=00131
-imof=022B7
-imped=001B5
-in=02208
-incare=02105
-infin=0221E
-infintie=029DD
-inodot=00131
-int=0222B
-intcal=022BA
-integers=02124
-intercal=022BA
-intlarhk=02A17
-intprod=02A3C
-iocy=00451
-iogon=0012F
-iopf=1D55A
-iota=003B9
-iprod=02A3C
-iquest=000BF
-iscr=1D4BE
-isin=02208
-isinE=022F9
-isindot=022F5
-isins=022F4
-isinsv=022F3
-isinv=02208
-it=02062
-itilde=00129
-iukcy=00456
-iuml=000EF
-jcirc=00135
-jcy=00439
-jfr=1D527
-jmath=00237
-jopf=1D55B
-jscr=1D4BF
-jsercy=00458
-jukcy=00454
-kappa=003BA
-kappav=003F0
-kcedil=00137
-kcy=0043A
-kfr=1D528
-kgreen=00138
-khcy=00445
-kjcy=0045C
-kopf=1D55C
-kscr=1D4C0
-lAarr=021DA
-lArr=021D0
-lAtail=0291B
-lBarr=0290E
-lE=02266
-lEg=02A8B
-lHar=02962
-lacute=0013A
-laemptyv=029B4
-lagran=02112
-lambda=003BB
-lang=027E8
-langd=02991
-langle=027E8
-lap=02A85
-laquo=000AB
-larr=02190
-larrb=021E4
-larrbfs=0291F
-larrfs=0291D
-larrhk=021A9
-larrlp=021AB
-larrpl=02939
-larrsim=02973
-larrtl=021A2
-lat=02AAB
-latail=02919
-late=02AAD
-lbarr=0290C
-lbbrk=02772
-lbrace=0007B
-lbrack=0005B
-lbrke=0298B
-lbrksld=0298F
-lbrkslu=0298D
-lcaron=0013E
-lcedil=0013C
-lceil=02308
-lcub=0007B
-lcy=0043B
-ldca=02936
-ldquo=0201C
-ldquor=0201E
-ldrdhar=02967
-ldrushar=0294B
-ldsh=021B2
-le=02264
-leftarrow=02190
-leftarrowtail=021A2
-leftharpoondown=021BD
-leftharpoonup=021BC
-leftleftarrows=021C7
-leftrightarrow=02194
-leftrightarrows=021C6
-leftrightharpoons=021CB
-leftrightsquigarrow=021AD
-leftthreetimes=022CB
-leg=022DA
-leq=02264
-leqq=02266
-leqslant=02A7D
-les=02A7D
-lescc=02AA8
-lesdot=02A7F
-lesdoto=02A81
-lesdotor=02A83
-lesges=02A93
-lessapprox=02A85
-lessdot=022D6
-lesseqgtr=022DA
-lesseqqgtr=02A8B
-lessgtr=02276
-lesssim=02272
-lfisht=0297C
-lfloor=0230A
-lfr=1D529
-lg=02276
-lgE=02A91
-lhard=021BD
-lharu=021BC
-lharul=0296A
-lhblk=02584
-ljcy=00459
-ll=0226A
-llarr=021C7
-llcorner=0231E
-llhard=0296B
-lltri=025FA
-lmidot=00140
-lmoust=023B0
-lmoustache=023B0
-lnE=02268
-lnap=02A89
-lnapprox=02A89
-lne=02A87
-lneq=02A87
-lneqq=02268
-lnsim=022E6
-loang=027EC
-loarr=021FD
-lobrk=027E6
-longleftarrow=027F5
-longleftrightarrow=027F7
-longmapsto=027FC
-longrightarrow=027F6
-looparrowleft=021AB
-looparrowright=021AC
-lopar=02985
-lopf=1D55D
-loplus=02A2D
-lotimes=02A34
-lowast=02217
-lowbar=0005F
-loz=025CA
-lozenge=025CA
-lozf=029EB
-lpar=00028
-lparlt=02993
-lrarr=021C6
-lrcorner=0231F
-lrhar=021CB
-lrhard=0296D
-lrm=0200E
-lrtri=022BF
-lsaquo=02039
-lscr=1D4C1
-lsh=021B0
-lsim=02272
-lsime=02A8D
-lsimg=02A8F
-lsqb=0005B
-lsquo=02018
-lsquor=0201A
-lstrok=00142
-lt=0003C
-ltcc=02AA6
-ltcir=02A79
-ltdot=022D6
-lthree=022CB
-ltimes=022C9
-ltlarr=02976
-ltquest=02A7B
-ltrPar=02996
-ltri=025C3
-ltrie=022B4
-ltrif=025C2
-lurdshar=0294A
-luruhar=02966
-mDDot=0223A
-macr=000AF
-male=02642
-malt=02720
-maltese=02720
-map=021A6
-mapsto=021A6
-mapstodown=021A7
-mapstoleft=021A4
-mapstoup=021A5
-marker=025AE
-mcomma=02A29
-mcy=0043C
-mdash=02014
-measuredangle=02221
-mfr=1D52A
-mho=02127
-micro=000B5
-mid=02223
-midast=0002A
-midcir=02AF0
-middot=000B7
-minus=02212
-minusb=0229F
-minusd=02238
-minusdu=02A2A
-mlcp=02ADB
-mldr=02026
-mnplus=02213
-models=022A7
-mopf=1D55E
-mp=02213
-mscr=1D4C2
-mstpos=0223E
-mu=003BC
-multimap=022B8
-mumap=022B8
-nLeftarrow=021CD
-nLeftrightarrow=021CE
-nRightarrow=021CF
-nVDash=022AF
-nVdash=022AE
-nabla=02207
-nacute=00144
-nap=02249
-napos=00149
-napprox=02249
-natur=0266E
-natural=0266E
-naturals=02115
-nbsp=000A0
-ncap=02A43
-ncaron=00148
-ncedil=00146
-ncong=02247
-ncup=02A42
-ncy=0043D
-ndash=02013
-ne=02260
-neArr=021D7
-nearhk=02924
-nearr=02197
-nearrow=02197
-nequiv=02262
-nesear=02928
-nexist=02204
-nexists=02204
-nfr=1D52B
-nge=02271
-ngeq=02271
-ngsim=02275
-ngt=0226F
-ngtr=0226F
-nhArr=021CE
-nharr=021AE
-nhpar=02AF2
-ni=0220B
-nis=022FC
-nisd=022FA
-niv=0220B
-njcy=0045A
-nlArr=021CD
-nlarr=0219A
-nldr=02025
-nle=02270
-nleftarrow=0219A
-nleftrightarrow=021AE
-nleq=02270
-nless=0226E
-nlsim=02274
-nlt=0226E
-nltri=022EA
-nltrie=022EC
-nmid=02224
-nopf=1D55F
-not=000AC
-notin=02209
-notinva=02209
-notinvb=022F7
-notinvc=022F6
-notni=0220C
-notniva=0220C
-notnivb=022FE
-notnivc=022FD
-npar=02226
-nparallel=02226
-npolint=02A14
-npr=02280
-nprcue=022E0
-nprec=02280
-nrArr=021CF
-nrarr=0219B
-nrightarrow=0219B
-nrtri=022EB
-nrtrie=022ED
-nsc=02281
-nsccue=022E1
-nscr=1D4C3
-nshortmid=02224
-nshortparallel=02226
-nsim=02241
-nsime=02244
-nsimeq=02244
-nsmid=02224
-nspar=02226
-nsqsube=022E2
-nsqsupe=022E3
-nsub=02284
-nsube=02288
-nsubseteq=02288
-nsucc=02281
-nsup=02285
-nsupe=02289
-nsupseteq=02289
-ntgl=02279
-ntilde=000F1
-ntlg=02278
-ntriangleleft=022EA
-ntrianglelefteq=022EC
-ntriangleright=022EB
-ntrianglerighteq=022ED
-nu=003BD
-num=00023
-numero=02116
-numsp=02007
-nvDash=022AD
-nvHarr=02904
-nvdash=022AC
-nvinfin=029DE
-nvlArr=02902
-nvrArr=02903
-nwArr=021D6
-nwarhk=02923
-nwarr=02196
-nwarrow=02196
-nwnear=02927
-oS=024C8
-oacute=000F3
-oast=0229B
-ocir=0229A
-ocirc=000F4
-ocy=0043E
-odash=0229D
-odblac=00151
-odiv=02A38
-odot=02299
-odsold=029BC
-oelig=00153
-ofcir=029BF
-ofr=1D52C
-ogon=002DB
-ograve=000F2
-ogt=029C1
-ohbar=029B5
-ohm=003A9
-oint=0222E
-olarr=021BA
-olcir=029BE
-olcross=029BB
-oline=0203E
-olt=029C0
-omacr=0014D
-omega=003C9
-omicron=003BF
-omid=029B6
-ominus=02296
-oopf=1D560
-opar=029B7
-operp=029B9
-oplus=02295
-or=02228
-orarr=021BB
-ord=02A5D
-order=02134
-orderof=02134
-ordf=000AA
-ordm=000BA
-origof=022B6
-oror=02A56
-orslope=02A57
-orv=02A5B
-oscr=02134
-oslash=000F8
-osol=02298
-otilde=000F5
-otimes=02297
-otimesas=02A36
-ouml=000F6
-ovbar=0233D
-par=02225
-para=000B6
-parallel=02225
-parsim=02AF3
-parsl=02AFD
-part=02202
-pcy=0043F
-percnt=00025
-period=0002E
-permil=02030
-perp=022A5
-pertenk=02031
-pfr=1D52D
-phi=003C6
-phiv=003D5
-phmmat=02133
-phone=0260E
-pi=003C0
-pitchfork=022D4
-piv=003D6
-planck=0210F
-planckh=0210E
-plankv=0210F
-plus=0002B
-plusacir=02A23
-plusb=0229E
-pluscir=02A22
-plusdo=02214
-plusdu=02A25
-pluse=02A72
-plusmn=000B1
-plussim=02A26
-plustwo=02A27
-pm=000B1
-pointint=02A15
-popf=1D561
-pound=000A3
-pr=0227A
-prE=02AB3
-prap=02AB7
-prcue=0227C
-pre=02AAF
-prec=0227A
-precapprox=02AB7
-preccurlyeq=0227C
-preceq=02AAF
-precnapprox=02AB9
-precneqq=02AB5
-precnsim=022E8
-precsim=0227E
-prime=02032
-primes=02119
-prnE=02AB5
-prnap=02AB9
-prnsim=022E8
-prod=0220F
-profalar=0232E
-profline=02312
-profsurf=02313
-prop=0221D
-propto=0221D
-prsim=0227E
-prurel=022B0
-pscr=1D4C5
-psi=003C8
-puncsp=02008
-qfr=1D52E
-qint=02A0C
-qopf=1D562
-qprime=02057
-qscr=1D4C6
-quaternions=0210D
-quatint=02A16
-quest=0003F
-questeq=0225F
-quot=00022
-rAarr=021DB
-rArr=021D2
-rAtail=0291C
-rBarr=0290F
-rHar=02964
-racute=00155
-radic=0221A
-raemptyv=029B3
-rang=027E9
-rangd=02992
-range=029A5
-rangle=027E9
-raquo=000BB
-rarr=02192
-rarrap=02975
-rarrb=021E5
-rarrbfs=02920
-rarrc=02933
-rarrfs=0291E
-rarrhk=021AA
-rarrlp=021AC
-rarrpl=02945
-rarrsim=02974
-rarrtl=021A3
-rarrw=0219D
-ratail=0291A
-ratio=02236
-rationals=0211A
-rbarr=0290D
-rbbrk=02773
-rbrace=0007D
-rbrack=0005D
-rbrke=0298C
-rbrksld=0298E
-rbrkslu=02990
-rcaron=00159
-rcedil=00157
-rceil=02309
-rcub=0007D
-rcy=00440
-rdca=02937
-rdldhar=02969
-rdquo=0201D
-rdquor=0201D
-rdsh=021B3
-real=0211C
-realine=0211B
-realpart=0211C
-reals=0211D
-rect=025AD
-reg=000AE
-rfisht=0297D
-rfloor=0230B
-rfr=1D52F
-rhard=021C1
-rharu=021C0
-rharul=0296C
-rho=003C1
-rhov=003F1
-rightarrow=02192
-rightarrowtail=021A3
-rightharpoondown=021C1
-rightharpoonup=021C0
-rightleftarrows=021C4
-rightleftharpoons=021CC
-rightrightarrows=021C9
-rightsquigarrow=0219D
-rightthreetimes=022CC
-ring=002DA
-risingdotseq=02253
-rlarr=021C4
-rlhar=021CC
-rlm=0200F
-rmoust=023B1
-rmoustache=023B1
-rnmid=02AEE
-roang=027ED
-roarr=021FE
-robrk=027E7
-ropar=02986
-ropf=1D563
-roplus=02A2E
-rotimes=02A35
-rpar=00029
-rpargt=02994
-rppolint=02A12
-rrarr=021C9
-rsaquo=0203A
-rscr=1D4C7
-rsh=021B1
-rsqb=0005D
-rsquo=02019
-rsquor=02019
-rthree=022CC
-rtimes=022CA
-rtri=025B9
-rtrie=022B5
-rtrif=025B8
-rtriltri=029CE
-ruluhar=02968
-rx=0211E
-sacute=0015B
-sbquo=0201A
-sc=0227B
-scE=02AB4
-scap=02AB8
-scaron=00161
-sccue=0227D
-sce=02AB0
-scedil=0015F
-scirc=0015D
-scnE=02AB6
-scnap=02ABA
-scnsim=022E9
-scpolint=02A13
-scsim=0227F
-scy=00441
-sdot=022C5
-sdotb=022A1
-sdote=02A66
-seArr=021D8
-searhk=02925
-searr=02198
-searrow=02198
-sect=000A7
-semi=0003B
-seswar=02929
-setminus=02216
-setmn=02216
-sext=02736
-sfr=1D530
-sfrown=02322
-sharp=0266F
-shchcy=00449
-shcy=00448
-shortmid=02223
-shortparallel=02225
-shy=000AD
-sigma=003C3
-sigmaf=003C2
-sigmav=003C2
-sim=0223C
-simdot=02A6A
-sime=02243
-simeq=02243
-simg=02A9E
-simgE=02AA0
-siml=02A9D
-simlE=02A9F
-simne=02246
-simplus=02A24
-simrarr=02972
-slarr=02190
-smallsetminus=02216
-smashp=02A33
-smeparsl=029E4
-smid=02223
-smile=02323
-smt=02AAA
-smte=02AAC
-softcy=0044C
-sol=0002F
-solb=029C4
-solbar=0233F
-sopf=1D564
-spades=02660
-spadesuit=02660
-spar=02225
-sqcap=02293
-sqcup=02294
-sqsub=0228F
-sqsube=02291
-sqsubset=0228F
-sqsubseteq=02291
-sqsup=02290
-sqsupe=02292
-sqsupset=02290
-sqsupseteq=02292
-squ=025A1
-square=025A1
-squarf=025AA
-squf=025AA
-srarr=02192
-sscr=1D4C8
-ssetmn=02216
-ssmile=02323
-sstarf=022C6
-star=02606
-starf=02605
-straightepsilon=003F5
-straightphi=003D5
-strns=000AF
-sub=02282
-subE=02AC5
-subdot=02ABD
-sube=02286
-subedot=02AC3
-submult=02AC1
-subnE=02ACB
-subne=0228A
-subplus=02ABF
-subrarr=02979
-subset=02282
-subseteq=02286
-subseteqq=02AC5
-subsetneq=0228A
-subsetneqq=02ACB
-subsim=02AC7
-subsub=02AD5
-subsup=02AD3
-succ=0227B
-succapprox=02AB8
-succcurlyeq=0227D
-succeq=02AB0
-succnapprox=02ABA
-succneqq=02AB6
-succnsim=022E9
-succsim=0227F
-sum=02211
-sung=0266A
-sup1=000B9
-sup2=000B2
-sup3=000B3
-sup=02283
-supE=02AC6
-supdot=02ABE
-supdsub=02AD8
-supe=02287
-supedot=02AC4
-suphsol=027C9
-suphsub=02AD7
-suplarr=0297B
-supmult=02AC2
-supnE=02ACC
-supne=0228B
-supplus=02AC0
-supset=02283
-supseteq=02287
-supseteqq=02AC6
-supsetneq=0228B
-supsetneqq=02ACC
-supsim=02AC8
-supsub=02AD4
-supsup=02AD6
-swArr=021D9
-swarhk=02926
-swarr=02199
-swarrow=02199
-swnwar=0292A
-szlig=000DF
-target=02316
-tau=003C4
-tbrk=023B4
-tcaron=00165
-tcedil=00163
-tcy=00442
-tdot=020DB
-telrec=02315
-tfr=1D531
-there4=02234
-therefore=02234
-theta=003B8
-thetasym=003D1
-thetav=003D1
-thickapprox=02248
-thicksim=0223C
-thinsp=02009
-thkap=02248
-thksim=0223C
-thorn=000FE
-tilde=002DC
-times=000D7
-timesb=022A0
-timesbar=02A31
-timesd=02A30
-tint=0222D
-toea=02928
-top=022A4
-topbot=02336
-topcir=02AF1
-topf=1D565
-topfork=02ADA
-tosa=02929
-tprime=02034
-trade=02122
-triangle=025B5
-triangledown=025BF
-triangleleft=025C3
-trianglelefteq=022B4
-triangleq=0225C
-triangleright=025B9
-trianglerighteq=022B5
-tridot=025EC
-trie=0225C
-triminus=02A3A
-triplus=02A39
-trisb=029CD
-tritime=02A3B
-trpezium=023E2
-tscr=1D4C9
-tscy=00446
-tshcy=0045B
-tstrok=00167
-twixt=0226C
-twoheadleftarrow=0219E
-twoheadrightarrow=021A0
-uArr=021D1
-uHar=02963
-uacute=000FA
-uarr=02191
-ubrcy=0045E
-ubreve=0016D
-ucirc=000FB
-ucy=00443
-udarr=021C5
-udblac=00171
-udhar=0296E
-ufisht=0297E
-ufr=1D532
-ugrave=000F9
-uharl=021BF
-uharr=021BE
-uhblk=02580
-ulcorn=0231C
-ulcorner=0231C
-ulcrop=0230F
-ultri=025F8
-umacr=0016B
-uml=000A8
-uogon=00173
-uopf=1D566
-uparrow=02191
-updownarrow=02195
-upharpoonleft=021BF
-upharpoonright=021BE
-uplus=0228E
-upsi=003C5
-upsih=003D2
-upsilon=003C5
-upuparrows=021C8
-urcorn=0231D
-urcorner=0231D
-urcrop=0230E
-uring=0016F
-urtri=025F9
-uscr=1D4CA
-utdot=022F0
-utilde=00169
-utri=025B5
-utrif=025B4
-uuarr=021C8
-uuml=000FC
-uwangle=029A7
-vArr=021D5
-vBar=02AE8
-vBarv=02AE9
-vDash=022A8
-vangrt=0299C
-varepsilon=003F5
-varkappa=003F0
-varnothing=02205
-varphi=003D5
-varpi=003D6
-varpropto=0221D
-varr=02195
-varrho=003F1
-varsigma=003C2
-vartheta=003D1
-vartriangleleft=022B2
-vartriangleright=022B3
-vcy=00432
-vdash=022A2
-vee=02228
-veebar=022BB
-veeeq=0225A
-vellip=022EE
-verbar=0007C
-vert=0007C
-vfr=1D533
-vltri=022B2
-vopf=1D567
-vprop=0221D
-vrtri=022B3
-vscr=1D4CB
-vzigzag=0299A
-wcirc=00175
-wedbar=02A5F
-wedge=02227
-wedgeq=02259
-weierp=02118
-wfr=1D534
-wopf=1D568
-wp=02118
-wr=02240
-wreath=02240
-wscr=1D4CC
-xcap=022C2
-xcirc=025EF
-xcup=022C3
-xdtri=025BD
-xfr=1D535
-xhArr=027FA
-xharr=027F7
-xi=003BE
-xlArr=027F8
-xlarr=027F5
-xmap=027FC
-xnis=022FB
-xodot=02A00
-xopf=1D569
-xoplus=02A01
-xotime=02A02
-xrArr=027F9
-xrarr=027F6
-xscr=1D4CD
-xsqcup=02A06
-xuplus=02A04
-xutri=025B3
-xvee=022C1
-xwedge=022C0
-yacute=000FD
-yacy=0044F
-ycirc=00177
-ycy=0044B
-yen=000A5
-yfr=1D536
-yicy=00457
-yopf=1D56A
-yscr=1D4CE
-yucy=0044E
-yuml=000FF
-zacute=0017A
-zcaron=0017E
-zcy=00437
-zdot=0017C
-zeetrf=02128
-zeta=003B6
-zfr=1D537
-zhcy=00436
-zigrarr=021DD
-zopf=1D56B
-zscr=1D4CF
-zwj=0200D
-zwnj=0200C
diff --git a/src/org/jsoup/nodes/package-info.java b/src/org/jsoup/nodes/package-info.java
deleted file mode 100644
index 24b12803ff..0000000000
--- a/src/org/jsoup/nodes/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- HTML document structure nodes.
- */
-package org.jsoup.nodes; \ No newline at end of file
diff --git a/src/org/jsoup/package-info.java b/src/org/jsoup/package-info.java
deleted file mode 100644
index 49526116b4..0000000000
--- a/src/org/jsoup/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- Contains the main {@link org.jsoup.Jsoup} class, which provides convenient static access to the jsoup functionality.
- */
-package org.jsoup; \ No newline at end of file
diff --git a/src/org/jsoup/parser/CharacterReader.java b/src/org/jsoup/parser/CharacterReader.java
deleted file mode 100644
index b549a571a0..0000000000
--- a/src/org/jsoup/parser/CharacterReader.java
+++ /dev/null
@@ -1,230 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.Validate;
-
-/**
- CharacterReader consumes tokens off a string. To replace the old TokenQueue.
- */
-class CharacterReader {
- static final char EOF = (char) -1;
-
- private final String input;
- private final int length;
- private int pos = 0;
- private int mark = 0;
-
- CharacterReader(String input) {
- Validate.notNull(input);
- input = input.replaceAll("\r\n?", "\n"); // normalise carriage returns to newlines
-
- this.input = input;
- this.length = input.length();
- }
-
- int pos() {
- return pos;
- }
-
- boolean isEmpty() {
- return pos >= length;
- }
-
- char current() {
- return isEmpty() ? EOF : input.charAt(pos);
- }
-
- char consume() {
- char val = isEmpty() ? EOF : input.charAt(pos);
- pos++;
- return val;
- }
-
- void unconsume() {
- pos--;
- }
-
- void advance() {
- pos++;
- }
-
- void mark() {
- mark = pos;
- }
-
- void rewindToMark() {
- pos = mark;
- }
-
- String consumeAsString() {
- return input.substring(pos, pos++);
- }
-
- String consumeTo(char c) {
- int offset = input.indexOf(c, pos);
- if (offset != -1) {
- String consumed = input.substring(pos, offset);
- pos += consumed.length();
- return consumed;
- } else {
- return consumeToEnd();
- }
- }
-
- String consumeTo(String seq) {
- int offset = input.indexOf(seq, pos);
- if (offset != -1) {
- String consumed = input.substring(pos, offset);
- pos += consumed.length();
- return consumed;
- } else {
- return consumeToEnd();
- }
- }
-
- String consumeToAny(char... seq) {
- int start = pos;
-
- OUTER: while (!isEmpty()) {
- char c = input.charAt(pos);
- for (char seek : seq) {
- if (seek == c)
- break OUTER;
- }
- pos++;
- }
-
- return pos > start ? input.substring(start, pos) : "";
- }
-
- String consumeToEnd() {
- String data = input.substring(pos, input.length());
- pos = input.length();
- return data;
- }
-
- String consumeLetterSequence() {
- int start = pos;
- while (!isEmpty()) {
- char c = input.charAt(pos);
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
- pos++;
- else
- break;
- }
-
- return input.substring(start, pos);
- }
-
- String consumeLetterThenDigitSequence() {
- int start = pos;
- while (!isEmpty()) {
- char c = input.charAt(pos);
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
- pos++;
- else
- break;
- }
- while (!isEmpty()) {
- char c = input.charAt(pos);
- if (c >= '0' && c <= '9')
- pos++;
- else
- break;
- }
-
- return input.substring(start, pos);
- }
-
- String consumeHexSequence() {
- int start = pos;
- while (!isEmpty()) {
- char c = input.charAt(pos);
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
- pos++;
- else
- break;
- }
- return input.substring(start, pos);
- }
-
- String consumeDigitSequence() {
- int start = pos;
- while (!isEmpty()) {
- char c = input.charAt(pos);
- if (c >= '0' && c <= '9')
- pos++;
- else
- break;
- }
- return input.substring(start, pos);
- }
-
- boolean matches(char c) {
- return !isEmpty() && input.charAt(pos) == c;
-
- }
-
- boolean matches(String seq) {
- return input.startsWith(seq, pos);
- }
-
- boolean matchesIgnoreCase(String seq) {
- return input.regionMatches(true, pos, seq, 0, seq.length());
- }
-
- boolean matchesAny(char... seq) {
- if (isEmpty())
- return false;
-
- char c = input.charAt(pos);
- for (char seek : seq) {
- if (seek == c)
- return true;
- }
- return false;
- }
-
- boolean matchesLetter() {
- if (isEmpty())
- return false;
- char c = input.charAt(pos);
- return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
- }
-
- boolean matchesDigit() {
- if (isEmpty())
- return false;
- char c = input.charAt(pos);
- return (c >= '0' && c <= '9');
- }
-
- boolean matchConsume(String seq) {
- if (matches(seq)) {
- pos += seq.length();
- return true;
- } else {
- return false;
- }
- }
-
- boolean matchConsumeIgnoreCase(String seq) {
- if (matchesIgnoreCase(seq)) {
- pos += seq.length();
- return true;
- } else {
- return false;
- }
- }
-
- boolean containsIgnoreCase(String seq) {
- // used to check presence of </title>, </style>. only finds consistent case.
- String loScan = seq.toLowerCase();
- String hiScan = seq.toUpperCase();
- return (input.indexOf(loScan, pos) > -1) || (input.indexOf(hiScan, pos) > -1);
- }
-
- @Override
- public String toString() {
- return input.substring(pos);
- }
-}
diff --git a/src/org/jsoup/parser/HtmlTreeBuilder.java b/src/org/jsoup/parser/HtmlTreeBuilder.java
deleted file mode 100644
index 457a4c3249..0000000000
--- a/src/org/jsoup/parser/HtmlTreeBuilder.java
+++ /dev/null
@@ -1,672 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.DescendableLinkedList;
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.*;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * HTML Tree Builder; creates a DOM from Tokens.
- */
-class HtmlTreeBuilder extends TreeBuilder {
-
- private HtmlTreeBuilderState state; // the current state
- private HtmlTreeBuilderState originalState; // original / marked state
-
- private boolean baseUriSetFromDoc = false;
- private Element headElement; // the current head element
- private Element formElement; // the current form element
- private Element contextElement; // fragment parse context -- could be null even if fragment parsing
- private DescendableLinkedList<Element> formattingElements = new DescendableLinkedList<Element>(); // active (open) formatting elements
- private List<Token.Character> pendingTableCharacters = new ArrayList<Token.Character>(); // chars in table to be shifted out
-
- private boolean framesetOk = true; // if ok to go into frameset
- private boolean fosterInserts = false; // if next inserts should be fostered
- private boolean fragmentParsing = false; // if parsing a fragment of html
-
- HtmlTreeBuilder() {}
-
- @Override
- Document parse(String input, String baseUri, ParseErrorList errors) {
- state = HtmlTreeBuilderState.Initial;
- return super.parse(input, baseUri, errors);
- }
-
- List<Node> parseFragment(String inputFragment, Element context, String baseUri, ParseErrorList errors) {
- // context may be null
- state = HtmlTreeBuilderState.Initial;
- initialiseParse(inputFragment, baseUri, errors);
- contextElement = context;
- fragmentParsing = true;
- Element root = null;
-
- if (context != null) {
- if (context.ownerDocument() != null) // quirks setup:
- doc.quirksMode(context.ownerDocument().quirksMode());
-
- // initialise the tokeniser state:
- String contextTag = context.tagName();
- if (StringUtil.in(contextTag, "title", "textarea"))
- tokeniser.transition(TokeniserState.Rcdata);
- else if (StringUtil.in(contextTag, "iframe", "noembed", "noframes", "style", "xmp"))
- tokeniser.transition(TokeniserState.Rawtext);
- else if (contextTag.equals("script"))
- tokeniser.transition(TokeniserState.ScriptData);
- else if (contextTag.equals(("noscript")))
- tokeniser.transition(TokeniserState.Data); // if scripting enabled, rawtext
- else if (contextTag.equals("plaintext"))
- tokeniser.transition(TokeniserState.Data);
- else
- tokeniser.transition(TokeniserState.Data); // default
-
- root = new Element(Tag.valueOf("html"), baseUri);
- doc.appendChild(root);
- stack.push(root);
- resetInsertionMode();
- // todo: setup form element to nearest form on context (up ancestor chain)
- }
-
- runParser();
- if (context != null)
- return root.childNodes();
- else
- return doc.childNodes();
- }
-
- @Override
- protected boolean process(Token token) {
- currentToken = token;
- return this.state.process(token, this);
- }
-
- boolean process(Token token, HtmlTreeBuilderState state) {
- currentToken = token;
- return state.process(token, this);
- }
-
- void transition(HtmlTreeBuilderState state) {
- this.state = state;
- }
-
- HtmlTreeBuilderState state() {
- return state;
- }
-
- void markInsertionMode() {
- originalState = state;
- }
-
- HtmlTreeBuilderState originalState() {
- return originalState;
- }
-
- void framesetOk(boolean framesetOk) {
- this.framesetOk = framesetOk;
- }
-
- boolean framesetOk() {
- return framesetOk;
- }
-
- Document getDocument() {
- return doc;
- }
-
- String getBaseUri() {
- return baseUri;
- }
-
- void maybeSetBaseUri(Element base) {
- if (baseUriSetFromDoc) // only listen to the first <base href> in parse
- return;
-
- String href = base.absUrl("href");
- if (href.length() != 0) { // ignore <base target> etc
- baseUri = href;
- baseUriSetFromDoc = true;
- doc.setBaseUri(href); // set on the doc so doc.createElement(Tag) will get updated base, and to update all descendants
- }
- }
-
- boolean isFragmentParsing() {
- return fragmentParsing;
- }
-
- void error(HtmlTreeBuilderState state) {
- if (errors.canAddError())
- errors.add(new ParseError(reader.pos(), "Unexpected token [%s] when in state [%s]", currentToken.tokenType(), state));
- }
-
- Element insert(Token.StartTag startTag) {
- // handle empty unknown tags
- // when the spec expects an empty tag, will directly hit insertEmpty, so won't generate fake end tag.
- if (startTag.isSelfClosing() && !Tag.isKnownTag(startTag.name())) {
- Element el = insertEmpty(startTag);
- process(new Token.EndTag(el.tagName())); // ensure we get out of whatever state we are in
- return el;
- }
-
- Element el = new Element(Tag.valueOf(startTag.name()), baseUri, startTag.attributes);
- insert(el);
- return el;
- }
-
- Element insert(String startTagName) {
- Element el = new Element(Tag.valueOf(startTagName), baseUri);
- insert(el);
- return el;
- }
-
- void insert(Element el) {
- insertNode(el);
- stack.add(el);
- }
-
- Element insertEmpty(Token.StartTag startTag) {
- Tag tag = Tag.valueOf(startTag.name());
- Element el = new Element(tag, baseUri, startTag.attributes);
- insertNode(el);
- if (startTag.isSelfClosing()) {
- tokeniser.acknowledgeSelfClosingFlag();
- if (!tag.isKnownTag()) // unknown tag, remember this is self closing for output
- tag.setSelfClosing();
- }
- return el;
- }
-
- void insert(Token.Comment commentToken) {
- Comment comment = new Comment(commentToken.getData(), baseUri);
- insertNode(comment);
- }
-
- void insert(Token.Character characterToken) {
- Node node;
- // characters in script and style go in as datanodes, not text nodes
- if (StringUtil.in(currentElement().tagName(), "script", "style"))
- node = new DataNode(characterToken.getData(), baseUri);
- else
- node = new TextNode(characterToken.getData(), baseUri);
- currentElement().appendChild(node); // doesn't use insertNode, because we don't foster these; and will always have a stack.
- }
-
- private void insertNode(Node node) {
- // if the stack hasn't been set up yet, elements (doctype, comments) go into the doc
- if (stack.size() == 0)
- doc.appendChild(node);
- else if (isFosterInserts())
- insertInFosterParent(node);
- else
- currentElement().appendChild(node);
- }
-
- Element pop() {
- // todo - dev, remove validation check
- if (stack.peekLast().nodeName().equals("td") && !state.name().equals("InCell"))
- Validate.isFalse(true, "pop td not in cell");
- if (stack.peekLast().nodeName().equals("html"))
- Validate.isFalse(true, "popping html!");
- return stack.pollLast();
- }
-
- void push(Element element) {
- stack.add(element);
- }
-
- DescendableLinkedList<Element> getStack() {
- return stack;
- }
-
- boolean onStack(Element el) {
- return isElementInQueue(stack, el);
- }
-
- private boolean isElementInQueue(DescendableLinkedList<Element> queue, Element element) {
- Iterator<Element> it = queue.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == element) {
- return true;
- }
- }
- return false;
- }
-
- Element getFromStack(String elName) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next.nodeName().equals(elName)) {
- return next;
- }
- }
- return null;
- }
-
- boolean removeFromStack(Element el) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == el) {
- it.remove();
- return true;
- }
- }
- return false;
- }
-
- void popStackToClose(String elName) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next.nodeName().equals(elName)) {
- it.remove();
- break;
- } else {
- it.remove();
- }
- }
- }
-
- void popStackToClose(String... elNames) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (StringUtil.in(next.nodeName(), elNames)) {
- it.remove();
- break;
- } else {
- it.remove();
- }
- }
- }
-
- void popStackToBefore(String elName) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next.nodeName().equals(elName)) {
- break;
- } else {
- it.remove();
- }
- }
- }
-
- void clearStackToTableContext() {
- clearStackToContext("table");
- }
-
- void clearStackToTableBodyContext() {
- clearStackToContext("tbody", "tfoot", "thead");
- }
-
- void clearStackToTableRowContext() {
- clearStackToContext("tr");
- }
-
- private void clearStackToContext(String... nodeNames) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (StringUtil.in(next.nodeName(), nodeNames) || next.nodeName().equals("html"))
- break;
- else
- it.remove();
- }
- }
-
- Element aboveOnStack(Element el) {
- assert onStack(el);
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == el) {
- return it.next();
- }
- }
- return null;
- }
-
- void insertOnStackAfter(Element after, Element in) {
- int i = stack.lastIndexOf(after);
- Validate.isTrue(i != -1);
- stack.add(i+1, in);
- }
-
- void replaceOnStack(Element out, Element in) {
- replaceInQueue(stack, out, in);
- }
-
- private void replaceInQueue(LinkedList<Element> queue, Element out, Element in) {
- int i = queue.lastIndexOf(out);
- Validate.isTrue(i != -1);
- queue.remove(i);
- queue.add(i, in);
- }
-
- void resetInsertionMode() {
- boolean last = false;
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element node = it.next();
- if (!it.hasNext()) {
- last = true;
- node = contextElement;
- }
- String name = node.nodeName();
- if ("select".equals(name)) {
- transition(HtmlTreeBuilderState.InSelect);
- break; // frag
- } else if (("td".equals(name) || "td".equals(name) && !last)) {
- transition(HtmlTreeBuilderState.InCell);
- break;
- } else if ("tr".equals(name)) {
- transition(HtmlTreeBuilderState.InRow);
- break;
- } else if ("tbody".equals(name) || "thead".equals(name) || "tfoot".equals(name)) {
- transition(HtmlTreeBuilderState.InTableBody);
- break;
- } else if ("caption".equals(name)) {
- transition(HtmlTreeBuilderState.InCaption);
- break;
- } else if ("colgroup".equals(name)) {
- transition(HtmlTreeBuilderState.InColumnGroup);
- break; // frag
- } else if ("table".equals(name)) {
- transition(HtmlTreeBuilderState.InTable);
- break;
- } else if ("head".equals(name)) {
- transition(HtmlTreeBuilderState.InBody);
- break; // frag
- } else if ("body".equals(name)) {
- transition(HtmlTreeBuilderState.InBody);
- break;
- } else if ("frameset".equals(name)) {
- transition(HtmlTreeBuilderState.InFrameset);
- break; // frag
- } else if ("html".equals(name)) {
- transition(HtmlTreeBuilderState.BeforeHead);
- break; // frag
- } else if (last) {
- transition(HtmlTreeBuilderState.InBody);
- break; // frag
- }
- }
- }
-
- // todo: tidy up in specific scope methods
- private boolean inSpecificScope(String targetName, String[] baseTypes, String[] extraTypes) {
- return inSpecificScope(new String[]{targetName}, baseTypes, extraTypes);
- }
-
- private boolean inSpecificScope(String[] targetNames, String[] baseTypes, String[] extraTypes) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element el = it.next();
- String elName = el.nodeName();
- if (StringUtil.in(elName, targetNames))
- return true;
- if (StringUtil.in(elName, baseTypes))
- return false;
- if (extraTypes != null && StringUtil.in(elName, extraTypes))
- return false;
- }
- Validate.fail("Should not be reachable");
- return false;
- }
-
- boolean inScope(String[] targetNames) {
- return inSpecificScope(targetNames, new String[]{"applet", "caption", "html", "table", "td", "th", "marquee", "object"}, null);
- }
-
- boolean inScope(String targetName) {
- return inScope(targetName, null);
- }
-
- boolean inScope(String targetName, String[] extras) {
- return inSpecificScope(targetName, new String[]{"applet", "caption", "html", "table", "td", "th", "marquee", "object"}, extras);
- // todo: in mathml namespace: mi, mo, mn, ms, mtext annotation-xml
- // todo: in svg namespace: forignOjbect, desc, title
- }
-
- boolean inListItemScope(String targetName) {
- return inScope(targetName, new String[]{"ol", "ul"});
- }
-
- boolean inButtonScope(String targetName) {
- return inScope(targetName, new String[]{"button"});
- }
-
- boolean inTableScope(String targetName) {
- return inSpecificScope(targetName, new String[]{"html", "table"}, null);
- }
-
- boolean inSelectScope(String targetName) {
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element el = it.next();
- String elName = el.nodeName();
- if (elName.equals(targetName))
- return true;
- if (!StringUtil.in(elName, "optgroup", "option")) // all elements except
- return false;
- }
- Validate.fail("Should not be reachable");
- return false;
- }
-
- void setHeadElement(Element headElement) {
- this.headElement = headElement;
- }
-
- Element getHeadElement() {
- return headElement;
- }
-
- boolean isFosterInserts() {
- return fosterInserts;
- }
-
- void setFosterInserts(boolean fosterInserts) {
- this.fosterInserts = fosterInserts;
- }
-
- Element getFormElement() {
- return formElement;
- }
-
- void setFormElement(Element formElement) {
- this.formElement = formElement;
- }
-
- void newPendingTableCharacters() {
- pendingTableCharacters = new ArrayList<Token.Character>();
- }
-
- List<Token.Character> getPendingTableCharacters() {
- return pendingTableCharacters;
- }
-
- void setPendingTableCharacters(List<Token.Character> pendingTableCharacters) {
- this.pendingTableCharacters = pendingTableCharacters;
- }
-
- /**
- 11.2.5.2 Closing elements that have implied end tags<p/>
- When the steps below require the UA to generate implied end tags, then, while the current node is a dd element, a
- dt element, an li element, an option element, an optgroup element, a p element, an rp element, or an rt element,
- the UA must pop the current node off the stack of open elements.
-
- @param excludeTag If a step requires the UA to generate implied end tags but lists an element to exclude from the
- process, then the UA must perform the above steps as if that element was not in the above list.
- */
- void generateImpliedEndTags(String excludeTag) {
- while ((excludeTag != null && !currentElement().nodeName().equals(excludeTag)) &&
- StringUtil.in(currentElement().nodeName(), "dd", "dt", "li", "option", "optgroup", "p", "rp", "rt"))
- pop();
- }
-
- void generateImpliedEndTags() {
- generateImpliedEndTags(null);
- }
-
- boolean isSpecial(Element el) {
- // todo: mathml's mi, mo, mn
- // todo: svg's foreigObject, desc, title
- String name = el.nodeName();
- return StringUtil.in(name, "address", "applet", "area", "article", "aside", "base", "basefont", "bgsound",
- "blockquote", "body", "br", "button", "caption", "center", "col", "colgroup", "command", "dd",
- "details", "dir", "div", "dl", "dt", "embed", "fieldset", "figcaption", "figure", "footer", "form",
- "frame", "frameset", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html",
- "iframe", "img", "input", "isindex", "li", "link", "listing", "marquee", "menu", "meta", "nav",
- "noembed", "noframes", "noscript", "object", "ol", "p", "param", "plaintext", "pre", "script",
- "section", "select", "style", "summary", "table", "tbody", "td", "textarea", "tfoot", "th", "thead",
- "title", "tr", "ul", "wbr", "xmp");
- }
-
- // active formatting elements
- void pushActiveFormattingElements(Element in) {
- int numSeen = 0;
- Iterator<Element> iter = formattingElements.descendingIterator();
- while (iter.hasNext()) {
- Element el = iter.next();
- if (el == null) // marker
- break;
-
- if (isSameFormattingElement(in, el))
- numSeen++;
-
- if (numSeen == 3) {
- iter.remove();
- break;
- }
- }
- formattingElements.add(in);
- }
-
- private boolean isSameFormattingElement(Element a, Element b) {
- // same if: same namespace, tag, and attributes. Element.equals only checks tag, might in future check children
- return a.nodeName().equals(b.nodeName()) &&
- // a.namespace().equals(b.namespace()) &&
- a.attributes().equals(b.attributes());
- // todo: namespaces
- }
-
- void reconstructFormattingElements() {
- int size = formattingElements.size();
- if (size == 0 || formattingElements.getLast() == null || onStack(formattingElements.getLast()))
- return;
-
- Element entry = formattingElements.getLast();
- int pos = size - 1;
- boolean skip = false;
- while (true) {
- if (pos == 0) { // step 4. if none before, skip to 8
- skip = true;
- break;
- }
- entry = formattingElements.get(--pos); // step 5. one earlier than entry
- if (entry == null || onStack(entry)) // step 6 - neither marker nor on stack
- break; // jump to 8, else continue back to 4
- }
- while(true) {
- if (!skip) // step 7: on later than entry
- entry = formattingElements.get(++pos);
- Validate.notNull(entry); // should not occur, as we break at last element
-
- // 8. create new element from element, 9 insert into current node, onto stack
- skip = false; // can only skip increment from 4.
- Element newEl = insert(entry.nodeName()); // todo: avoid fostering here?
- // newEl.namespace(entry.namespace()); // todo: namespaces
- newEl.attributes().addAll(entry.attributes());
-
- // 10. replace entry with new entry
- formattingElements.add(pos, newEl);
- formattingElements.remove(pos + 1);
-
- // 11
- if (pos == size-1) // if not last entry in list, jump to 7
- break;
- }
- }
-
- void clearFormattingElementsToLastMarker() {
- while (!formattingElements.isEmpty()) {
- Element el = formattingElements.peekLast();
- formattingElements.removeLast();
- if (el == null)
- break;
- }
- }
-
- void removeFromActiveFormattingElements(Element el) {
- Iterator<Element> it = formattingElements.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == el) {
- it.remove();
- break;
- }
- }
- }
-
- boolean isInActiveFormattingElements(Element el) {
- return isElementInQueue(formattingElements, el);
- }
-
- Element getActiveFormattingElement(String nodeName) {
- Iterator<Element> it = formattingElements.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == null) // scope marker
- break;
- else if (next.nodeName().equals(nodeName))
- return next;
- }
- return null;
- }
-
- void replaceActiveFormattingElement(Element out, Element in) {
- replaceInQueue(formattingElements, out, in);
- }
-
- void insertMarkerToFormattingElements() {
- formattingElements.add(null);
- }
-
- void insertInFosterParent(Node in) {
- Element fosterParent = null;
- Element lastTable = getFromStack("table");
- boolean isLastTableParent = false;
- if (lastTable != null) {
- if (lastTable.parent() != null) {
- fosterParent = lastTable.parent();
- isLastTableParent = true;
- } else
- fosterParent = aboveOnStack(lastTable);
- } else { // no table == frag
- fosterParent = stack.get(0);
- }
-
- if (isLastTableParent) {
- Validate.notNull(lastTable); // last table cannot be null by this point.
- lastTable.before(in);
- }
- else
- fosterParent.appendChild(in);
- }
-
- @Override
- public String toString() {
- return "TreeBuilder{" +
- "currentToken=" + currentToken +
- ", state=" + state +
- ", currentElement=" + currentElement() +
- '}';
- }
-}
diff --git a/src/org/jsoup/parser/HtmlTreeBuilderState.java b/src/org/jsoup/parser/HtmlTreeBuilderState.java
deleted file mode 100644
index ceab9faa5a..0000000000
--- a/src/org/jsoup/parser/HtmlTreeBuilderState.java
+++ /dev/null
@@ -1,1482 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.DescendableLinkedList;
-import org.jsoup.helper.StringUtil;
-import org.jsoup.nodes.*;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-/**
- * The Tree Builder's current state. Each state embodies the processing for the state, and transitions to other states.
- */
-enum HtmlTreeBuilderState {
- Initial {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- return true; // ignore whitespace
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype()) {
- // todo: parse error check on expected doctypes
- // todo: quirk state check on doctype ids
- Token.Doctype d = t.asDoctype();
- DocumentType doctype = new DocumentType(d.getName(), d.getPublicIdentifier(), d.getSystemIdentifier(), tb.getBaseUri());
- tb.getDocument().appendChild(doctype);
- if (d.isForceQuirks())
- tb.getDocument().quirksMode(Document.QuirksMode.quirks);
- tb.transition(BeforeHtml);
- } else {
- // todo: check not iframe srcdoc
- tb.transition(BeforeHtml);
- return tb.process(t); // re-process token
- }
- return true;
- }
- },
- BeforeHtml {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (isWhitespace(t)) {
- return true; // ignore whitespace
- } else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
- tb.insert(t.asStartTag());
- tb.transition(BeforeHead);
- } else if (t.isEndTag() && (StringUtil.in(t.asEndTag().name(), "head", "body", "html", "br"))) {
- return anythingElse(t, tb);
- } else if (t.isEndTag()) {
- tb.error(this);
- return false;
- } else {
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- tb.insert("html");
- tb.transition(BeforeHead);
- return tb.process(t);
- }
- },
- BeforeHead {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- return true;
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
- return InBody.process(t, tb); // does not transition
- } else if (t.isStartTag() && t.asStartTag().name().equals("head")) {
- Element head = tb.insert(t.asStartTag());
- tb.setHeadElement(head);
- tb.transition(InHead);
- } else if (t.isEndTag() && (StringUtil.in(t.asEndTag().name(), "head", "body", "html", "br"))) {
- tb.process(new Token.StartTag("head"));
- return tb.process(t);
- } else if (t.isEndTag()) {
- tb.error(this);
- return false;
- } else {
- tb.process(new Token.StartTag("head"));
- return tb.process(t);
- }
- return true;
- }
- },
- InHead {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- tb.insert(t.asCharacter());
- return true;
- }
- switch (t.type) {
- case Comment:
- tb.insert(t.asComment());
- break;
- case Doctype:
- tb.error(this);
- return false;
- case StartTag:
- Token.StartTag start = t.asStartTag();
- String name = start.name();
- if (name.equals("html")) {
- return InBody.process(t, tb);
- } else if (StringUtil.in(name, "base", "basefont", "bgsound", "command", "link")) {
- Element el = tb.insertEmpty(start);
- // jsoup special: update base the frist time it is seen
- if (name.equals("base") && el.hasAttr("href"))
- tb.maybeSetBaseUri(el);
- } else if (name.equals("meta")) {
- Element meta = tb.insertEmpty(start);
- // todo: charset switches
- } else if (name.equals("title")) {
- handleRcData(start, tb);
- } else if (StringUtil.in(name, "noframes", "style")) {
- handleRawtext(start, tb);
- } else if (name.equals("noscript")) {
- // else if noscript && scripting flag = true: rawtext (jsoup doesn't run script, to handle as noscript)
- tb.insert(start);
- tb.transition(InHeadNoscript);
- } else if (name.equals("script")) {
- // skips some script rules as won't execute them
- tb.insert(start);
- tb.tokeniser.transition(TokeniserState.ScriptData);
- tb.markInsertionMode();
- tb.transition(Text);
- } else if (name.equals("head")) {
- tb.error(this);
- return false;
- } else {
- return anythingElse(t, tb);
- }
- break;
- case EndTag:
- Token.EndTag end = t.asEndTag();
- name = end.name();
- if (name.equals("head")) {
- tb.pop();
- tb.transition(AfterHead);
- } else if (StringUtil.in(name, "body", "html", "br")) {
- return anythingElse(t, tb);
- } else {
- tb.error(this);
- return false;
- }
- break;
- default:
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, TreeBuilder tb) {
- tb.process(new Token.EndTag("head"));
- return tb.process(t);
- }
- },
- InHeadNoscript {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isDoctype()) {
- tb.error(this);
- } else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
- return tb.process(t, InBody);
- } else if (t.isEndTag() && t.asEndTag().name().equals("noscript")) {
- tb.pop();
- tb.transition(InHead);
- } else if (isWhitespace(t) || t.isComment() || (t.isStartTag() && StringUtil.in(t.asStartTag().name(),
- "basefont", "bgsound", "link", "meta", "noframes", "style"))) {
- return tb.process(t, InHead);
- } else if (t.isEndTag() && t.asEndTag().name().equals("br")) {
- return anythingElse(t, tb);
- } else if ((t.isStartTag() && StringUtil.in(t.asStartTag().name(), "head", "noscript")) || t.isEndTag()) {
- tb.error(this);
- return false;
- } else {
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- tb.error(this);
- tb.process(new Token.EndTag("noscript"));
- return tb.process(t);
- }
- },
- AfterHead {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- tb.insert(t.asCharacter());
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype()) {
- tb.error(this);
- } else if (t.isStartTag()) {
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
- if (name.equals("html")) {
- return tb.process(t, InBody);
- } else if (name.equals("body")) {
- tb.insert(startTag);
- tb.framesetOk(false);
- tb.transition(InBody);
- } else if (name.equals("frameset")) {
- tb.insert(startTag);
- tb.transition(InFrameset);
- } else if (StringUtil.in(name, "base", "basefont", "bgsound", "link", "meta", "noframes", "script", "style", "title")) {
- tb.error(this);
- Element head = tb.getHeadElement();
- tb.push(head);
- tb.process(t, InHead);
- tb.removeFromStack(head);
- } else if (name.equals("head")) {
- tb.error(this);
- return false;
- } else {
- anythingElse(t, tb);
- }
- } else if (t.isEndTag()) {
- if (StringUtil.in(t.asEndTag().name(), "body", "html")) {
- anythingElse(t, tb);
- } else {
- tb.error(this);
- return false;
- }
- } else {
- anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- tb.process(new Token.StartTag("body"));
- tb.framesetOk(true);
- return tb.process(t);
- }
- },
- InBody {
- boolean process(Token t, HtmlTreeBuilder tb) {
- switch (t.type) {
- case Character: {
- Token.Character c = t.asCharacter();
- if (c.getData().equals(nullString)) {
- // todo confirm that check
- tb.error(this);
- return false;
- } else if (isWhitespace(c)) {
- tb.reconstructFormattingElements();
- tb.insert(c);
- } else {
- tb.reconstructFormattingElements();
- tb.insert(c);
- tb.framesetOk(false);
- }
- break;
- }
- case Comment: {
- tb.insert(t.asComment());
- break;
- }
- case Doctype: {
- tb.error(this);
- return false;
- }
- case StartTag:
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
- if (name.equals("html")) {
- tb.error(this);
- // merge attributes onto real html
- Element html = tb.getStack().getFirst();
- for (Attribute attribute : startTag.getAttributes()) {
- if (!html.hasAttr(attribute.getKey()))
- html.attributes().put(attribute);
- }
- } else if (StringUtil.in(name, "base", "basefont", "bgsound", "command", "link", "meta", "noframes", "script", "style", "title")) {
- return tb.process(t, InHead);
- } else if (name.equals("body")) {
- tb.error(this);
- LinkedList<Element> stack = tb.getStack();
- if (stack.size() == 1 || (stack.size() > 2 && !stack.get(1).nodeName().equals("body"))) {
- // only in fragment case
- return false; // ignore
- } else {
- tb.framesetOk(false);
- Element body = stack.get(1);
- for (Attribute attribute : startTag.getAttributes()) {
- if (!body.hasAttr(attribute.getKey()))
- body.attributes().put(attribute);
- }
- }
- } else if (name.equals("frameset")) {
- tb.error(this);
- LinkedList<Element> stack = tb.getStack();
- if (stack.size() == 1 || (stack.size() > 2 && !stack.get(1).nodeName().equals("body"))) {
- // only in fragment case
- return false; // ignore
- } else if (!tb.framesetOk()) {
- return false; // ignore frameset
- } else {
- Element second = stack.get(1);
- if (second.parent() != null)
- second.remove();
- // pop up to html element
- while (stack.size() > 1)
- stack.removeLast();
- tb.insert(startTag);
- tb.transition(InFrameset);
- }
- } else if (StringUtil.in(name,
- "address", "article", "aside", "blockquote", "center", "details", "dir", "div", "dl",
- "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "menu", "nav", "ol",
- "p", "section", "summary", "ul")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- } else if (StringUtil.in(name, "h1", "h2", "h3", "h4", "h5", "h6")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- if (StringUtil.in(tb.currentElement().nodeName(), "h1", "h2", "h3", "h4", "h5", "h6")) {
- tb.error(this);
- tb.pop();
- }
- tb.insert(startTag);
- } else if (StringUtil.in(name, "pre", "listing")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- // todo: ignore LF if next token
- tb.framesetOk(false);
- } else if (name.equals("form")) {
- if (tb.getFormElement() != null) {
- tb.error(this);
- return false;
- }
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- Element form = tb.insert(startTag);
- tb.setFormElement(form);
- } else if (name.equals("li")) {
- tb.framesetOk(false);
- LinkedList<Element> stack = tb.getStack();
- for (int i = stack.size() - 1; i > 0; i--) {
- Element el = stack.get(i);
- if (el.nodeName().equals("li")) {
- tb.process(new Token.EndTag("li"));
- break;
- }
- if (tb.isSpecial(el) && !StringUtil.in(el.nodeName(), "address", "div", "p"))
- break;
- }
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- } else if (StringUtil.in(name, "dd", "dt")) {
- tb.framesetOk(false);
- LinkedList<Element> stack = tb.getStack();
- for (int i = stack.size() - 1; i > 0; i--) {
- Element el = stack.get(i);
- if (StringUtil.in(el.nodeName(), "dd", "dt")) {
- tb.process(new Token.EndTag(el.nodeName()));
- break;
- }
- if (tb.isSpecial(el) && !StringUtil.in(el.nodeName(), "address", "div", "p"))
- break;
- }
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- } else if (name.equals("plaintext")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- tb.tokeniser.transition(TokeniserState.PLAINTEXT); // once in, never gets out
- } else if (name.equals("button")) {
- if (tb.inButtonScope("button")) {
- // close and reprocess
- tb.error(this);
- tb.process(new Token.EndTag("button"));
- tb.process(startTag);
- } else {
- tb.reconstructFormattingElements();
- tb.insert(startTag);
- tb.framesetOk(false);
- }
- } else if (name.equals("a")) {
- if (tb.getActiveFormattingElement("a") != null) {
- tb.error(this);
- tb.process(new Token.EndTag("a"));
-
- // still on stack?
- Element remainingA = tb.getFromStack("a");
- if (remainingA != null) {
- tb.removeFromActiveFormattingElements(remainingA);
- tb.removeFromStack(remainingA);
- }
- }
- tb.reconstructFormattingElements();
- Element a = tb.insert(startTag);
- tb.pushActiveFormattingElements(a);
- } else if (StringUtil.in(name,
- "b", "big", "code", "em", "font", "i", "s", "small", "strike", "strong", "tt", "u")) {
- tb.reconstructFormattingElements();
- Element el = tb.insert(startTag);
- tb.pushActiveFormattingElements(el);
- } else if (name.equals("nobr")) {
- tb.reconstructFormattingElements();
- if (tb.inScope("nobr")) {
- tb.error(this);
- tb.process(new Token.EndTag("nobr"));
- tb.reconstructFormattingElements();
- }
- Element el = tb.insert(startTag);
- tb.pushActiveFormattingElements(el);
- } else if (StringUtil.in(name, "applet", "marquee", "object")) {
- tb.reconstructFormattingElements();
- tb.insert(startTag);
- tb.insertMarkerToFormattingElements();
- tb.framesetOk(false);
- } else if (name.equals("table")) {
- if (tb.getDocument().quirksMode() != Document.QuirksMode.quirks && tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insert(startTag);
- tb.framesetOk(false);
- tb.transition(InTable);
- } else if (StringUtil.in(name, "area", "br", "embed", "img", "keygen", "wbr")) {
- tb.reconstructFormattingElements();
- tb.insertEmpty(startTag);
- tb.framesetOk(false);
- } else if (name.equals("input")) {
- tb.reconstructFormattingElements();
- Element el = tb.insertEmpty(startTag);
- if (!el.attr("type").equalsIgnoreCase("hidden"))
- tb.framesetOk(false);
- } else if (StringUtil.in(name, "param", "source", "track")) {
- tb.insertEmpty(startTag);
- } else if (name.equals("hr")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.insertEmpty(startTag);
- tb.framesetOk(false);
- } else if (name.equals("image")) {
- // we're not supposed to ask.
- startTag.name("img");
- return tb.process(startTag);
- } else if (name.equals("isindex")) {
- // how much do we care about the early 90s?
- tb.error(this);
- if (tb.getFormElement() != null)
- return false;
-
- tb.tokeniser.acknowledgeSelfClosingFlag();
- tb.process(new Token.StartTag("form"));
- if (startTag.attributes.hasKey("action")) {
- Element form = tb.getFormElement();
- form.attr("action", startTag.attributes.get("action"));
- }
- tb.process(new Token.StartTag("hr"));
- tb.process(new Token.StartTag("label"));
- // hope you like english.
- String prompt = startTag.attributes.hasKey("prompt") ?
- startTag.attributes.get("prompt") :
- "This is a searchable index. Enter search keywords: ";
-
- tb.process(new Token.Character(prompt));
-
- // input
- Attributes inputAttribs = new Attributes();
- for (Attribute attr : startTag.attributes) {
- if (!StringUtil.in(attr.getKey(), "name", "action", "prompt"))
- inputAttribs.put(attr);
- }
- inputAttribs.put("name", "isindex");
- tb.process(new Token.StartTag("input", inputAttribs));
- tb.process(new Token.EndTag("label"));
- tb.process(new Token.StartTag("hr"));
- tb.process(new Token.EndTag("form"));
- } else if (name.equals("textarea")) {
- tb.insert(startTag);
- // todo: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
- tb.tokeniser.transition(TokeniserState.Rcdata);
- tb.markInsertionMode();
- tb.framesetOk(false);
- tb.transition(Text);
- } else if (name.equals("xmp")) {
- if (tb.inButtonScope("p")) {
- tb.process(new Token.EndTag("p"));
- }
- tb.reconstructFormattingElements();
- tb.framesetOk(false);
- handleRawtext(startTag, tb);
- } else if (name.equals("iframe")) {
- tb.framesetOk(false);
- handleRawtext(startTag, tb);
- } else if (name.equals("noembed")) {
- // also handle noscript if script enabled
- handleRawtext(startTag, tb);
- } else if (name.equals("select")) {
- tb.reconstructFormattingElements();
- tb.insert(startTag);
- tb.framesetOk(false);
-
- HtmlTreeBuilderState state = tb.state();
- if (state.equals(InTable) || state.equals(InCaption) || state.equals(InTableBody) || state.equals(InRow) || state.equals(InCell))
- tb.transition(InSelectInTable);
- else
- tb.transition(InSelect);
- } else if (StringUtil.in("optgroup", "option")) {
- if (tb.currentElement().nodeName().equals("option"))
- tb.process(new Token.EndTag("option"));
- tb.reconstructFormattingElements();
- tb.insert(startTag);
- } else if (StringUtil.in("rp", "rt")) {
- if (tb.inScope("ruby")) {
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals("ruby")) {
- tb.error(this);
- tb.popStackToBefore("ruby"); // i.e. close up to but not include name
- }
- tb.insert(startTag);
- }
- } else if (name.equals("math")) {
- tb.reconstructFormattingElements();
- // todo: handle A start tag whose tag name is "math" (i.e. foreign, mathml)
- tb.insert(startTag);
- tb.tokeniser.acknowledgeSelfClosingFlag();
- } else if (name.equals("svg")) {
- tb.reconstructFormattingElements();
- // todo: handle A start tag whose tag name is "svg" (xlink, svg)
- tb.insert(startTag);
- tb.tokeniser.acknowledgeSelfClosingFlag();
- } else if (StringUtil.in(name,
- "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr")) {
- tb.error(this);
- return false;
- } else {
- tb.reconstructFormattingElements();
- tb.insert(startTag);
- }
- break;
-
- case EndTag:
- Token.EndTag endTag = t.asEndTag();
- name = endTag.name();
- if (name.equals("body")) {
- if (!tb.inScope("body")) {
- tb.error(this);
- return false;
- } else {
- // todo: error if stack contains something not dd, dt, li, optgroup, option, p, rp, rt, tbody, td, tfoot, th, thead, tr, body, html
- tb.transition(AfterBody);
- }
- } else if (name.equals("html")) {
- boolean notIgnored = tb.process(new Token.EndTag("body"));
- if (notIgnored)
- return tb.process(endTag);
- } else if (StringUtil.in(name,
- "address", "article", "aside", "blockquote", "button", "center", "details", "dir", "div",
- "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "listing", "menu",
- "nav", "ol", "pre", "section", "summary", "ul")) {
- // todo: refactor these lookups
- if (!tb.inScope(name)) {
- // nothing to close
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- }
- } else if (name.equals("form")) {
- Element currentForm = tb.getFormElement();
- tb.setFormElement(null);
- if (currentForm == null || !tb.inScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- // remove currentForm from stack. will shift anything under up.
- tb.removeFromStack(currentForm);
- }
- } else if (name.equals("p")) {
- if (!tb.inButtonScope(name)) {
- tb.error(this);
- tb.process(new Token.StartTag(name)); // if no p to close, creates an empty <p></p>
- return tb.process(endTag);
- } else {
- tb.generateImpliedEndTags(name);
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- }
- } else if (name.equals("li")) {
- if (!tb.inListItemScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags(name);
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- }
- } else if (StringUtil.in(name, "dd", "dt")) {
- if (!tb.inScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags(name);
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- }
- } else if (StringUtil.in(name, "h1", "h2", "h3", "h4", "h5", "h6")) {
- if (!tb.inScope(new String[]{"h1", "h2", "h3", "h4", "h5", "h6"})) {
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags(name);
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose("h1", "h2", "h3", "h4", "h5", "h6");
- }
- } else if (name.equals("sarcasm")) {
- // *sigh*
- return anyOtherEndTag(t, tb);
- } else if (StringUtil.in(name,
- "a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u")) {
- // Adoption Agency Algorithm.
- OUTER:
- for (int i = 0; i < 8; i++) {
- Element formatEl = tb.getActiveFormattingElement(name);
- if (formatEl == null)
- return anyOtherEndTag(t, tb);
- else if (!tb.onStack(formatEl)) {
- tb.error(this);
- tb.removeFromActiveFormattingElements(formatEl);
- return true;
- } else if (!tb.inScope(formatEl.nodeName())) {
- tb.error(this);
- return false;
- } else if (tb.currentElement() != formatEl)
- tb.error(this);
-
- Element furthestBlock = null;
- Element commonAncestor = null;
- boolean seenFormattingElement = false;
- LinkedList<Element> stack = tb.getStack();
- for (int si = 0; si < stack.size(); si++) {
- Element el = stack.get(si);
- if (el == formatEl) {
- commonAncestor = stack.get(si - 1);
- seenFormattingElement = true;
- } else if (seenFormattingElement && tb.isSpecial(el)) {
- furthestBlock = el;
- break;
- }
- }
- if (furthestBlock == null) {
- tb.popStackToClose(formatEl.nodeName());
- tb.removeFromActiveFormattingElements(formatEl);
- return true;
- }
-
- // todo: Let a bookmark note the position of the formatting element in the list of active formatting elements relative to the elements on either side of it in the list.
- // does that mean: int pos of format el in list?
- Element node = furthestBlock;
- Element lastNode = furthestBlock;
- INNER:
- for (int j = 0; j < 3; j++) {
- if (tb.onStack(node))
- node = tb.aboveOnStack(node);
- if (!tb.isInActiveFormattingElements(node)) { // note no bookmark check
- tb.removeFromStack(node);
- continue INNER;
- } else if (node == formatEl)
- break INNER;
-
- Element replacement = new Element(Tag.valueOf(node.nodeName()), tb.getBaseUri());
- tb.replaceActiveFormattingElement(node, replacement);
- tb.replaceOnStack(node, replacement);
- node = replacement;
-
- if (lastNode == furthestBlock) {
- // todo: move the aforementioned bookmark to be immediately after the new node in the list of active formatting elements.
- // not getting how this bookmark both straddles the element above, but is inbetween here...
- }
- if (lastNode.parent() != null)
- lastNode.remove();
- node.appendChild(lastNode);
-
- lastNode = node;
- }
-
- if (StringUtil.in(commonAncestor.nodeName(), "table", "tbody", "tfoot", "thead", "tr")) {
- if (lastNode.parent() != null)
- lastNode.remove();
- tb.insertInFosterParent(lastNode);
- } else {
- if (lastNode.parent() != null)
- lastNode.remove();
- commonAncestor.appendChild(lastNode);
- }
-
- Element adopter = new Element(Tag.valueOf(name), tb.getBaseUri());
- Node[] childNodes = furthestBlock.childNodes().toArray(new Node[furthestBlock.childNodes().size()]);
- for (Node childNode : childNodes) {
- adopter.appendChild(childNode); // append will reparent. thus the clone to avoid concurrent mod.
- }
- furthestBlock.appendChild(adopter);
- tb.removeFromActiveFormattingElements(formatEl);
- // todo: insert the new element into the list of active formatting elements at the position of the aforementioned bookmark.
- tb.removeFromStack(formatEl);
- tb.insertOnStackAfter(furthestBlock, adopter);
- }
- } else if (StringUtil.in(name, "applet", "marquee", "object")) {
- if (!tb.inScope("name")) {
- if (!tb.inScope(name)) {
- tb.error(this);
- return false;
- }
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- tb.clearFormattingElementsToLastMarker();
- }
- } else if (name.equals("br")) {
- tb.error(this);
- tb.process(new Token.StartTag("br"));
- return false;
- } else {
- return anyOtherEndTag(t, tb);
- }
-
- break;
- case EOF:
- // todo: error if stack contains something not dd, dt, li, p, tbody, td, tfoot, th, thead, tr, body, html
- // stop parsing
- break;
- }
- return true;
- }
-
- boolean anyOtherEndTag(Token t, HtmlTreeBuilder tb) {
- String name = t.asEndTag().name();
- DescendableLinkedList<Element> stack = tb.getStack();
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element node = it.next();
- if (node.nodeName().equals(name)) {
- tb.generateImpliedEndTags(name);
- if (!name.equals(tb.currentElement().nodeName()))
- tb.error(this);
- tb.popStackToClose(name);
- break;
- } else {
- if (tb.isSpecial(node)) {
- tb.error(this);
- return false;
- }
- }
- }
- return true;
- }
- },
- Text {
- // in script, style etc. normally treated as data tags
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isCharacter()) {
- tb.insert(t.asCharacter());
- } else if (t.isEOF()) {
- tb.error(this);
- // if current node is script: already started
- tb.pop();
- tb.transition(tb.originalState());
- return tb.process(t);
- } else if (t.isEndTag()) {
- // if: An end tag whose tag name is "script" -- scripting nesting level, if evaluating scripts
- tb.pop();
- tb.transition(tb.originalState());
- }
- return true;
- }
- },
- InTable {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isCharacter()) {
- tb.newPendingTableCharacters();
- tb.markInsertionMode();
- tb.transition(InTableText);
- return tb.process(t);
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- return true;
- } else if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isStartTag()) {
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
- if (name.equals("caption")) {
- tb.clearStackToTableContext();
- tb.insertMarkerToFormattingElements();
- tb.insert(startTag);
- tb.transition(InCaption);
- } else if (name.equals("colgroup")) {
- tb.clearStackToTableContext();
- tb.insert(startTag);
- tb.transition(InColumnGroup);
- } else if (name.equals("col")) {
- tb.process(new Token.StartTag("colgroup"));
- return tb.process(t);
- } else if (StringUtil.in(name, "tbody", "tfoot", "thead")) {
- tb.clearStackToTableContext();
- tb.insert(startTag);
- tb.transition(InTableBody);
- } else if (StringUtil.in(name, "td", "th", "tr")) {
- tb.process(new Token.StartTag("tbody"));
- return tb.process(t);
- } else if (name.equals("table")) {
- tb.error(this);
- boolean processed = tb.process(new Token.EndTag("table"));
- if (processed) // only ignored if in fragment
- return tb.process(t);
- } else if (StringUtil.in(name, "style", "script")) {
- return tb.process(t, InHead);
- } else if (name.equals("input")) {
- if (!startTag.attributes.get("type").equalsIgnoreCase("hidden")) {
- return anythingElse(t, tb);
- } else {
- tb.insertEmpty(startTag);
- }
- } else if (name.equals("form")) {
- tb.error(this);
- if (tb.getFormElement() != null)
- return false;
- else {
- Element form = tb.insertEmpty(startTag);
- tb.setFormElement(form);
- }
- } else {
- return anythingElse(t, tb);
- }
- } else if (t.isEndTag()) {
- Token.EndTag endTag = t.asEndTag();
- String name = endTag.name();
-
- if (name.equals("table")) {
- if (!tb.inTableScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.popStackToClose("table");
- }
- tb.resetInsertionMode();
- } else if (StringUtil.in(name,
- "body", "caption", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr")) {
- tb.error(this);
- return false;
- } else {
- return anythingElse(t, tb);
- }
- } else if (t.isEOF()) {
- if (tb.currentElement().nodeName().equals("html"))
- tb.error(this);
- return true; // stops parsing
- }
- return anythingElse(t, tb);
- }
-
- boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- tb.error(this);
- boolean processed = true;
- if (StringUtil.in(tb.currentElement().nodeName(), "table", "tbody", "tfoot", "thead", "tr")) {
- tb.setFosterInserts(true);
- processed = tb.process(t, InBody);
- tb.setFosterInserts(false);
- } else {
- processed = tb.process(t, InBody);
- }
- return processed;
- }
- },
- InTableText {
- boolean process(Token t, HtmlTreeBuilder tb) {
- switch (t.type) {
- case Character:
- Token.Character c = t.asCharacter();
- if (c.getData().equals(nullString)) {
- tb.error(this);
- return false;
- } else {
- tb.getPendingTableCharacters().add(c);
- }
- break;
- default:
- if (tb.getPendingTableCharacters().size() > 0) {
- for (Token.Character character : tb.getPendingTableCharacters()) {
- if (!isWhitespace(character)) {
- // InTable anything else section:
- tb.error(this);
- if (StringUtil.in(tb.currentElement().nodeName(), "table", "tbody", "tfoot", "thead", "tr")) {
- tb.setFosterInserts(true);
- tb.process(character, InBody);
- tb.setFosterInserts(false);
- } else {
- tb.process(character, InBody);
- }
- } else
- tb.insert(character);
- }
- tb.newPendingTableCharacters();
- }
- tb.transition(tb.originalState());
- return tb.process(t);
- }
- return true;
- }
- },
- InCaption {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isEndTag() && t.asEndTag().name().equals("caption")) {
- Token.EndTag endTag = t.asEndTag();
- String name = endTag.name();
- if (!tb.inTableScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals("caption"))
- tb.error(this);
- tb.popStackToClose("caption");
- tb.clearFormattingElementsToLastMarker();
- tb.transition(InTable);
- }
- } else if ((
- t.isStartTag() && StringUtil.in(t.asStartTag().name(),
- "caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr") ||
- t.isEndTag() && t.asEndTag().name().equals("table"))
- ) {
- tb.error(this);
- boolean processed = tb.process(new Token.EndTag("caption"));
- if (processed)
- return tb.process(t);
- } else if (t.isEndTag() && StringUtil.in(t.asEndTag().name(),
- "body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr")) {
- tb.error(this);
- return false;
- } else {
- return tb.process(t, InBody);
- }
- return true;
- }
- },
- InColumnGroup {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- tb.insert(t.asCharacter());
- return true;
- }
- switch (t.type) {
- case Comment:
- tb.insert(t.asComment());
- break;
- case Doctype:
- tb.error(this);
- break;
- case StartTag:
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
- if (name.equals("html"))
- return tb.process(t, InBody);
- else if (name.equals("col"))
- tb.insertEmpty(startTag);
- else
- return anythingElse(t, tb);
- break;
- case EndTag:
- Token.EndTag endTag = t.asEndTag();
- name = endTag.name();
- if (name.equals("colgroup")) {
- if (tb.currentElement().nodeName().equals("html")) { // frag case
- tb.error(this);
- return false;
- } else {
- tb.pop();
- tb.transition(InTable);
- }
- } else
- return anythingElse(t, tb);
- break;
- case EOF:
- if (tb.currentElement().nodeName().equals("html"))
- return true; // stop parsing; frag case
- else
- return anythingElse(t, tb);
- default:
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, TreeBuilder tb) {
- boolean processed = tb.process(new Token.EndTag("colgroup"));
- if (processed) // only ignored in frag case
- return tb.process(t);
- return true;
- }
- },
- InTableBody {
- boolean process(Token t, HtmlTreeBuilder tb) {
- switch (t.type) {
- case StartTag:
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
- if (name.equals("tr")) {
- tb.clearStackToTableBodyContext();
- tb.insert(startTag);
- tb.transition(InRow);
- } else if (StringUtil.in(name, "th", "td")) {
- tb.error(this);
- tb.process(new Token.StartTag("tr"));
- return tb.process(startTag);
- } else if (StringUtil.in(name, "caption", "col", "colgroup", "tbody", "tfoot", "thead")) {
- return exitTableBody(t, tb);
- } else
- return anythingElse(t, tb);
- break;
- case EndTag:
- Token.EndTag endTag = t.asEndTag();
- name = endTag.name();
- if (StringUtil.in(name, "tbody", "tfoot", "thead")) {
- if (!tb.inTableScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.clearStackToTableBodyContext();
- tb.pop();
- tb.transition(InTable);
- }
- } else if (name.equals("table")) {
- return exitTableBody(t, tb);
- } else if (StringUtil.in(name, "body", "caption", "col", "colgroup", "html", "td", "th", "tr")) {
- tb.error(this);
- return false;
- } else
- return anythingElse(t, tb);
- break;
- default:
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean exitTableBody(Token t, HtmlTreeBuilder tb) {
- if (!(tb.inTableScope("tbody") || tb.inTableScope("thead") || tb.inScope("tfoot"))) {
- // frag case
- tb.error(this);
- return false;
- }
- tb.clearStackToTableBodyContext();
- tb.process(new Token.EndTag(tb.currentElement().nodeName())); // tbody, tfoot, thead
- return tb.process(t);
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- return tb.process(t, InTable);
- }
- },
- InRow {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isStartTag()) {
- Token.StartTag startTag = t.asStartTag();
- String name = startTag.name();
-
- if (StringUtil.in(name, "th", "td")) {
- tb.clearStackToTableRowContext();
- tb.insert(startTag);
- tb.transition(InCell);
- tb.insertMarkerToFormattingElements();
- } else if (StringUtil.in(name, "caption", "col", "colgroup", "tbody", "tfoot", "thead", "tr")) {
- return handleMissingTr(t, tb);
- } else {
- return anythingElse(t, tb);
- }
- } else if (t.isEndTag()) {
- Token.EndTag endTag = t.asEndTag();
- String name = endTag.name();
-
- if (name.equals("tr")) {
- if (!tb.inTableScope(name)) {
- tb.error(this); // frag
- return false;
- }
- tb.clearStackToTableRowContext();
- tb.pop(); // tr
- tb.transition(InTableBody);
- } else if (name.equals("table")) {
- return handleMissingTr(t, tb);
- } else if (StringUtil.in(name, "tbody", "tfoot", "thead")) {
- if (!tb.inTableScope(name)) {
- tb.error(this);
- return false;
- }
- tb.process(new Token.EndTag("tr"));
- return tb.process(t);
- } else if (StringUtil.in(name, "body", "caption", "col", "colgroup", "html", "td", "th")) {
- tb.error(this);
- return false;
- } else {
- return anythingElse(t, tb);
- }
- } else {
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- return tb.process(t, InTable);
- }
-
- private boolean handleMissingTr(Token t, TreeBuilder tb) {
- boolean processed = tb.process(new Token.EndTag("tr"));
- if (processed)
- return tb.process(t);
- else
- return false;
- }
- },
- InCell {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isEndTag()) {
- Token.EndTag endTag = t.asEndTag();
- String name = endTag.name();
-
- if (StringUtil.in(name, "td", "th")) {
- if (!tb.inTableScope(name)) {
- tb.error(this);
- tb.transition(InRow); // might not be in scope if empty: <td /> and processing fake end tag
- return false;
- }
- tb.generateImpliedEndTags();
- if (!tb.currentElement().nodeName().equals(name))
- tb.error(this);
- tb.popStackToClose(name);
- tb.clearFormattingElementsToLastMarker();
- tb.transition(InRow);
- } else if (StringUtil.in(name, "body", "caption", "col", "colgroup", "html")) {
- tb.error(this);
- return false;
- } else if (StringUtil.in(name, "table", "tbody", "tfoot", "thead", "tr")) {
- if (!tb.inTableScope(name)) {
- tb.error(this);
- return false;
- }
- closeCell(tb);
- return tb.process(t);
- } else {
- return anythingElse(t, tb);
- }
- } else if (t.isStartTag() &&
- StringUtil.in(t.asStartTag().name(),
- "caption", "col", "colgroup", "tbody", "td", "tfoot", "th", "thead", "tr")) {
- if (!(tb.inTableScope("td") || tb.inTableScope("th"))) {
- tb.error(this);
- return false;
- }
- closeCell(tb);
- return tb.process(t);
- } else {
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- return tb.process(t, InBody);
- }
-
- private void closeCell(HtmlTreeBuilder tb) {
- if (tb.inTableScope("td"))
- tb.process(new Token.EndTag("td"));
- else
- tb.process(new Token.EndTag("th")); // only here if th or td in scope
- }
- },
- InSelect {
- boolean process(Token t, HtmlTreeBuilder tb) {
- switch (t.type) {
- case Character:
- Token.Character c = t.asCharacter();
- if (c.getData().equals(nullString)) {
- tb.error(this);
- return false;
- } else {
- tb.insert(c);
- }
- break;
- case Comment:
- tb.insert(t.asComment());
- break;
- case Doctype:
- tb.error(this);
- return false;
- case StartTag:
- Token.StartTag start = t.asStartTag();
- String name = start.name();
- if (name.equals("html"))
- return tb.process(start, InBody);
- else if (name.equals("option")) {
- tb.process(new Token.EndTag("option"));
- tb.insert(start);
- } else if (name.equals("optgroup")) {
- if (tb.currentElement().nodeName().equals("option"))
- tb.process(new Token.EndTag("option"));
- else if (tb.currentElement().nodeName().equals("optgroup"))
- tb.process(new Token.EndTag("optgroup"));
- tb.insert(start);
- } else if (name.equals("select")) {
- tb.error(this);
- return tb.process(new Token.EndTag("select"));
- } else if (StringUtil.in(name, "input", "keygen", "textarea")) {
- tb.error(this);
- if (!tb.inSelectScope("select"))
- return false; // frag
- tb.process(new Token.EndTag("select"));
- return tb.process(start);
- } else if (name.equals("script")) {
- return tb.process(t, InHead);
- } else {
- return anythingElse(t, tb);
- }
- break;
- case EndTag:
- Token.EndTag end = t.asEndTag();
- name = end.name();
- if (name.equals("optgroup")) {
- if (tb.currentElement().nodeName().equals("option") && tb.aboveOnStack(tb.currentElement()) != null && tb.aboveOnStack(tb.currentElement()).nodeName().equals("optgroup"))
- tb.process(new Token.EndTag("option"));
- if (tb.currentElement().nodeName().equals("optgroup"))
- tb.pop();
- else
- tb.error(this);
- } else if (name.equals("option")) {
- if (tb.currentElement().nodeName().equals("option"))
- tb.pop();
- else
- tb.error(this);
- } else if (name.equals("select")) {
- if (!tb.inSelectScope(name)) {
- tb.error(this);
- return false;
- } else {
- tb.popStackToClose(name);
- tb.resetInsertionMode();
- }
- } else
- return anythingElse(t, tb);
- break;
- case EOF:
- if (!tb.currentElement().nodeName().equals("html"))
- tb.error(this);
- break;
- default:
- return anythingElse(t, tb);
- }
- return true;
- }
-
- private boolean anythingElse(Token t, HtmlTreeBuilder tb) {
- tb.error(this);
- return false;
- }
- },
- InSelectInTable {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isStartTag() && StringUtil.in(t.asStartTag().name(), "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th")) {
- tb.error(this);
- tb.process(new Token.EndTag("select"));
- return tb.process(t);
- } else if (t.isEndTag() && StringUtil.in(t.asEndTag().name(), "caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th")) {
- tb.error(this);
- if (tb.inTableScope(t.asEndTag().name())) {
- tb.process(new Token.EndTag("select"));
- return (tb.process(t));
- } else
- return false;
- } else {
- return tb.process(t, InSelect);
- }
- }
- },
- AfterBody {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- return tb.process(t, InBody);
- } else if (t.isComment()) {
- tb.insert(t.asComment()); // into html node
- } else if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
- return tb.process(t, InBody);
- } else if (t.isEndTag() && t.asEndTag().name().equals("html")) {
- if (tb.isFragmentParsing()) {
- tb.error(this);
- return false;
- } else {
- tb.transition(AfterAfterBody);
- }
- } else if (t.isEOF()) {
- // chillax! we're done
- } else {
- tb.error(this);
- tb.transition(InBody);
- return tb.process(t);
- }
- return true;
- }
- },
- InFrameset {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- tb.insert(t.asCharacter());
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isStartTag()) {
- Token.StartTag start = t.asStartTag();
- String name = start.name();
- if (name.equals("html")) {
- return tb.process(start, InBody);
- } else if (name.equals("frameset")) {
- tb.insert(start);
- } else if (name.equals("frame")) {
- tb.insertEmpty(start);
- } else if (name.equals("noframes")) {
- return tb.process(start, InHead);
- } else {
- tb.error(this);
- return false;
- }
- } else if (t.isEndTag() && t.asEndTag().name().equals("frameset")) {
- if (tb.currentElement().nodeName().equals("html")) { // frag
- tb.error(this);
- return false;
- } else {
- tb.pop();
- if (!tb.isFragmentParsing() && !tb.currentElement().nodeName().equals("frameset")) {
- tb.transition(AfterFrameset);
- }
- }
- } else if (t.isEOF()) {
- if (!tb.currentElement().nodeName().equals("html")) {
- tb.error(this);
- return true;
- }
- } else {
- tb.error(this);
- return false;
- }
- return true;
- }
- },
- AfterFrameset {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (isWhitespace(t)) {
- tb.insert(t.asCharacter());
- } else if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype()) {
- tb.error(this);
- return false;
- } else if (t.isStartTag() && t.asStartTag().name().equals("html")) {
- return tb.process(t, InBody);
- } else if (t.isEndTag() && t.asEndTag().name().equals("html")) {
- tb.transition(AfterAfterFrameset);
- } else if (t.isStartTag() && t.asStartTag().name().equals("noframes")) {
- return tb.process(t, InHead);
- } else if (t.isEOF()) {
- // cool your heels, we're complete
- } else {
- tb.error(this);
- return false;
- }
- return true;
- }
- },
- AfterAfterBody {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype() || isWhitespace(t) || (t.isStartTag() && t.asStartTag().name().equals("html"))) {
- return tb.process(t, InBody);
- } else if (t.isEOF()) {
- // nice work chuck
- } else {
- tb.error(this);
- tb.transition(InBody);
- return tb.process(t);
- }
- return true;
- }
- },
- AfterAfterFrameset {
- boolean process(Token t, HtmlTreeBuilder tb) {
- if (t.isComment()) {
- tb.insert(t.asComment());
- } else if (t.isDoctype() || isWhitespace(t) || (t.isStartTag() && t.asStartTag().name().equals("html"))) {
- return tb.process(t, InBody);
- } else if (t.isEOF()) {
- // nice work chuck
- } else if (t.isStartTag() && t.asStartTag().name().equals("noframes")) {
- return tb.process(t, InHead);
- } else {
- tb.error(this);
- return false;
- }
- return true;
- }
- },
- ForeignContent {
- boolean process(Token t, HtmlTreeBuilder tb) {
- return true;
- // todo: implement. Also; how do we get here?
- }
- };
-
- private static String nullString = String.valueOf('\u0000');
-
- abstract boolean process(Token t, HtmlTreeBuilder tb);
-
- private static boolean isWhitespace(Token t) {
- if (t.isCharacter()) {
- String data = t.asCharacter().getData();
- // todo: this checks more than spec - "\t", "\n", "\f", "\r", " "
- for (int i = 0; i < data.length(); i++) {
- char c = data.charAt(i);
- if (!StringUtil.isWhitespace(c))
- return false;
- }
- return true;
- }
- return false;
- }
-
- private static void handleRcData(Token.StartTag startTag, HtmlTreeBuilder tb) {
- tb.insert(startTag);
- tb.tokeniser.transition(TokeniserState.Rcdata);
- tb.markInsertionMode();
- tb.transition(Text);
- }
-
- private static void handleRawtext(Token.StartTag startTag, HtmlTreeBuilder tb) {
- tb.insert(startTag);
- tb.tokeniser.transition(TokeniserState.Rawtext);
- tb.markInsertionMode();
- tb.transition(Text);
- }
-}
diff --git a/src/org/jsoup/parser/ParseError.java b/src/org/jsoup/parser/ParseError.java
deleted file mode 100644
index dfa090051b..0000000000
--- a/src/org/jsoup/parser/ParseError.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.jsoup.parser;
-
-/**
- * A Parse Error records an error in the input HTML that occurs in either the tokenisation or the tree building phase.
- */
-public class ParseError {
- private int pos;
- private String errorMsg;
-
- ParseError(int pos, String errorMsg) {
- this.pos = pos;
- this.errorMsg = errorMsg;
- }
-
- ParseError(int pos, String errorFormat, Object... args) {
- this.errorMsg = String.format(errorFormat, args);
- this.pos = pos;
- }
-
- /**
- * Retrieve the error message.
- * @return the error message.
- */
- public String getErrorMessage() {
- return errorMsg;
- }
-
- /**
- * Retrieves the offset of the error.
- * @return error offset within input
- */
- public int getPosition() {
- return pos;
- }
-
- @Override
- public String toString() {
- return pos + ": " + errorMsg;
- }
-}
diff --git a/src/org/jsoup/parser/ParseErrorList.java b/src/org/jsoup/parser/ParseErrorList.java
deleted file mode 100644
index 3824ffbc4e..0000000000
--- a/src/org/jsoup/parser/ParseErrorList.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.jsoup.parser;
-
-import java.util.ArrayList;
-
-/**
- * A container for ParseErrors.
- *
- * @author Jonathan Hedley
- */
-class ParseErrorList extends ArrayList<ParseError>{
- private static final int INITIAL_CAPACITY = 16;
- private final int maxSize;
-
- ParseErrorList(int initialCapacity, int maxSize) {
- super(initialCapacity);
- this.maxSize = maxSize;
- }
-
- boolean canAddError() {
- return size() < maxSize;
- }
-
- int getMaxSize() {
- return maxSize;
- }
-
- static ParseErrorList noTracking() {
- return new ParseErrorList(0, 0);
- }
-
- static ParseErrorList tracking(int maxSize) {
- return new ParseErrorList(INITIAL_CAPACITY, maxSize);
- }
-}
diff --git a/src/org/jsoup/parser/Parser.java b/src/org/jsoup/parser/Parser.java
deleted file mode 100644
index 2236219c06..0000000000
--- a/src/org/jsoup/parser/Parser.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-
-import java.util.List;
-
-/**
- * Parses HTML into a {@link org.jsoup.nodes.Document}. Generally best to use one of the more convenient parse methods
- * in {@link org.jsoup.Jsoup}.
- */
-public class Parser {
- private static final int DEFAULT_MAX_ERRORS = 0; // by default, error tracking is disabled.
-
- private TreeBuilder treeBuilder;
- private int maxErrors = DEFAULT_MAX_ERRORS;
- private ParseErrorList errors;
-
- /**
- * Create a new Parser, using the specified TreeBuilder
- * @param treeBuilder TreeBuilder to use to parse input into Documents.
- */
- public Parser(TreeBuilder treeBuilder) {
- this.treeBuilder = treeBuilder;
- }
-
- public Document parseInput(String html, String baseUri) {
- errors = isTrackErrors() ? ParseErrorList.tracking(maxErrors) : ParseErrorList.noTracking();
- Document doc = treeBuilder.parse(html, baseUri, errors);
- return doc;
- }
-
- // gets & sets
- /**
- * Get the TreeBuilder currently in use.
- * @return current TreeBuilder.
- */
- public TreeBuilder getTreeBuilder() {
- return treeBuilder;
- }
-
- /**
- * Update the TreeBuilder used when parsing content.
- * @param treeBuilder current TreeBuilder
- * @return this, for chaining
- */
- public Parser setTreeBuilder(TreeBuilder treeBuilder) {
- this.treeBuilder = treeBuilder;
- return this;
- }
-
- /**
- * Check if parse error tracking is enabled.
- * @return current track error state.
- */
- public boolean isTrackErrors() {
- return maxErrors > 0;
- }
-
- /**
- * Enable or disable parse error tracking for the next parse.
- * @param maxErrors the maximum number of errors to track. Set to 0 to disable.
- * @return this, for chaining
- */
- public Parser setTrackErrors(int maxErrors) {
- this.maxErrors = maxErrors;
- return this;
- }
-
- /**
- * Retrieve the parse errors, if any, from the last parse.
- * @return list of parse errors, up to the size of the maximum errors tracked.
- */
- public List<ParseError> getErrors() {
- return errors;
- }
-
- // static parse functions below
- /**
- * Parse HTML into a Document.
- *
- * @param html HTML to parse
- * @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
- *
- * @return parsed Document
- */
- public static Document parse(String html, String baseUri) {
- TreeBuilder treeBuilder = new HtmlTreeBuilder();
- return treeBuilder.parse(html, baseUri, ParseErrorList.noTracking());
- }
-
- /**
- * Parse a fragment of HTML into a list of nodes. The context element, if supplied, supplies parsing context.
- *
- * @param fragmentHtml the fragment of HTML to parse
- * @param context (optional) the element that this HTML fragment is being parsed for (i.e. for inner HTML). This
- * provides stack context (for implicit element creation).
- * @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
- *
- * @return list of nodes parsed from the input HTML. Note that the context element, if supplied, is not modified.
- */
- public static List<Node> parseFragment(String fragmentHtml, Element context, String baseUri) {
- HtmlTreeBuilder treeBuilder = new HtmlTreeBuilder();
- return treeBuilder.parseFragment(fragmentHtml, context, baseUri, ParseErrorList.noTracking());
- }
-
- /**
- * Parse a fragment of HTML into the {@code body} of a Document.
- *
- * @param bodyHtml fragment of HTML
- * @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
- *
- * @return Document, with empty head, and HTML parsed into body
- */
- public static Document parseBodyFragment(String bodyHtml, String baseUri) {
- Document doc = Document.createShell(baseUri);
- Element body = doc.body();
- List<Node> nodeList = parseFragment(bodyHtml, body, baseUri);
- Node[] nodes = nodeList.toArray(new Node[nodeList.size()]); // the node list gets modified when re-parented
- for (Node node : nodes) {
- body.appendChild(node);
- }
- return doc;
- }
-
- /**
- * @param bodyHtml HTML to parse
- * @param baseUri baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
- *
- * @return parsed Document
- * @deprecated Use {@link #parseBodyFragment} or {@link #parseFragment} instead.
- */
- public static Document parseBodyFragmentRelaxed(String bodyHtml, String baseUri) {
- return parse(bodyHtml, baseUri);
- }
-
- // builders
-
- /**
- * Create a new HTML parser. This parser treats input as HTML5, and enforces the creation of a normalised document,
- * based on a knowledge of the semantics of the incoming tags.
- * @return a new HTML parser.
- */
- public static Parser htmlParser() {
- return new Parser(new HtmlTreeBuilder());
- }
-
- /**
- * Create a new XML parser. This parser assumes no knowledge of the incoming tags and does not treat it as HTML,
- * rather creates a simple tree directly from the input.
- * @return a new simple XML parser.
- */
- public static Parser xmlParser() {
- return new Parser(new XmlTreeBuilder());
- }
-}
diff --git a/src/org/jsoup/parser/Tag.java b/src/org/jsoup/parser/Tag.java
deleted file mode 100644
index 40b7557b39..0000000000
--- a/src/org/jsoup/parser/Tag.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.Validate;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * HTML Tag capabilities.
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- */
-public class Tag {
- private static final Map<String, Tag> tags = new HashMap<String, Tag>(); // map of known tags
-
- private String tagName;
- private boolean isBlock = true; // block or inline
- private boolean formatAsBlock = true; // should be formatted as a block
- private boolean canContainBlock = true; // Can this tag hold block level tags?
- private boolean canContainInline = true; // only pcdata if not
- private boolean empty = false; // can hold nothing; e.g. img
- private boolean selfClosing = false; // can self close (<foo />). used for unknown tags that self close, without forcing them as empty.
- private boolean preserveWhitespace = false; // for pre, textarea, script etc
-
- private Tag(String tagName) {
- this.tagName = tagName.toLowerCase();
- }
-
- /**
- * Get this tag's name.
- *
- * @return the tag's name
- */
- public String getName() {
- return tagName;
- }
-
- /**
- * Get a Tag by name. If not previously defined (unknown), returns a new generic tag, that can do anything.
- * <p/>
- * Pre-defined tags (P, DIV etc) will be ==, but unknown tags are not registered and will only .equals().
- *
- * @param tagName Name of tag, e.g. "p". Case insensitive.
- * @return The tag, either defined or new generic.
- */
- public static Tag valueOf(String tagName) {
- Validate.notNull(tagName);
- tagName = tagName.trim().toLowerCase();
- Validate.notEmpty(tagName);
-
- synchronized (tags) {
- Tag tag = tags.get(tagName);
- if (tag == null) {
- // not defined: create default; go anywhere, do anything! (incl be inside a <p>)
- tag = new Tag(tagName);
- tag.isBlock = false;
- tag.canContainBlock = true;
- }
- return tag;
- }
- }
-
- /**
- * Gets if this is a block tag.
- *
- * @return if block tag
- */
- public boolean isBlock() {
- return isBlock;
- }
-
- /**
- * Gets if this tag should be formatted as a block (or as inline)
- *
- * @return if should be formatted as block or inline
- */
- public boolean formatAsBlock() {
- return formatAsBlock;
- }
-
- /**
- * Gets if this tag can contain block tags.
- *
- * @return if tag can contain block tags
- */
- public boolean canContainBlock() {
- return canContainBlock;
- }
-
- /**
- * Gets if this tag is an inline tag.
- *
- * @return if this tag is an inline tag.
- */
- public boolean isInline() {
- return !isBlock;
- }
-
- /**
- * Gets if this tag is a data only tag.
- *
- * @return if this tag is a data only tag
- */
- public boolean isData() {
- return !canContainInline && !isEmpty();
- }
-
- /**
- * Get if this is an empty tag
- *
- * @return if this is an empty tag
- */
- public boolean isEmpty() {
- return empty;
- }
-
- /**
- * Get if this tag is self closing.
- *
- * @return if this tag should be output as self closing.
- */
- public boolean isSelfClosing() {
- return empty || selfClosing;
- }
-
- /**
- * Get if this is a pre-defined tag, or was auto created on parsing.
- *
- * @return if a known tag
- */
- public boolean isKnownTag() {
- return tags.containsKey(tagName);
- }
-
- /**
- * Check if this tagname is a known tag.
- *
- * @param tagName name of tag
- * @return if known HTML tag
- */
- public static boolean isKnownTag(String tagName) {
- return tags.containsKey(tagName);
- }
-
- /**
- * Get if this tag should preserve whitespace within child text nodes.
- *
- * @return if preserve whitepace
- */
- public boolean preserveWhitespace() {
- return preserveWhitespace;
- }
-
- Tag setSelfClosing() {
- selfClosing = true;
- return this;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof Tag)) return false;
-
- Tag tag = (Tag) o;
-
- if (canContainBlock != tag.canContainBlock) return false;
- if (canContainInline != tag.canContainInline) return false;
- if (empty != tag.empty) return false;
- if (formatAsBlock != tag.formatAsBlock) return false;
- if (isBlock != tag.isBlock) return false;
- if (preserveWhitespace != tag.preserveWhitespace) return false;
- if (selfClosing != tag.selfClosing) return false;
- if (!tagName.equals(tag.tagName)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = tagName.hashCode();
- result = 31 * result + (isBlock ? 1 : 0);
- result = 31 * result + (formatAsBlock ? 1 : 0);
- result = 31 * result + (canContainBlock ? 1 : 0);
- result = 31 * result + (canContainInline ? 1 : 0);
- result = 31 * result + (empty ? 1 : 0);
- result = 31 * result + (selfClosing ? 1 : 0);
- result = 31 * result + (preserveWhitespace ? 1 : 0);
- return result;
- }
-
- public String toString() {
- return tagName;
- }
-
- // internal static initialisers:
- // prepped from http://www.w3.org/TR/REC-html40/sgml/dtd.html and other sources
- private static final String[] blockTags = {
- "html", "head", "body", "frameset", "script", "noscript", "style", "meta", "link", "title", "frame",
- "noframes", "section", "nav", "aside", "hgroup", "header", "footer", "p", "h1", "h2", "h3", "h4", "h5", "h6",
- "ul", "ol", "pre", "div", "blockquote", "hr", "address", "figure", "figcaption", "form", "fieldset", "ins",
- "del", "dl", "dt", "dd", "li", "table", "caption", "thead", "tfoot", "tbody", "colgroup", "col", "tr", "th",
- "td", "video", "audio", "canvas", "details", "menu", "plaintext"
- };
- private static final String[] inlineTags = {
- "object", "base", "font", "tt", "i", "b", "u", "big", "small", "em", "strong", "dfn", "code", "samp", "kbd",
- "var", "cite", "abbr", "time", "acronym", "mark", "ruby", "rt", "rp", "a", "img", "br", "wbr", "map", "q",
- "sub", "sup", "bdo", "iframe", "embed", "span", "input", "select", "textarea", "label", "button", "optgroup",
- "option", "legend", "datalist", "keygen", "output", "progress", "meter", "area", "param", "source", "track",
- "summary", "command", "device"
- };
- private static final String[] emptyTags = {
- "meta", "link", "base", "frame", "img", "br", "wbr", "embed", "hr", "input", "keygen", "col", "command",
- "device"
- };
- private static final String[] formatAsInlineTags = {
- "title", "a", "p", "h1", "h2", "h3", "h4", "h5", "h6", "pre", "address", "li", "th", "td", "script", "style"
- };
- private static final String[] preserveWhitespaceTags = {"pre", "plaintext", "title"};
-
- static {
- // creates
- for (String tagName : blockTags) {
- Tag tag = new Tag(tagName);
- register(tag);
- }
- for (String tagName : inlineTags) {
- Tag tag = new Tag(tagName);
- tag.isBlock = false;
- tag.canContainBlock = false;
- tag.formatAsBlock = false;
- register(tag);
- }
-
- // mods:
- for (String tagName : emptyTags) {
- Tag tag = tags.get(tagName);
- Validate.notNull(tag);
- tag.canContainBlock = false;
- tag.canContainInline = false;
- tag.empty = true;
- }
-
- for (String tagName : formatAsInlineTags) {
- Tag tag = tags.get(tagName);
- Validate.notNull(tag);
- tag.formatAsBlock = false;
- }
-
- for (String tagName : preserveWhitespaceTags) {
- Tag tag = tags.get(tagName);
- Validate.notNull(tag);
- tag.preserveWhitespace = true;
- }
- }
-
- private static Tag register(Tag tag) {
- synchronized (tags) {
- tags.put(tag.tagName, tag);
- }
- return tag;
- }
-}
diff --git a/src/org/jsoup/parser/Token.java b/src/org/jsoup/parser/Token.java
deleted file mode 100644
index 9f4f9e250d..0000000000
--- a/src/org/jsoup/parser/Token.java
+++ /dev/null
@@ -1,252 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Attribute;
-import org.jsoup.nodes.Attributes;
-
-/**
- * Parse tokens for the Tokeniser.
- */
-abstract class Token {
- TokenType type;
-
- private Token() {
- }
-
- String tokenType() {
- return this.getClass().getSimpleName();
- }
-
- static class Doctype extends Token {
- final StringBuilder name = new StringBuilder();
- final StringBuilder publicIdentifier = new StringBuilder();
- final StringBuilder systemIdentifier = new StringBuilder();
- boolean forceQuirks = false;
-
- Doctype() {
- type = TokenType.Doctype;
- }
-
- String getName() {
- return name.toString();
- }
-
- String getPublicIdentifier() {
- return publicIdentifier.toString();
- }
-
- public String getSystemIdentifier() {
- return systemIdentifier.toString();
- }
-
- public boolean isForceQuirks() {
- return forceQuirks;
- }
- }
-
- static abstract class Tag extends Token {
- protected String tagName;
- private String pendingAttributeName;
- private String pendingAttributeValue;
-
- boolean selfClosing = false;
- Attributes attributes = new Attributes(); // todo: allow nodes to not have attributes
-
- void newAttribute() {
- if (pendingAttributeName != null) {
- if (pendingAttributeValue == null)
- pendingAttributeValue = "";
- Attribute attribute = new Attribute(pendingAttributeName, pendingAttributeValue);
- attributes.put(attribute);
- }
- pendingAttributeName = null;
- pendingAttributeValue = null;
- }
-
- void finaliseTag() {
- // finalises for emit
- if (pendingAttributeName != null) {
- // todo: check if attribute name exists; if so, drop and error
- newAttribute();
- }
- }
-
- String name() {
- Validate.isFalse(tagName.length() == 0);
- return tagName;
- }
-
- Tag name(String name) {
- tagName = name;
- return this;
- }
-
- boolean isSelfClosing() {
- return selfClosing;
- }
-
- @SuppressWarnings({"TypeMayBeWeakened"})
- Attributes getAttributes() {
- return attributes;
- }
-
- // these appenders are rarely hit in not null state-- caused by null chars.
- void appendTagName(String append) {
- tagName = tagName == null ? append : tagName.concat(append);
- }
-
- void appendTagName(char append) {
- appendTagName(String.valueOf(append));
- }
-
- void appendAttributeName(String append) {
- pendingAttributeName = pendingAttributeName == null ? append : pendingAttributeName.concat(append);
- }
-
- void appendAttributeName(char append) {
- appendAttributeName(String.valueOf(append));
- }
-
- void appendAttributeValue(String append) {
- pendingAttributeValue = pendingAttributeValue == null ? append : pendingAttributeValue.concat(append);
- }
-
- void appendAttributeValue(char append) {
- appendAttributeValue(String.valueOf(append));
- }
- }
-
- static class StartTag extends Tag {
- StartTag() {
- super();
- type = TokenType.StartTag;
- }
-
- StartTag(String name) {
- this();
- this.tagName = name;
- }
-
- StartTag(String name, Attributes attributes) {
- this();
- this.tagName = name;
- this.attributes = attributes;
- }
-
- @Override
- public String toString() {
- return "<" + name() + " " + attributes.toString() + ">";
- }
- }
-
- static class EndTag extends Tag{
- EndTag() {
- super();
- type = TokenType.EndTag;
- }
-
- EndTag(String name) {
- this();
- this.tagName = name;
- }
-
- @Override
- public String toString() {
- return "</" + name() + " " + attributes.toString() + ">";
- }
- }
-
- static class Comment extends Token {
- final StringBuilder data = new StringBuilder();
-
- Comment() {
- type = TokenType.Comment;
- }
-
- String getData() {
- return data.toString();
- }
-
- @Override
- public String toString() {
- return "<!--" + getData() + "-->";
- }
- }
-
- static class Character extends Token {
- private final String data;
-
- Character(String data) {
- type = TokenType.Character;
- this.data = data;
- }
-
- String getData() {
- return data;
- }
-
- @Override
- public String toString() {
- return getData();
- }
- }
-
- static class EOF extends Token {
- EOF() {
- type = Token.TokenType.EOF;
- }
- }
-
- boolean isDoctype() {
- return type == TokenType.Doctype;
- }
-
- Doctype asDoctype() {
- return (Doctype) this;
- }
-
- boolean isStartTag() {
- return type == TokenType.StartTag;
- }
-
- StartTag asStartTag() {
- return (StartTag) this;
- }
-
- boolean isEndTag() {
- return type == TokenType.EndTag;
- }
-
- EndTag asEndTag() {
- return (EndTag) this;
- }
-
- boolean isComment() {
- return type == TokenType.Comment;
- }
-
- Comment asComment() {
- return (Comment) this;
- }
-
- boolean isCharacter() {
- return type == TokenType.Character;
- }
-
- Character asCharacter() {
- return (Character) this;
- }
-
- boolean isEOF() {
- return type == TokenType.EOF;
- }
-
- enum TokenType {
- Doctype,
- StartTag,
- EndTag,
- Comment,
- Character,
- EOF
- }
-}
diff --git a/src/org/jsoup/parser/TokenQueue.java b/src/org/jsoup/parser/TokenQueue.java
deleted file mode 100644
index a2fdfe621a..0000000000
--- a/src/org/jsoup/parser/TokenQueue.java
+++ /dev/null
@@ -1,393 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-
-/**
- * A character queue with parsing helpers.
- *
- * @author Jonathan Hedley
- */
-public class TokenQueue {
- private String queue;
- private int pos = 0;
-
- private static final char ESC = '\\'; // escape char for chomp balanced.
-
- /**
- Create a new TokenQueue.
- @param data string of data to back queue.
- */
- public TokenQueue(String data) {
- Validate.notNull(data);
- queue = data;
- }
-
- /**
- * Is the queue empty?
- * @return true if no data left in queue.
- */
- public boolean isEmpty() {
- return remainingLength() == 0;
- }
-
- private int remainingLength() {
- return queue.length() - pos;
- }
-
- /**
- * Retrieves but does not remove the first character from the queue.
- * @return First character, or 0 if empty.
- */
- public char peek() {
- return isEmpty() ? 0 : queue.charAt(pos);
- }
-
- /**
- Add a character to the start of the queue (will be the next character retrieved).
- @param c character to add
- */
- public void addFirst(Character c) {
- addFirst(c.toString());
- }
-
- /**
- Add a string to the start of the queue.
- @param seq string to add.
- */
- public void addFirst(String seq) {
- // not very performant, but an edge case
- queue = seq + queue.substring(pos);
- pos = 0;
- }
-
- /**
- * Tests if the next characters on the queue match the sequence. Case insensitive.
- * @param seq String to check queue for.
- * @return true if the next characters match.
- */
- public boolean matches(String seq) {
- return queue.regionMatches(true, pos, seq, 0, seq.length());
- }
-
- /**
- * Case sensitive match test.
- * @param seq string to case sensitively check for
- * @return true if matched, false if not
- */
- public boolean matchesCS(String seq) {
- return queue.startsWith(seq, pos);
- }
-
-
- /**
- Tests if the next characters match any of the sequences. Case insensitive.
- @param seq list of strings to case insensitively check for
- @return true of any matched, false if none did
- */
- public boolean matchesAny(String... seq) {
- for (String s : seq) {
- if (matches(s))
- return true;
- }
- return false;
- }
-
- public boolean matchesAny(char... seq) {
- if (isEmpty())
- return false;
-
- for (char c: seq) {
- if (queue.charAt(pos) == c)
- return true;
- }
- return false;
- }
-
- public boolean matchesStartTag() {
- // micro opt for matching "<x"
- return (remainingLength() >= 2 && queue.charAt(pos) == '<' && Character.isLetter(queue.charAt(pos+1)));
- }
-
- /**
- * Tests if the queue matches the sequence (as with match), and if they do, removes the matched string from the
- * queue.
- * @param seq String to search for, and if found, remove from queue.
- * @return true if found and removed, false if not found.
- */
- public boolean matchChomp(String seq) {
- if (matches(seq)) {
- pos += seq.length();
- return true;
- } else {
- return false;
- }
- }
-
- /**
- Tests if queue starts with a whitespace character.
- @return if starts with whitespace
- */
- public boolean matchesWhitespace() {
- return !isEmpty() && StringUtil.isWhitespace(queue.charAt(pos));
- }
-
- /**
- Test if the queue matches a word character (letter or digit).
- @return if matches a word character
- */
- public boolean matchesWord() {
- return !isEmpty() && Character.isLetterOrDigit(queue.charAt(pos));
- }
-
- /**
- * Drops the next character off the queue.
- */
- public void advance() {
- if (!isEmpty()) pos++;
- }
-
- /**
- * Consume one character off queue.
- * @return first character on queue.
- */
- public char consume() {
- return queue.charAt(pos++);
- }
-
- /**
- * Consumes the supplied sequence of the queue. If the queue does not start with the supplied sequence, will
- * throw an illegal state exception -- but you should be running match() against that condition.
- <p>
- Case insensitive.
- * @param seq sequence to remove from head of queue.
- */
- public void consume(String seq) {
- if (!matches(seq))
- throw new IllegalStateException("Queue did not match expected sequence");
- int len = seq.length();
- if (len > remainingLength())
- throw new IllegalStateException("Queue not long enough to consume sequence");
-
- pos += len;
- }
-
- /**
- * Pulls a string off the queue, up to but exclusive of the match sequence, or to the queue running out.
- * @param seq String to end on (and not include in return, but leave on queue). <b>Case sensitive.</b>
- * @return The matched data consumed from queue.
- */
- public String consumeTo(String seq) {
- int offset = queue.indexOf(seq, pos);
- if (offset != -1) {
- String consumed = queue.substring(pos, offset);
- pos += consumed.length();
- return consumed;
- } else {
- return remainder();
- }
- }
-
- public String consumeToIgnoreCase(String seq) {
- int start = pos;
- String first = seq.substring(0, 1);
- boolean canScan = first.toLowerCase().equals(first.toUpperCase()); // if first is not cased, use index of
- while (!isEmpty()) {
- if (matches(seq))
- break;
-
- if (canScan) {
- int skip = queue.indexOf(first, pos) - pos;
- if (skip == 0) // this char is the skip char, but not match, so force advance of pos
- pos++;
- else if (skip < 0) // no chance of finding, grab to end
- pos = queue.length();
- else
- pos += skip;
- }
- else
- pos++;
- }
-
- String data = queue.substring(start, pos);
- return data;
- }
-
- /**
- Consumes to the first sequence provided, or to the end of the queue. Leaves the terminator on the queue.
- @param seq any number of terminators to consume to. <b>Case insensitive.</b>
- @return consumed string
- */
- // todo: method name. not good that consumeTo cares for case, and consume to any doesn't. And the only use for this
- // is is a case sensitive time...
- public String consumeToAny(String... seq) {
- int start = pos;
- while (!isEmpty() && !matchesAny(seq)) {
- pos++;
- }
-
- String data = queue.substring(start, pos);
- return data;
- }
-
- /**
- * Pulls a string off the queue (like consumeTo), and then pulls off the matched string (but does not return it).
- * <p>
- * If the queue runs out of characters before finding the seq, will return as much as it can (and queue will go
- * isEmpty() == true).
- * @param seq String to match up to, and not include in return, and to pull off queue. <b>Case sensitive.</b>
- * @return Data matched from queue.
- */
- public String chompTo(String seq) {
- String data = consumeTo(seq);
- matchChomp(seq);
- return data;
- }
-
- public String chompToIgnoreCase(String seq) {
- String data = consumeToIgnoreCase(seq); // case insensitive scan
- matchChomp(seq);
- return data;
- }
-
- /**
- * Pulls a balanced string off the queue. E.g. if queue is "(one (two) three) four", (,) will return "one (two) three",
- * and leave " four" on the queue. Unbalanced openers and closers can be escaped (with \). Those escapes will be left
- * in the returned string, which is suitable for regexes (where we need to preserve the escape), but unsuitable for
- * contains text strings; use unescape for that.
- * @param open opener
- * @param close closer
- * @return data matched from the queue
- */
- public String chompBalanced(char open, char close) {
- StringBuilder accum = new StringBuilder();
- int depth = 0;
- char last = 0;
-
- do {
- if (isEmpty()) break;
- Character c = consume();
- if (last == 0 || last != ESC) {
- if (c.equals(open))
- depth++;
- else if (c.equals(close))
- depth--;
- }
-
- if (depth > 0 && last != 0)
- accum.append(c); // don't include the outer match pair in the return
- last = c;
- } while (depth > 0);
- return accum.toString();
- }
-
- /**
- * Unescaped a \ escaped string.
- * @param in backslash escaped string
- * @return unescaped string
- */
- public static String unescape(String in) {
- StringBuilder out = new StringBuilder();
- char last = 0;
- for (char c : in.toCharArray()) {
- if (c == ESC) {
- if (last != 0 && last == ESC)
- out.append(c);
- }
- else
- out.append(c);
- last = c;
- }
- return out.toString();
- }
-
- /**
- * Pulls the next run of whitespace characters of the queue.
- */
- public boolean consumeWhitespace() {
- boolean seen = false;
- while (matchesWhitespace()) {
- pos++;
- seen = true;
- }
- return seen;
- }
-
- /**
- * Retrieves the next run of word type (letter or digit) off the queue.
- * @return String of word characters from queue, or empty string if none.
- */
- public String consumeWord() {
- int start = pos;
- while (matchesWord())
- pos++;
- return queue.substring(start, pos);
- }
-
- /**
- * Consume an tag name off the queue (word or :, _, -)
- *
- * @return tag name
- */
- public String consumeTagName() {
- int start = pos;
- while (!isEmpty() && (matchesWord() || matchesAny(':', '_', '-')))
- pos++;
-
- return queue.substring(start, pos);
- }
-
- /**
- * Consume a CSS element selector (tag name, but | instead of : for namespaces, to not conflict with :pseudo selects).
- *
- * @return tag name
- */
- public String consumeElementSelector() {
- int start = pos;
- while (!isEmpty() && (matchesWord() || matchesAny('|', '_', '-')))
- pos++;
-
- return queue.substring(start, pos);
- }
-
- /**
- Consume a CSS identifier (ID or class) off the queue (letter, digit, -, _)
- http://www.w3.org/TR/CSS2/syndata.html#value-def-identifier
- @return identifier
- */
- public String consumeCssIdentifier() {
- int start = pos;
- while (!isEmpty() && (matchesWord() || matchesAny('-', '_')))
- pos++;
-
- return queue.substring(start, pos);
- }
-
- /**
- Consume an attribute key off the queue (letter, digit, -, _, :")
- @return attribute key
- */
- public String consumeAttributeKey() {
- int start = pos;
- while (!isEmpty() && (matchesWord() || matchesAny('-', '_', ':')))
- pos++;
-
- return queue.substring(start, pos);
- }
-
- /**
- Consume and return whatever is left on the queue.
- @return remained of queue.
- */
- public String remainder() {
- StringBuilder accum = new StringBuilder();
- while (!isEmpty()) {
- accum.append(consume());
- }
- return accum.toString();
- }
-
- public String toString() {
- return queue.substring(pos);
- }
-}
diff --git a/src/org/jsoup/parser/Tokeniser.java b/src/org/jsoup/parser/Tokeniser.java
deleted file mode 100644
index ce6ee690d6..0000000000
--- a/src/org/jsoup/parser/Tokeniser.java
+++ /dev/null
@@ -1,230 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Entities;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Readers the input stream into tokens.
- */
-class Tokeniser {
- static final char replacementChar = '\uFFFD'; // replaces null character
-
- private CharacterReader reader; // html input
- private ParseErrorList errors; // errors found while tokenising
-
- private TokeniserState state = TokeniserState.Data; // current tokenisation state
- private Token emitPending; // the token we are about to emit on next read
- private boolean isEmitPending = false;
- private StringBuilder charBuffer = new StringBuilder(); // buffers characters to output as one token
- StringBuilder dataBuffer; // buffers data looking for </script>
-
- Token.Tag tagPending; // tag we are building up
- Token.Doctype doctypePending; // doctype building up
- Token.Comment commentPending; // comment building up
- private Token.StartTag lastStartTag; // the last start tag emitted, to test appropriate end tag
- private boolean selfClosingFlagAcknowledged = true;
-
- Tokeniser(CharacterReader reader, ParseErrorList errors) {
- this.reader = reader;
- this.errors = errors;
- }
-
- Token read() {
- if (!selfClosingFlagAcknowledged) {
- error("Self closing flag not acknowledged");
- selfClosingFlagAcknowledged = true;
- }
-
- while (!isEmitPending)
- state.read(this, reader);
-
- // if emit is pending, a non-character token was found: return any chars in buffer, and leave token for next read:
- if (charBuffer.length() > 0) {
- String str = charBuffer.toString();
- charBuffer.delete(0, charBuffer.length());
- return new Token.Character(str);
- } else {
- isEmitPending = false;
- return emitPending;
- }
- }
-
- void emit(Token token) {
- Validate.isFalse(isEmitPending, "There is an unread token pending!");
-
- emitPending = token;
- isEmitPending = true;
-
- if (token.type == Token.TokenType.StartTag) {
- Token.StartTag startTag = (Token.StartTag) token;
- lastStartTag = startTag;
- if (startTag.selfClosing)
- selfClosingFlagAcknowledged = false;
- } else if (token.type == Token.TokenType.EndTag) {
- Token.EndTag endTag = (Token.EndTag) token;
- if (endTag.attributes.size() > 0)
- error("Attributes incorrectly present on end tag");
- }
- }
-
- void emit(String str) {
- // buffer strings up until last string token found, to emit only one token for a run of character refs etc.
- // does not set isEmitPending; read checks that
- charBuffer.append(str);
- }
-
- void emit(char c) {
- charBuffer.append(c);
- }
-
- TokeniserState getState() {
- return state;
- }
-
- void transition(TokeniserState state) {
- this.state = state;
- }
-
- void advanceTransition(TokeniserState state) {
- reader.advance();
- this.state = state;
- }
-
- void acknowledgeSelfClosingFlag() {
- selfClosingFlagAcknowledged = true;
- }
-
- Character consumeCharacterReference(Character additionalAllowedCharacter, boolean inAttribute) {
- if (reader.isEmpty())
- return null;
- if (additionalAllowedCharacter != null && additionalAllowedCharacter == reader.current())
- return null;
- if (reader.matchesAny('\t', '\n', '\f', ' ', '<', '&'))
- return null;
-
- reader.mark();
- if (reader.matchConsume("#")) { // numbered
- boolean isHexMode = reader.matchConsumeIgnoreCase("X");
- String numRef = isHexMode ? reader.consumeHexSequence() : reader.consumeDigitSequence();
- if (numRef.length() == 0) { // didn't match anything
- characterReferenceError("numeric reference with no numerals");
- reader.rewindToMark();
- return null;
- }
- if (!reader.matchConsume(";"))
- characterReferenceError("missing semicolon"); // missing semi
- int charval = -1;
- try {
- int base = isHexMode ? 16 : 10;
- charval = Integer.valueOf(numRef, base);
- } catch (NumberFormatException e) {
- } // skip
- if (charval == -1 || (charval >= 0xD800 && charval <= 0xDFFF) || charval > 0x10FFFF) {
- characterReferenceError("character outside of valid range");
- return replacementChar;
- } else {
- // todo: implement number replacement table
- // todo: check for extra illegal unicode points as parse errors
- return (char) charval;
- }
- } else { // named
- // get as many letters as possible, and look for matching entities. unconsume backwards till a match is found
- String nameRef = reader.consumeLetterThenDigitSequence();
- String origNameRef = new String(nameRef); // for error reporting. nameRef gets chomped looking for matches
- boolean looksLegit = reader.matches(';');
- boolean found = false;
- while (nameRef.length() > 0 && !found) {
- if (Entities.isNamedEntity(nameRef))
- found = true;
- else {
- nameRef = nameRef.substring(0, nameRef.length()-1);
- reader.unconsume();
- }
- }
- if (!found) {
- if (looksLegit) // named with semicolon
- characterReferenceError(String.format("invalid named referenece '%s'", origNameRef));
- reader.rewindToMark();
- return null;
- }
- if (inAttribute && (reader.matchesLetter() || reader.matchesDigit() || reader.matchesAny('=', '-', '_'))) {
- // don't want that to match
- reader.rewindToMark();
- return null;
- }
- if (!reader.matchConsume(";"))
- characterReferenceError("missing semicolon"); // missing semi
- return Entities.getCharacterByName(nameRef);
- }
- }
-
- Token.Tag createTagPending(boolean start) {
- tagPending = start ? new Token.StartTag() : new Token.EndTag();
- return tagPending;
- }
-
- void emitTagPending() {
- tagPending.finaliseTag();
- emit(tagPending);
- }
-
- void createCommentPending() {
- commentPending = new Token.Comment();
- }
-
- void emitCommentPending() {
- emit(commentPending);
- }
-
- void createDoctypePending() {
- doctypePending = new Token.Doctype();
- }
-
- void emitDoctypePending() {
- emit(doctypePending);
- }
-
- void createTempBuffer() {
- dataBuffer = new StringBuilder();
- }
-
- boolean isAppropriateEndTagToken() {
- if (lastStartTag == null)
- return false;
- return tagPending.tagName.equals(lastStartTag.tagName);
- }
-
- String appropriateEndTagName() {
- return lastStartTag.tagName;
- }
-
- void error(TokeniserState state) {
- if (errors.canAddError())
- errors.add(new ParseError(reader.pos(), "Unexpected character '%s' in input state [%s]", reader.current(), state));
- }
-
- void eofError(TokeniserState state) {
- if (errors.canAddError())
- errors.add(new ParseError(reader.pos(), "Unexpectedly reached end of file (EOF) in input state [%s]", state));
- }
-
- private void characterReferenceError(String message) {
- if (errors.canAddError())
- errors.add(new ParseError(reader.pos(), "Invalid character reference: %s", message));
- }
-
- private void error(String errorMsg) {
- if (errors.canAddError())
- errors.add(new ParseError(reader.pos(), errorMsg));
- }
-
- boolean currentNodeInHtmlNS() {
- // todo: implement namespaces correctly
- return true;
- // Element currentNode = currentNode();
- // return currentNode != null && currentNode.namespace().equals("HTML");
- }
-}
diff --git a/src/org/jsoup/parser/TokeniserState.java b/src/org/jsoup/parser/TokeniserState.java
deleted file mode 100644
index e3013c73e9..0000000000
--- a/src/org/jsoup/parser/TokeniserState.java
+++ /dev/null
@@ -1,1778 +0,0 @@
-package org.jsoup.parser;
-
-/**
- * States and transition activations for the Tokeniser.
- */
-enum TokeniserState {
- Data {
- // in data state, gather characters until a character reference or tag is found
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case '&':
- t.advanceTransition(CharacterReferenceInData);
- break;
- case '<':
- t.advanceTransition(TagOpen);
- break;
- case nullChar:
- t.error(this); // NOT replacement character (oddly?)
- t.emit(r.consume());
- break;
- case eof:
- t.emit(new Token.EOF());
- break;
- default:
- String data = r.consumeToAny('&', '<', nullChar);
- t.emit(data);
- break;
- }
- }
- },
- CharacterReferenceInData {
- // from & in data
- void read(Tokeniser t, CharacterReader r) {
- Character c = t.consumeCharacterReference(null, false);
- if (c == null)
- t.emit('&');
- else
- t.emit(c);
- t.transition(Data);
- }
- },
- Rcdata {
- /// handles data in title, textarea etc
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case '&':
- t.advanceTransition(CharacterReferenceInRcdata);
- break;
- case '<':
- t.advanceTransition(RcdataLessthanSign);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- case eof:
- t.emit(new Token.EOF());
- break;
- default:
- String data = r.consumeToAny('&', '<', nullChar);
- t.emit(data);
- break;
- }
- }
- },
- CharacterReferenceInRcdata {
- void read(Tokeniser t, CharacterReader r) {
- Character c = t.consumeCharacterReference(null, false);
- if (c == null)
- t.emit('&');
- else
- t.emit(c);
- t.transition(Rcdata);
- }
- },
- Rawtext {
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case '<':
- t.advanceTransition(RawtextLessthanSign);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- case eof:
- t.emit(new Token.EOF());
- break;
- default:
- String data = r.consumeToAny('<', nullChar);
- t.emit(data);
- break;
- }
- }
- },
- ScriptData {
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case '<':
- t.advanceTransition(ScriptDataLessthanSign);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- case eof:
- t.emit(new Token.EOF());
- break;
- default:
- String data = r.consumeToAny('<', nullChar);
- t.emit(data);
- break;
- }
- }
- },
- PLAINTEXT {
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- case eof:
- t.emit(new Token.EOF());
- break;
- default:
- String data = r.consumeTo(nullChar);
- t.emit(data);
- break;
- }
- }
- },
- TagOpen {
- // from < in data
- void read(Tokeniser t, CharacterReader r) {
- switch (r.current()) {
- case '!':
- t.advanceTransition(MarkupDeclarationOpen);
- break;
- case '/':
- t.advanceTransition(EndTagOpen);
- break;
- case '?':
- t.advanceTransition(BogusComment);
- break;
- default:
- if (r.matchesLetter()) {
- t.createTagPending(true);
- t.transition(TagName);
- } else {
- t.error(this);
- t.emit('<'); // char that got us here
- t.transition(Data);
- }
- break;
- }
- }
- },
- EndTagOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.isEmpty()) {
- t.eofError(this);
- t.emit("</");
- t.transition(Data);
- } else if (r.matchesLetter()) {
- t.createTagPending(false);
- t.transition(TagName);
- } else if (r.matches('>')) {
- t.error(this);
- t.advanceTransition(Data);
- } else {
- t.error(this);
- t.advanceTransition(BogusComment);
- }
- }
- },
- TagName {
- // from < or </ in data, will have start or end tag pending
- void read(Tokeniser t, CharacterReader r) {
- // previous TagOpen state did NOT consume, will have a letter char in current
- String tagName = r.consumeToAny('\t', '\n', '\f', ' ', '/', '>', nullChar).toLowerCase();
- t.tagPending.appendTagName(tagName);
-
- switch (r.consume()) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case nullChar: // replacement
- t.tagPending.appendTagName(replacementStr);
- break;
- case eof: // should emit pending tag?
- t.eofError(this);
- t.transition(Data);
- // no default, as covered with above consumeToAny
- }
- }
- },
- RcdataLessthanSign {
- // from < in rcdata
- void read(Tokeniser t, CharacterReader r) {
- if (r.matches('/')) {
- t.createTempBuffer();
- t.advanceTransition(RCDATAEndTagOpen);
- } else if (r.matchesLetter() && !r.containsIgnoreCase("</" + t.appropriateEndTagName())) {
- // diverge from spec: got a start tag, but there's no appropriate end tag (</title>), so rather than
- // consuming to EOF; break out here
- t.tagPending = new Token.EndTag(t.appropriateEndTagName());
- t.emitTagPending();
- r.unconsume(); // undo "<"
- t.transition(Data);
- } else {
- t.emit("<");
- t.transition(Rcdata);
- }
- }
- },
- RCDATAEndTagOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createTagPending(false);
- t.tagPending.appendTagName(Character.toLowerCase(r.current()));
- t.dataBuffer.append(Character.toLowerCase(r.current()));
- t.advanceTransition(RCDATAEndTagName);
- } else {
- t.emit("</");
- t.transition(Rcdata);
- }
- }
- },
- RCDATAEndTagName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.tagPending.appendTagName(name.toLowerCase());
- t.dataBuffer.append(name);
- return;
- }
-
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- if (t.isAppropriateEndTagToken())
- t.transition(BeforeAttributeName);
- else
- anythingElse(t, r);
- break;
- case '/':
- if (t.isAppropriateEndTagToken())
- t.transition(SelfClosingStartTag);
- else
- anythingElse(t, r);
- break;
- case '>':
- if (t.isAppropriateEndTagToken()) {
- t.emitTagPending();
- t.transition(Data);
- }
- else
- anythingElse(t, r);
- break;
- default:
- anythingElse(t, r);
- }
- }
-
- private void anythingElse(Tokeniser t, CharacterReader r) {
- t.emit("</" + t.dataBuffer.toString());
- t.transition(Rcdata);
- }
- },
- RawtextLessthanSign {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matches('/')) {
- t.createTempBuffer();
- t.advanceTransition(RawtextEndTagOpen);
- } else {
- t.emit('<');
- t.transition(Rawtext);
- }
- }
- },
- RawtextEndTagOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createTagPending(false);
- t.transition(RawtextEndTagName);
- } else {
- t.emit("</");
- t.transition(Rawtext);
- }
- }
- },
- RawtextEndTagName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.tagPending.appendTagName(name.toLowerCase());
- t.dataBuffer.append(name);
- return;
- }
-
- if (t.isAppropriateEndTagToken() && !r.isEmpty()) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- default:
- t.dataBuffer.append(c);
- anythingElse(t, r);
- }
- } else
- anythingElse(t, r);
- }
-
- private void anythingElse(Tokeniser t, CharacterReader r) {
- t.emit("</" + t.dataBuffer.toString());
- t.transition(Rawtext);
- }
- },
- ScriptDataLessthanSign {
- void read(Tokeniser t, CharacterReader r) {
- switch (r.consume()) {
- case '/':
- t.createTempBuffer();
- t.transition(ScriptDataEndTagOpen);
- break;
- case '!':
- t.emit("<!");
- t.transition(ScriptDataEscapeStart);
- break;
- default:
- t.emit("<");
- r.unconsume();
- t.transition(ScriptData);
- }
- }
- },
- ScriptDataEndTagOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createTagPending(false);
- t.transition(ScriptDataEndTagName);
- } else {
- t.emit("</");
- t.transition(ScriptData);
- }
-
- }
- },
- ScriptDataEndTagName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.tagPending.appendTagName(name.toLowerCase());
- t.dataBuffer.append(name);
- return;
- }
-
- if (t.isAppropriateEndTagToken() && !r.isEmpty()) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- default:
- t.dataBuffer.append(c);
- anythingElse(t, r);
- }
- } else {
- anythingElse(t, r);
- }
- }
-
- private void anythingElse(Tokeniser t, CharacterReader r) {
- t.emit("</" + t.dataBuffer.toString());
- t.transition(ScriptData);
- }
- },
- ScriptDataEscapeStart {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matches('-')) {
- t.emit('-');
- t.advanceTransition(ScriptDataEscapeStartDash);
- } else {
- t.transition(ScriptData);
- }
- }
- },
- ScriptDataEscapeStartDash {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matches('-')) {
- t.emit('-');
- t.advanceTransition(ScriptDataEscapedDashDash);
- } else {
- t.transition(ScriptData);
- }
- }
- },
- ScriptDataEscaped {
- void read(Tokeniser t, CharacterReader r) {
- if (r.isEmpty()) {
- t.eofError(this);
- t.transition(Data);
- return;
- }
-
- switch (r.current()) {
- case '-':
- t.emit('-');
- t.advanceTransition(ScriptDataEscapedDash);
- break;
- case '<':
- t.advanceTransition(ScriptDataEscapedLessthanSign);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- default:
- String data = r.consumeToAny('-', '<', nullChar);
- t.emit(data);
- }
- }
- },
- ScriptDataEscapedDash {
- void read(Tokeniser t, CharacterReader r) {
- if (r.isEmpty()) {
- t.eofError(this);
- t.transition(Data);
- return;
- }
-
- char c = r.consume();
- switch (c) {
- case '-':
- t.emit(c);
- t.transition(ScriptDataEscapedDashDash);
- break;
- case '<':
- t.transition(ScriptDataEscapedLessthanSign);
- break;
- case nullChar:
- t.error(this);
- t.emit(replacementChar);
- t.transition(ScriptDataEscaped);
- break;
- default:
- t.emit(c);
- t.transition(ScriptDataEscaped);
- }
- }
- },
- ScriptDataEscapedDashDash {
- void read(Tokeniser t, CharacterReader r) {
- if (r.isEmpty()) {
- t.eofError(this);
- t.transition(Data);
- return;
- }
-
- char c = r.consume();
- switch (c) {
- case '-':
- t.emit(c);
- break;
- case '<':
- t.transition(ScriptDataEscapedLessthanSign);
- break;
- case '>':
- t.emit(c);
- t.transition(ScriptData);
- break;
- case nullChar:
- t.error(this);
- t.emit(replacementChar);
- t.transition(ScriptDataEscaped);
- break;
- default:
- t.emit(c);
- t.transition(ScriptDataEscaped);
- }
- }
- },
- ScriptDataEscapedLessthanSign {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createTempBuffer();
- t.dataBuffer.append(Character.toLowerCase(r.current()));
- t.emit("<" + r.current());
- t.advanceTransition(ScriptDataDoubleEscapeStart);
- } else if (r.matches('/')) {
- t.createTempBuffer();
- t.advanceTransition(ScriptDataEscapedEndTagOpen);
- } else {
- t.emit('<');
- t.transition(ScriptDataEscaped);
- }
- }
- },
- ScriptDataEscapedEndTagOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createTagPending(false);
- t.tagPending.appendTagName(Character.toLowerCase(r.current()));
- t.dataBuffer.append(r.current());
- t.advanceTransition(ScriptDataEscapedEndTagName);
- } else {
- t.emit("</");
- t.transition(ScriptDataEscaped);
- }
- }
- },
- ScriptDataEscapedEndTagName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.tagPending.appendTagName(name.toLowerCase());
- t.dataBuffer.append(name);
- return;
- }
-
- if (t.isAppropriateEndTagToken() && !r.isEmpty()) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- default:
- t.dataBuffer.append(c);
- anythingElse(t, r);
- break;
- }
- } else {
- anythingElse(t, r);
- }
- }
-
- private void anythingElse(Tokeniser t, CharacterReader r) {
- t.emit("</" + t.dataBuffer.toString());
- t.transition(ScriptDataEscaped);
- }
- },
- ScriptDataDoubleEscapeStart {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.dataBuffer.append(name.toLowerCase());
- t.emit(name);
- return;
- }
-
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- case '/':
- case '>':
- if (t.dataBuffer.toString().equals("script"))
- t.transition(ScriptDataDoubleEscaped);
- else
- t.transition(ScriptDataEscaped);
- t.emit(c);
- break;
- default:
- r.unconsume();
- t.transition(ScriptDataEscaped);
- }
- }
- },
- ScriptDataDoubleEscaped {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.current();
- switch (c) {
- case '-':
- t.emit(c);
- t.advanceTransition(ScriptDataDoubleEscapedDash);
- break;
- case '<':
- t.emit(c);
- t.advanceTransition(ScriptDataDoubleEscapedLessthanSign);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.emit(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- default:
- String data = r.consumeToAny('-', '<', nullChar);
- t.emit(data);
- }
- }
- },
- ScriptDataDoubleEscapedDash {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.emit(c);
- t.transition(ScriptDataDoubleEscapedDashDash);
- break;
- case '<':
- t.emit(c);
- t.transition(ScriptDataDoubleEscapedLessthanSign);
- break;
- case nullChar:
- t.error(this);
- t.emit(replacementChar);
- t.transition(ScriptDataDoubleEscaped);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- default:
- t.emit(c);
- t.transition(ScriptDataDoubleEscaped);
- }
- }
- },
- ScriptDataDoubleEscapedDashDash {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.emit(c);
- break;
- case '<':
- t.emit(c);
- t.transition(ScriptDataDoubleEscapedLessthanSign);
- break;
- case '>':
- t.emit(c);
- t.transition(ScriptData);
- break;
- case nullChar:
- t.error(this);
- t.emit(replacementChar);
- t.transition(ScriptDataDoubleEscaped);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- default:
- t.emit(c);
- t.transition(ScriptDataDoubleEscaped);
- }
- }
- },
- ScriptDataDoubleEscapedLessthanSign {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matches('/')) {
- t.emit('/');
- t.createTempBuffer();
- t.advanceTransition(ScriptDataDoubleEscapeEnd);
- } else {
- t.transition(ScriptDataDoubleEscaped);
- }
- }
- },
- ScriptDataDoubleEscapeEnd {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.dataBuffer.append(name.toLowerCase());
- t.emit(name);
- return;
- }
-
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- case '/':
- case '>':
- if (t.dataBuffer.toString().equals("script"))
- t.transition(ScriptDataEscaped);
- else
- t.transition(ScriptDataDoubleEscaped);
- t.emit(c);
- break;
- default:
- r.unconsume();
- t.transition(ScriptDataDoubleEscaped);
- }
- }
- },
- BeforeAttributeName {
- // from tagname <xxx
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break; // ignore whitespace
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.tagPending.newAttribute();
- r.unconsume();
- t.transition(AttributeName);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- case '"':
- case '\'':
- case '<':
- case '=':
- t.error(this);
- t.tagPending.newAttribute();
- t.tagPending.appendAttributeName(c);
- t.transition(AttributeName);
- break;
- default: // A-Z, anything else
- t.tagPending.newAttribute();
- r.unconsume();
- t.transition(AttributeName);
- }
- }
- },
- AttributeName {
- // from before attribute name
- void read(Tokeniser t, CharacterReader r) {
- String name = r.consumeToAny('\t', '\n', '\f', ' ', '/', '=', '>', nullChar, '"', '\'', '<');
- t.tagPending.appendAttributeName(name.toLowerCase());
-
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(AfterAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '=':
- t.transition(BeforeAttributeValue);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeName(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- case '"':
- case '\'':
- case '<':
- t.error(this);
- t.tagPending.appendAttributeName(c);
- // no default, as covered in consumeToAny
- }
- }
- },
- AfterAttributeName {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- // ignore
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '=':
- t.transition(BeforeAttributeValue);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeName(replacementChar);
- t.transition(AttributeName);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- case '"':
- case '\'':
- case '<':
- t.error(this);
- t.tagPending.newAttribute();
- t.tagPending.appendAttributeName(c);
- t.transition(AttributeName);
- break;
- default: // A-Z, anything else
- t.tagPending.newAttribute();
- r.unconsume();
- t.transition(AttributeName);
- }
- }
- },
- BeforeAttributeValue {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- // ignore
- break;
- case '"':
- t.transition(AttributeValue_doubleQuoted);
- break;
- case '&':
- r.unconsume();
- t.transition(AttributeValue_unquoted);
- break;
- case '\'':
- t.transition(AttributeValue_singleQuoted);
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeValue(replacementChar);
- t.transition(AttributeValue_unquoted);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- case '>':
- t.error(this);
- t.emitTagPending();
- t.transition(Data);
- break;
- case '<':
- case '=':
- case '`':
- t.error(this);
- t.tagPending.appendAttributeValue(c);
- t.transition(AttributeValue_unquoted);
- break;
- default:
- r.unconsume();
- t.transition(AttributeValue_unquoted);
- }
- }
- },
- AttributeValue_doubleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- String value = r.consumeToAny('"', '&', nullChar);
- if (value.length() > 0)
- t.tagPending.appendAttributeValue(value);
-
- char c = r.consume();
- switch (c) {
- case '"':
- t.transition(AfterAttributeValue_quoted);
- break;
- case '&':
- Character ref = t.consumeCharacterReference('"', true);
- if (ref != null)
- t.tagPending.appendAttributeValue(ref);
- else
- t.tagPending.appendAttributeValue('&');
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeValue(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- // no default, handled in consume to any above
- }
- }
- },
- AttributeValue_singleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- String value = r.consumeToAny('\'', '&', nullChar);
- if (value.length() > 0)
- t.tagPending.appendAttributeValue(value);
-
- char c = r.consume();
- switch (c) {
- case '\'':
- t.transition(AfterAttributeValue_quoted);
- break;
- case '&':
- Character ref = t.consumeCharacterReference('\'', true);
- if (ref != null)
- t.tagPending.appendAttributeValue(ref);
- else
- t.tagPending.appendAttributeValue('&');
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeValue(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- // no default, handled in consume to any above
- }
- }
- },
- AttributeValue_unquoted {
- void read(Tokeniser t, CharacterReader r) {
- String value = r.consumeToAny('\t', '\n', '\f', ' ', '&', '>', nullChar, '"', '\'', '<', '=', '`');
- if (value.length() > 0)
- t.tagPending.appendAttributeValue(value);
-
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '&':
- Character ref = t.consumeCharacterReference('>', true);
- if (ref != null)
- t.tagPending.appendAttributeValue(ref);
- else
- t.tagPending.appendAttributeValue('&');
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.tagPending.appendAttributeValue(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- case '"':
- case '\'':
- case '<':
- case '=':
- case '`':
- t.error(this);
- t.tagPending.appendAttributeValue(c);
- break;
- // no default, handled in consume to any above
- }
-
- }
- },
- // CharacterReferenceInAttributeValue state handled inline
- AfterAttributeValue_quoted {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeAttributeName);
- break;
- case '/':
- t.transition(SelfClosingStartTag);
- break;
- case '>':
- t.emitTagPending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- default:
- t.error(this);
- r.unconsume();
- t.transition(BeforeAttributeName);
- }
-
- }
- },
- SelfClosingStartTag {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '>':
- t.tagPending.selfClosing = true;
- t.emitTagPending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.transition(BeforeAttributeName);
- }
- }
- },
- BogusComment {
- void read(Tokeniser t, CharacterReader r) {
- // todo: handle bogus comment starting from eof. when does that trigger?
- // rewind to capture character that lead us here
- r.unconsume();
- Token.Comment comment = new Token.Comment();
- comment.data.append(r.consumeTo('>'));
- // todo: replace nullChar with replaceChar
- t.emit(comment);
- t.advanceTransition(Data);
- }
- },
- MarkupDeclarationOpen {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchConsume("--")) {
- t.createCommentPending();
- t.transition(CommentStart);
- } else if (r.matchConsumeIgnoreCase("DOCTYPE")) {
- t.transition(Doctype);
- } else if (r.matchConsume("[CDATA[")) {
- // todo: should actually check current namepspace, and only non-html allows cdata. until namespace
- // is implemented properly, keep handling as cdata
- //} else if (!t.currentNodeInHtmlNS() && r.matchConsume("[CDATA[")) {
- t.transition(CdataSection);
- } else {
- t.error(this);
- t.advanceTransition(BogusComment); // advance so this character gets in bogus comment data's rewind
- }
- }
- },
- CommentStart {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.transition(CommentStartDash);
- break;
- case nullChar:
- t.error(this);
- t.commentPending.data.append(replacementChar);
- t.transition(Comment);
- break;
- case '>':
- t.error(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.commentPending.data.append(c);
- t.transition(Comment);
- }
- }
- },
- CommentStartDash {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.transition(CommentStartDash);
- break;
- case nullChar:
- t.error(this);
- t.commentPending.data.append(replacementChar);
- t.transition(Comment);
- break;
- case '>':
- t.error(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.commentPending.data.append(c);
- t.transition(Comment);
- }
- }
- },
- Comment {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.current();
- switch (c) {
- case '-':
- t.advanceTransition(CommentEndDash);
- break;
- case nullChar:
- t.error(this);
- r.advance();
- t.commentPending.data.append(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.commentPending.data.append(r.consumeToAny('-', nullChar));
- }
- }
- },
- CommentEndDash {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.transition(CommentEnd);
- break;
- case nullChar:
- t.error(this);
- t.commentPending.data.append('-').append(replacementChar);
- t.transition(Comment);
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.commentPending.data.append('-').append(c);
- t.transition(Comment);
- }
- }
- },
- CommentEnd {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '>':
- t.emitCommentPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.commentPending.data.append("--").append(replacementChar);
- t.transition(Comment);
- break;
- case '!':
- t.error(this);
- t.transition(CommentEndBang);
- break;
- case '-':
- t.error(this);
- t.commentPending.data.append('-');
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.commentPending.data.append("--").append(c);
- t.transition(Comment);
- }
- }
- },
- CommentEndBang {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '-':
- t.commentPending.data.append("--!");
- t.transition(CommentEndDash);
- break;
- case '>':
- t.emitCommentPending();
- t.transition(Data);
- break;
- case nullChar:
- t.error(this);
- t.commentPending.data.append("--!").append(replacementChar);
- t.transition(Comment);
- break;
- case eof:
- t.eofError(this);
- t.emitCommentPending();
- t.transition(Data);
- break;
- default:
- t.commentPending.data.append("--!").append(c);
- t.transition(Comment);
- }
- }
- },
- Doctype {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeDoctypeName);
- break;
- case eof:
- t.eofError(this);
- t.createDoctypePending();
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.transition(BeforeDoctypeName);
- }
- }
- },
- BeforeDoctypeName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- t.createDoctypePending();
- t.transition(DoctypeName);
- return;
- }
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break; // ignore whitespace
- case nullChar:
- t.error(this);
- t.doctypePending.name.append(replacementChar);
- t.transition(DoctypeName);
- break;
- case eof:
- t.eofError(this);
- t.createDoctypePending();
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.createDoctypePending();
- t.doctypePending.name.append(c);
- t.transition(DoctypeName);
- }
- }
- },
- DoctypeName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.matchesLetter()) {
- String name = r.consumeLetterSequence();
- t.doctypePending.name.append(name.toLowerCase());
- return;
- }
- char c = r.consume();
- switch (c) {
- case '>':
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(AfterDoctypeName);
- break;
- case nullChar:
- t.error(this);
- t.doctypePending.name.append(replacementChar);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.doctypePending.name.append(c);
- }
- }
- },
- AfterDoctypeName {
- void read(Tokeniser t, CharacterReader r) {
- if (r.isEmpty()) {
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- return;
- }
- if (r.matchesAny('\t', '\n', '\f', ' '))
- r.advance(); // ignore whitespace
- else if (r.matches('>')) {
- t.emitDoctypePending();
- t.advanceTransition(Data);
- } else if (r.matchConsumeIgnoreCase("PUBLIC")) {
- t.transition(AfterDoctypePublicKeyword);
- } else if (r.matchConsumeIgnoreCase("SYSTEM")) {
- t.transition(AfterDoctypeSystemKeyword);
- } else {
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.advanceTransition(BogusDoctype);
- }
-
- }
- },
- AfterDoctypePublicKeyword {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeDoctypePublicIdentifier);
- break;
- case '"':
- t.error(this);
- // set public id to empty string
- t.transition(DoctypePublicIdentifier_doubleQuoted);
- break;
- case '\'':
- t.error(this);
- // set public id to empty string
- t.transition(DoctypePublicIdentifier_singleQuoted);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.transition(BogusDoctype);
- }
- }
- },
- BeforeDoctypePublicIdentifier {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break;
- case '"':
- // set public id to empty string
- t.transition(DoctypePublicIdentifier_doubleQuoted);
- break;
- case '\'':
- // set public id to empty string
- t.transition(DoctypePublicIdentifier_singleQuoted);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.transition(BogusDoctype);
- }
- }
- },
- DoctypePublicIdentifier_doubleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '"':
- t.transition(AfterDoctypePublicIdentifier);
- break;
- case nullChar:
- t.error(this);
- t.doctypePending.publicIdentifier.append(replacementChar);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.doctypePending.publicIdentifier.append(c);
- }
- }
- },
- DoctypePublicIdentifier_singleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\'':
- t.transition(AfterDoctypePublicIdentifier);
- break;
- case nullChar:
- t.error(this);
- t.doctypePending.publicIdentifier.append(replacementChar);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.doctypePending.publicIdentifier.append(c);
- }
- }
- },
- AfterDoctypePublicIdentifier {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BetweenDoctypePublicAndSystemIdentifiers);
- break;
- case '>':
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case '"':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_doubleQuoted);
- break;
- case '\'':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_singleQuoted);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.transition(BogusDoctype);
- }
- }
- },
- BetweenDoctypePublicAndSystemIdentifiers {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break;
- case '>':
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case '"':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_doubleQuoted);
- break;
- case '\'':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_singleQuoted);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.transition(BogusDoctype);
- }
- }
- },
- AfterDoctypeSystemKeyword {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- t.transition(BeforeDoctypeSystemIdentifier);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case '"':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_doubleQuoted);
- break;
- case '\'':
- t.error(this);
- // system id empty
- t.transition(DoctypeSystemIdentifier_singleQuoted);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- }
- }
- },
- BeforeDoctypeSystemIdentifier {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break;
- case '"':
- // set system id to empty string
- t.transition(DoctypeSystemIdentifier_doubleQuoted);
- break;
- case '\'':
- // set public id to empty string
- t.transition(DoctypeSystemIdentifier_singleQuoted);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.transition(BogusDoctype);
- }
- }
- },
- DoctypeSystemIdentifier_doubleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '"':
- t.transition(AfterDoctypeSystemIdentifier);
- break;
- case nullChar:
- t.error(this);
- t.doctypePending.systemIdentifier.append(replacementChar);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.doctypePending.systemIdentifier.append(c);
- }
- }
- },
- DoctypeSystemIdentifier_singleQuoted {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\'':
- t.transition(AfterDoctypeSystemIdentifier);
- break;
- case nullChar:
- t.error(this);
- t.doctypePending.systemIdentifier.append(replacementChar);
- break;
- case '>':
- t.error(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.doctypePending.systemIdentifier.append(c);
- }
- }
- },
- AfterDoctypeSystemIdentifier {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '\t':
- case '\n':
- case '\f':
- case ' ':
- break;
- case '>':
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.eofError(this);
- t.doctypePending.forceQuirks = true;
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- t.error(this);
- t.transition(BogusDoctype);
- // NOT force quirks
- }
- }
- },
- BogusDoctype {
- void read(Tokeniser t, CharacterReader r) {
- char c = r.consume();
- switch (c) {
- case '>':
- t.emitDoctypePending();
- t.transition(Data);
- break;
- case eof:
- t.emitDoctypePending();
- t.transition(Data);
- break;
- default:
- // ignore char
- break;
- }
- }
- },
- CdataSection {
- void read(Tokeniser t, CharacterReader r) {
- String data = r.consumeTo("]]>");
- t.emit(data);
- r.matchConsume("]]>");
- t.transition(Data);
- }
- };
-
-
- abstract void read(Tokeniser t, CharacterReader r);
-
- private static final char nullChar = '\u0000';
- private static final char replacementChar = Tokeniser.replacementChar;
- private static final String replacementStr = String.valueOf(Tokeniser.replacementChar);
- private static final char eof = CharacterReader.EOF;
-}
diff --git a/src/org/jsoup/parser/TreeBuilder.java b/src/org/jsoup/parser/TreeBuilder.java
deleted file mode 100644
index e06caad501..0000000000
--- a/src/org/jsoup/parser/TreeBuilder.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.DescendableLinkedList;
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Jonathan Hedley
- */
-abstract class TreeBuilder {
- CharacterReader reader;
- Tokeniser tokeniser;
- protected Document doc; // current doc we are building into
- protected DescendableLinkedList<Element> stack; // the stack of open elements
- protected String baseUri; // current base uri, for creating new elements
- protected Token currentToken; // currentToken is used only for error tracking.
- protected ParseErrorList errors; // null when not tracking errors
-
- protected void initialiseParse(String input, String baseUri, ParseErrorList errors) {
- Validate.notNull(input, "String input must not be null");
- Validate.notNull(baseUri, "BaseURI must not be null");
-
- doc = new Document(baseUri);
- reader = new CharacterReader(input);
- this.errors = errors;
- tokeniser = new Tokeniser(reader, errors);
- stack = new DescendableLinkedList<Element>();
- this.baseUri = baseUri;
- }
-
- Document parse(String input, String baseUri) {
- return parse(input, baseUri, ParseErrorList.noTracking());
- }
-
- Document parse(String input, String baseUri, ParseErrorList errors) {
- initialiseParse(input, baseUri, errors);
- runParser();
- return doc;
- }
-
- protected void runParser() {
- while (true) {
- Token token = tokeniser.read();
- process(token);
-
- if (token.type == Token.TokenType.EOF)
- break;
- }
- }
-
- protected abstract boolean process(Token token);
-
- protected Element currentElement() {
- return stack.getLast();
- }
-}
diff --git a/src/org/jsoup/parser/XmlTreeBuilder.java b/src/org/jsoup/parser/XmlTreeBuilder.java
deleted file mode 100644
index 3f03ad26ac..0000000000
--- a/src/org/jsoup/parser/XmlTreeBuilder.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.jsoup.parser;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.*;
-
-import java.util.Iterator;
-
-/**
- * @author Jonathan Hedley
- */
-public class XmlTreeBuilder extends TreeBuilder {
- @Override
- protected void initialiseParse(String input, String baseUri, ParseErrorList errors) {
- super.initialiseParse(input, baseUri, errors);
- stack.add(doc); // place the document onto the stack. differs from HtmlTreeBuilder (not on stack)
- }
-
- @Override
- protected boolean process(Token token) {
- // start tag, end tag, doctype, comment, character, eof
- switch (token.type) {
- case StartTag:
- insert(token.asStartTag());
- break;
- case EndTag:
- popStackToClose(token.asEndTag());
- break;
- case Comment:
- insert(token.asComment());
- break;
- case Character:
- insert(token.asCharacter());
- break;
- case Doctype:
- insert(token.asDoctype());
- break;
- case EOF: // could put some normalisation here if desired
- break;
- default:
- Validate.fail("Unexpected token type: " + token.type);
- }
- return true;
- }
-
- private void insertNode(Node node) {
- currentElement().appendChild(node);
- }
-
- Element insert(Token.StartTag startTag) {
- Tag tag = Tag.valueOf(startTag.name());
- // todo: wonder if for xml parsing, should treat all tags as unknown? because it's not html.
- Element el = new Element(tag, baseUri, startTag.attributes);
- insertNode(el);
- if (startTag.isSelfClosing()) {
- tokeniser.acknowledgeSelfClosingFlag();
- if (!tag.isKnownTag()) // unknown tag, remember this is self closing for output. see above.
- tag.setSelfClosing();
- } else {
- stack.add(el);
- }
- return el;
- }
-
- void insert(Token.Comment commentToken) {
- Comment comment = new Comment(commentToken.getData(), baseUri);
- insertNode(comment);
- }
-
- void insert(Token.Character characterToken) {
- Node node = new TextNode(characterToken.getData(), baseUri);
- insertNode(node);
- }
-
- void insert(Token.Doctype d) {
- DocumentType doctypeNode = new DocumentType(d.getName(), d.getPublicIdentifier(), d.getSystemIdentifier(), baseUri);
- insertNode(doctypeNode);
- }
-
- /**
- * If the stack contains an element with this tag's name, pop up the stack to remove the first occurrence. If not
- * found, skips.
- *
- * @param endTag
- */
- private void popStackToClose(Token.EndTag endTag) {
- String elName = endTag.name();
- Element firstFound = null;
-
- Iterator<Element> it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next.nodeName().equals(elName)) {
- firstFound = next;
- break;
- }
- }
- if (firstFound == null)
- return; // not found, skip
-
- it = stack.descendingIterator();
- while (it.hasNext()) {
- Element next = it.next();
- if (next == firstFound) {
- it.remove();
- break;
- } else {
- it.remove();
- }
- }
- }
-}
diff --git a/src/org/jsoup/parser/package-info.java b/src/org/jsoup/parser/package-info.java
deleted file mode 100644
index 168fdf4086..0000000000
--- a/src/org/jsoup/parser/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- Contains the HTML parser, tag specifications, and HTML tokeniser.
- */
-package org.jsoup.parser;
diff --git a/src/org/jsoup/safety/Cleaner.java b/src/org/jsoup/safety/Cleaner.java
deleted file mode 100644
index eda67df86b..0000000000
--- a/src/org/jsoup/safety/Cleaner.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package org.jsoup.safety;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.*;
-import org.jsoup.parser.Tag;
-
-import java.util.List;
-
-/**
- The whitelist based HTML cleaner. Use to ensure that end-user provided HTML contains only the elements and attributes
- that you are expecting; no junk, and no cross-site scripting attacks!
- <p/>
- The HTML cleaner parses the input as HTML and then runs it through a white-list, so the output HTML can only contain
- HTML that is allowed by the whitelist.
- <p/>
- It is assumed that the input HTML is a body fragment; the clean methods only pull from the source's body, and the
- canned white-lists only allow body contained tags.
- <p/>
- Rather than interacting directly with a Cleaner object, generally see the {@code clean} methods in {@link org.jsoup.Jsoup}.
- */
-public class Cleaner {
- private Whitelist whitelist;
-
- /**
- Create a new cleaner, that sanitizes documents using the supplied whitelist.
- @param whitelist white-list to clean with
- */
- public Cleaner(Whitelist whitelist) {
- Validate.notNull(whitelist);
- this.whitelist = whitelist;
- }
-
- /**
- Creates a new, clean document, from the original dirty document, containing only elements allowed by the whitelist.
- The original document is not modified. Only elements from the dirt document's <code>body</code> are used.
- @param dirtyDocument Untrusted base document to clean.
- @return cleaned document.
- */
- public Document clean(Document dirtyDocument) {
- Validate.notNull(dirtyDocument);
-
- Document clean = Document.createShell(dirtyDocument.baseUri());
- copySafeNodes(dirtyDocument.body(), clean.body());
-
- return clean;
- }
-
- /**
- Determines if the input document is valid, against the whitelist. It is considered valid if all the tags and attributes
- in the input HTML are allowed by the whitelist.
- <p/>
- This method can be used as a validator for user input forms. An invalid document will still be cleaned successfully
- using the {@link #clean(Document)} document. If using as a validator, it is recommended to still clean the document
- to ensure enforced attributes are set correctly, and that the output is tidied.
- @param dirtyDocument document to test
- @return true if no tags or attributes need to be removed; false if they do
- */
- public boolean isValid(Document dirtyDocument) {
- Validate.notNull(dirtyDocument);
-
- Document clean = Document.createShell(dirtyDocument.baseUri());
- int numDiscarded = copySafeNodes(dirtyDocument.body(), clean.body());
- return numDiscarded == 0;
- }
-
- /**
- Iterates the input and copies trusted nodes (tags, attributes, text) into the destination.
- @param source source of HTML
- @param dest destination element to copy into
- @return number of discarded elements (that were considered unsafe)
- */
- private int copySafeNodes(Element source, Element dest) {
- List<Node> sourceChildren = source.childNodes();
- int numDiscarded = 0;
-
- for (Node sourceChild : sourceChildren) {
- if (sourceChild instanceof Element) {
- Element sourceEl = (Element) sourceChild;
-
- if (whitelist.isSafeTag(sourceEl.tagName())) { // safe, clone and copy safe attrs
- ElementMeta meta = createSafeElement(sourceEl);
- Element destChild = meta.el;
- dest.appendChild(destChild);
-
- numDiscarded += meta.numAttribsDiscarded;
- numDiscarded += copySafeNodes(sourceEl, destChild); // recurs
- } else { // not a safe tag, but it may have children (els or text) that are, so recurse
- numDiscarded++;
- numDiscarded += copySafeNodes(sourceEl, dest);
- }
- } else if (sourceChild instanceof TextNode) {
- TextNode sourceText = (TextNode) sourceChild;
- TextNode destText = new TextNode(sourceText.getWholeText(), sourceChild.baseUri());
- dest.appendChild(destText);
- } // else, we don't care about comments, xml proc instructions, etc
- }
- return numDiscarded;
- }
-
- private ElementMeta createSafeElement(Element sourceEl) {
- String sourceTag = sourceEl.tagName();
- Attributes destAttrs = new Attributes();
- Element dest = new Element(Tag.valueOf(sourceTag), sourceEl.baseUri(), destAttrs);
- int numDiscarded = 0;
-
- Attributes sourceAttrs = sourceEl.attributes();
- for (Attribute sourceAttr : sourceAttrs) {
- if (whitelist.isSafeAttribute(sourceTag, sourceEl, sourceAttr))
- destAttrs.put(sourceAttr);
- else
- numDiscarded++;
- }
- Attributes enforcedAttrs = whitelist.getEnforcedAttributes(sourceTag);
- destAttrs.addAll(enforcedAttrs);
-
- return new ElementMeta(dest, numDiscarded);
- }
-
- private static class ElementMeta {
- Element el;
- int numAttribsDiscarded;
-
- ElementMeta(Element el, int numAttribsDiscarded) {
- this.el = el;
- this.numAttribsDiscarded = numAttribsDiscarded;
- }
- }
-
-}
diff --git a/src/org/jsoup/safety/Whitelist.java b/src/org/jsoup/safety/Whitelist.java
deleted file mode 100644
index 2c1150ce9e..0000000000
--- a/src/org/jsoup/safety/Whitelist.java
+++ /dev/null
@@ -1,451 +0,0 @@
-package org.jsoup.safety;
-
-/*
- Thank you to Ryan Grove (wonko.com) for the Ruby HTML cleaner http://github.com/rgrove/sanitize/, which inspired
- this whitelist configuration, and the initial defaults.
- */
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Attribute;
-import org.jsoup.nodes.Attributes;
-import org.jsoup.nodes.Element;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- Whitelists define what HTML (elements and attributes) to allow through the cleaner. Everything else is removed.
- <p/>
- Start with one of the defaults:
- <ul>
- <li>{@link #none}
- <li>{@link #simpleText}
- <li>{@link #basic}
- <li>{@link #basicWithImages}
- <li>{@link #relaxed}
- </ul>
- <p/>
- If you need to allow more through (please be careful!), tweak a base whitelist with:
- <ul>
- <li>{@link #addTags}
- <li>{@link #addAttributes}
- <li>{@link #addEnforcedAttribute}
- <li>{@link #addProtocols}
- </ul>
- <p/>
- The cleaner and these whitelists assume that you want to clean a <code>body</code> fragment of HTML (to add user
- supplied HTML into a templated page), and not to clean a full HTML document. If the latter is the case, either wrap the
- document HTML around the cleaned body HTML, or create a whitelist that allows <code>html</code> and <code>head</code>
- elements as appropriate.
- <p/>
- If you are going to extend a whitelist, please be very careful. Make sure you understand what attributes may lead to
- XSS attack vectors. URL attributes are particularly vulnerable and require careful validation. See
- http://ha.ckers.org/xss.html for some XSS attack examples.
-
- @author Jonathan Hedley
- */
-public class Whitelist {
- private Set<TagName> tagNames; // tags allowed, lower case. e.g. [p, br, span]
- private Map<TagName, Set<AttributeKey>> attributes; // tag -> attribute[]. allowed attributes [href] for a tag.
- private Map<TagName, Map<AttributeKey, AttributeValue>> enforcedAttributes; // always set these attribute values
- private Map<TagName, Map<AttributeKey, Set<Protocol>>> protocols; // allowed URL protocols for attributes
- private boolean preserveRelativeLinks; // option to preserve relative links
-
- /**
- This whitelist allows only text nodes: all HTML will be stripped.
-
- @return whitelist
- */
- public static Whitelist none() {
- return new Whitelist();
- }
-
- /**
- This whitelist allows only simple text formatting: <code>b, em, i, strong, u</code>. All other HTML (tags and
- attributes) will be removed.
-
- @return whitelist
- */
- public static Whitelist simpleText() {
- return new Whitelist()
- .addTags("b", "em", "i", "strong", "u")
- ;
- }
-
- /**
- This whitelist allows a fuller range of text nodes: <code>a, b, blockquote, br, cite, code, dd, dl, dt, em, i, li,
- ol, p, pre, q, small, strike, strong, sub, sup, u, ul</code>, and appropriate attributes.
- <p/>
- Links (<code>a</code> elements) can point to <code>http, https, ftp, mailto</code>, and have an enforced
- <code>rel=nofollow</code> attribute.
- <p/>
- Does not allow images.
-
- @return whitelist
- */
- public static Whitelist basic() {
- return new Whitelist()
- .addTags(
- "a", "b", "blockquote", "br", "cite", "code", "dd", "dl", "dt", "em",
- "i", "li", "ol", "p", "pre", "q", "small", "strike", "strong", "sub",
- "sup", "u", "ul")
-
- .addAttributes("a", "href")
- .addAttributes("blockquote", "cite")
- .addAttributes("q", "cite")
-
- .addProtocols("a", "href", "ftp", "http", "https", "mailto")
- .addProtocols("blockquote", "cite", "http", "https")
- .addProtocols("cite", "cite", "http", "https")
-
- .addEnforcedAttribute("a", "rel", "nofollow")
- ;
-
- }
-
- /**
- This whitelist allows the same text tags as {@link #basic}, and also allows <code>img</code> tags, with appropriate
- attributes, with <code>src</code> pointing to <code>http</code> or <code>https</code>.
-
- @return whitelist
- */
- public static Whitelist basicWithImages() {
- return basic()
- .addTags("img")
- .addAttributes("img", "align", "alt", "height", "src", "title", "width")
- .addProtocols("img", "src", "http", "https")
- ;
- }
-
- /**
- This whitelist allows a full range of text and structural body HTML: <code>a, b, blockquote, br, caption, cite,
- code, col, colgroup, dd, dl, dt, em, h1, h2, h3, h4, h5, h6, i, img, li, ol, p, pre, q, small, strike, strong, sub,
- sup, table, tbody, td, tfoot, th, thead, tr, u, ul</code>
- <p/>
- Links do not have an enforced <code>rel=nofollow</code> attribute, but you can add that if desired.
-
- @return whitelist
- */
- public static Whitelist relaxed() {
- return new Whitelist()
- .addTags(
- "a", "b", "blockquote", "br", "caption", "cite", "code", "col",
- "colgroup", "dd", "div", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6",
- "i", "img", "li", "ol", "p", "pre", "q", "small", "strike", "strong",
- "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "u",
- "ul")
-
- .addAttributes("a", "href", "title")
- .addAttributes("blockquote", "cite")
- .addAttributes("col", "span", "width")
- .addAttributes("colgroup", "span", "width")
- .addAttributes("img", "align", "alt", "height", "src", "title", "width")
- .addAttributes("ol", "start", "type")
- .addAttributes("q", "cite")
- .addAttributes("table", "summary", "width")
- .addAttributes("td", "abbr", "axis", "colspan", "rowspan", "width")
- .addAttributes(
- "th", "abbr", "axis", "colspan", "rowspan", "scope",
- "width")
- .addAttributes("ul", "type")
-
- .addProtocols("a", "href", "ftp", "http", "https", "mailto")
- .addProtocols("blockquote", "cite", "http", "https")
- .addProtocols("img", "src", "http", "https")
- .addProtocols("q", "cite", "http", "https")
- ;
- }
-
- /**
- Create a new, empty whitelist. Generally it will be better to start with a default prepared whitelist instead.
-
- @see #basic()
- @see #basicWithImages()
- @see #simpleText()
- @see #relaxed()
- */
- public Whitelist() {
- tagNames = new HashSet<TagName>();
- attributes = new HashMap<TagName, Set<AttributeKey>>();
- enforcedAttributes = new HashMap<TagName, Map<AttributeKey, AttributeValue>>();
- protocols = new HashMap<TagName, Map<AttributeKey, Set<Protocol>>>();
- preserveRelativeLinks = false;
- }
-
- /**
- Add a list of allowed elements to a whitelist. (If a tag is not allowed, it will be removed from the HTML.)
-
- @param tags tag names to allow
- @return this (for chaining)
- */
- public Whitelist addTags(String... tags) {
- Validate.notNull(tags);
-
- for (String tagName : tags) {
- Validate.notEmpty(tagName);
- tagNames.add(TagName.valueOf(tagName));
- }
- return this;
- }
-
- /**
- Add a list of allowed attributes to a tag. (If an attribute is not allowed on an element, it will be removed.)
- <p/>
- E.g.: <code>addAttributes("a", "href", "class")</code> allows <code>href</code> and <code>class</code> attributes
- on <code>a</code> tags.
- <p/>
- To make an attribute valid for <b>all tags</b>, use the pseudo tag <code>:all</code>, e.g.
- <code>addAttributes(":all", "class")</code>.
-
- @param tag The tag the attributes are for. The tag will be added to the allowed tag list if necessary.
- @param keys List of valid attributes for the tag
- @return this (for chaining)
- */
- public Whitelist addAttributes(String tag, String... keys) {
- Validate.notEmpty(tag);
- Validate.notNull(keys);
- Validate.isTrue(keys.length > 0, "No attributes supplied.");
-
- TagName tagName = TagName.valueOf(tag);
- if (!tagNames.contains(tagName))
- tagNames.add(tagName);
- Set<AttributeKey> attributeSet = new HashSet<AttributeKey>();
- for (String key : keys) {
- Validate.notEmpty(key);
- attributeSet.add(AttributeKey.valueOf(key));
- }
- if (attributes.containsKey(tagName)) {
- Set<AttributeKey> currentSet = attributes.get(tagName);
- currentSet.addAll(attributeSet);
- } else {
- attributes.put(tagName, attributeSet);
- }
- return this;
- }
-
- /**
- Add an enforced attribute to a tag. An enforced attribute will always be added to the element. If the element
- already has the attribute set, it will be overridden.
- <p/>
- E.g.: <code>addEnforcedAttribute("a", "rel", "nofollow")</code> will make all <code>a</code> tags output as
- <code>&lt;a href="..." rel="nofollow"></code>
-
- @param tag The tag the enforced attribute is for. The tag will be added to the allowed tag list if necessary.
- @param key The attribute key
- @param value The enforced attribute value
- @return this (for chaining)
- */
- public Whitelist addEnforcedAttribute(String tag, String key, String value) {
- Validate.notEmpty(tag);
- Validate.notEmpty(key);
- Validate.notEmpty(value);
-
- TagName tagName = TagName.valueOf(tag);
- if (!tagNames.contains(tagName))
- tagNames.add(tagName);
- AttributeKey attrKey = AttributeKey.valueOf(key);
- AttributeValue attrVal = AttributeValue.valueOf(value);
-
- if (enforcedAttributes.containsKey(tagName)) {
- enforcedAttributes.get(tagName).put(attrKey, attrVal);
- } else {
- Map<AttributeKey, AttributeValue> attrMap = new HashMap<AttributeKey, AttributeValue>();
- attrMap.put(attrKey, attrVal);
- enforcedAttributes.put(tagName, attrMap);
- }
- return this;
- }
-
- /**
- * Configure this Whitelist to preserve relative links in an element's URL attribute, or convert them to absolute
- * links. By default, this is <b>false</b>: URLs will be made absolute (e.g. start with an allowed protocol, like
- * e.g. {@code http://}.
- * <p />
- * Note that when handling relative links, the input document must have an appropriate {@code base URI} set when
- * parsing, so that the link's protocol can be confirmed. Regardless of the setting of the {@code preserve relative
- * links} option, the link must be resolvable against the base URI to an allowed protocol; otherwise the attribute
- * will be removed.
- *
- * @param preserve {@code true} to allow relative links, {@code false} (default) to deny
- * @return this Whitelist, for chaining.
- * @see #addProtocols
- */
- public Whitelist preserveRelativeLinks(boolean preserve) {
- preserveRelativeLinks = preserve;
- return this;
- }
-
- /**
- Add allowed URL protocols for an element's URL attribute. This restricts the possible values of the attribute to
- URLs with the defined protocol.
- <p/>
- E.g.: <code>addProtocols("a", "href", "ftp", "http", "https")</code>
-
- @param tag Tag the URL protocol is for
- @param key Attribute key
- @param protocols List of valid protocols
- @return this, for chaining
- */
- public Whitelist addProtocols(String tag, String key, String... protocols) {
- Validate.notEmpty(tag);
- Validate.notEmpty(key);
- Validate.notNull(protocols);
-
- TagName tagName = TagName.valueOf(tag);
- AttributeKey attrKey = AttributeKey.valueOf(key);
- Map<AttributeKey, Set<Protocol>> attrMap;
- Set<Protocol> protSet;
-
- if (this.protocols.containsKey(tagName)) {
- attrMap = this.protocols.get(tagName);
- } else {
- attrMap = new HashMap<AttributeKey, Set<Protocol>>();
- this.protocols.put(tagName, attrMap);
- }
- if (attrMap.containsKey(attrKey)) {
- protSet = attrMap.get(attrKey);
- } else {
- protSet = new HashSet<Protocol>();
- attrMap.put(attrKey, protSet);
- }
- for (String protocol : protocols) {
- Validate.notEmpty(protocol);
- Protocol prot = Protocol.valueOf(protocol);
- protSet.add(prot);
- }
- return this;
- }
-
- boolean isSafeTag(String tag) {
- return tagNames.contains(TagName.valueOf(tag));
- }
-
- boolean isSafeAttribute(String tagName, Element el, Attribute attr) {
- TagName tag = TagName.valueOf(tagName);
- AttributeKey key = AttributeKey.valueOf(attr.getKey());
-
- if (attributes.containsKey(tag)) {
- if (attributes.get(tag).contains(key)) {
- if (protocols.containsKey(tag)) {
- Map<AttributeKey, Set<Protocol>> attrProts = protocols.get(tag);
- // ok if not defined protocol; otherwise test
- return !attrProts.containsKey(key) || testValidProtocol(el, attr, attrProts.get(key));
- } else { // attribute found, no protocols defined, so OK
- return true;
- }
- }
- }
- // no attributes defined for tag, try :all tag
- return !tagName.equals(":all") && isSafeAttribute(":all", el, attr);
- }
-
- private boolean testValidProtocol(Element el, Attribute attr, Set<Protocol> protocols) {
- // try to resolve relative urls to abs, and optionally update the attribute so output html has abs.
- // rels without a baseuri get removed
- String value = el.absUrl(attr.getKey());
- if (value.length() == 0)
- value = attr.getValue(); // if it could not be made abs, run as-is to allow custom unknown protocols
- if (!preserveRelativeLinks)
- attr.setValue(value);
-
- for (Protocol protocol : protocols) {
- String prot = protocol.toString() + ":";
- if (value.toLowerCase().startsWith(prot)) {
- return true;
- }
- }
- return false;
- }
-
- Attributes getEnforcedAttributes(String tagName) {
- Attributes attrs = new Attributes();
- TagName tag = TagName.valueOf(tagName);
- if (enforcedAttributes.containsKey(tag)) {
- Map<AttributeKey, AttributeValue> keyVals = enforcedAttributes.get(tag);
- for (Map.Entry<AttributeKey, AttributeValue> entry : keyVals.entrySet()) {
- attrs.put(entry.getKey().toString(), entry.getValue().toString());
- }
- }
- return attrs;
- }
-
- // named types for config. All just hold strings, but here for my sanity.
-
- static class TagName extends TypedValue {
- TagName(String value) {
- super(value);
- }
-
- static TagName valueOf(String value) {
- return new TagName(value);
- }
- }
-
- static class AttributeKey extends TypedValue {
- AttributeKey(String value) {
- super(value);
- }
-
- static AttributeKey valueOf(String value) {
- return new AttributeKey(value);
- }
- }
-
- static class AttributeValue extends TypedValue {
- AttributeValue(String value) {
- super(value);
- }
-
- static AttributeValue valueOf(String value) {
- return new AttributeValue(value);
- }
- }
-
- static class Protocol extends TypedValue {
- Protocol(String value) {
- super(value);
- }
-
- static Protocol valueOf(String value) {
- return new Protocol(value);
- }
- }
-
- abstract static class TypedValue {
- private String value;
-
- TypedValue(String value) {
- Validate.notNull(value);
- this.value = value;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((value == null) ? 0 : value.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- TypedValue other = (TypedValue) obj;
- if (value == null) {
- if (other.value != null) return false;
- } else if (!value.equals(other.value)) return false;
- return true;
- }
-
- @Override
- public String toString() {
- return value;
- }
- }
-}
-
diff --git a/src/org/jsoup/safety/package-info.java b/src/org/jsoup/safety/package-info.java
deleted file mode 100644
index ac890f0607..0000000000
--- a/src/org/jsoup/safety/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- Contains the jsoup HTML cleaner, and whitelist definitions.
- */
-package org.jsoup.safety;
diff --git a/src/org/jsoup/select/Collector.java b/src/org/jsoup/select/Collector.java
deleted file mode 100644
index 8f01045768..0000000000
--- a/src/org/jsoup/select/Collector.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-
-/**
- * Collects a list of elements that match the supplied criteria.
- *
- * @author Jonathan Hedley
- */
-public class Collector {
-
- private Collector() {
- }
-
- /**
- Build a list of elements, by visiting root and every descendant of root, and testing it against the evaluator.
- @param eval Evaluator to test elements against
- @param root root of tree to descend
- @return list of matches; empty if none
- */
- public static Elements collect (Evaluator eval, Element root) {
- Elements elements = new Elements();
- new NodeTraversor(new Accumulator(root, elements, eval)).traverse(root);
- return elements;
- }
-
- private static class Accumulator implements NodeVisitor {
- private final Element root;
- private final Elements elements;
- private final Evaluator eval;
-
- Accumulator(Element root, Elements elements, Evaluator eval) {
- this.root = root;
- this.elements = elements;
- this.eval = eval;
- }
-
- public void head(Node node, int depth) {
- if (node instanceof Element) {
- Element el = (Element) node;
- if (eval.matches(root, el))
- elements.add(el);
- }
- }
-
- public void tail(Node node, int depth) {
- // void
- }
- }
-}
diff --git a/src/org/jsoup/select/CombiningEvaluator.java b/src/org/jsoup/select/CombiningEvaluator.java
deleted file mode 100644
index a31ed2636f..0000000000
--- a/src/org/jsoup/select/CombiningEvaluator.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.nodes.Element;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Base combining (and, or) evaluator.
- */
-abstract class CombiningEvaluator extends Evaluator {
- final List<Evaluator> evaluators;
-
- CombiningEvaluator() {
- super();
- evaluators = new ArrayList<Evaluator>();
- }
-
- CombiningEvaluator(Collection<Evaluator> evaluators) {
- this();
- this.evaluators.addAll(evaluators);
- }
-
- Evaluator rightMostEvaluator() {
- return evaluators.size() > 0 ? evaluators.get(evaluators.size() - 1) : null;
- }
-
- void replaceRightMostEvaluator(Evaluator replacement) {
- evaluators.set(evaluators.size() - 1, replacement);
- }
-
- static final class And extends CombiningEvaluator {
- And(Collection<Evaluator> evaluators) {
- super(evaluators);
- }
-
- And(Evaluator... evaluators) {
- this(Arrays.asList(evaluators));
- }
-
- @Override
- public boolean matches(Element root, Element node) {
- for (Evaluator s : evaluators) {
- if (!s.matches(root, node))
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return StringUtil.join(evaluators, " ");
- }
- }
-
- static final class Or extends CombiningEvaluator {
- /**
- * Create a new Or evaluator. The initial evaluators are ANDed together and used as the first clause of the OR.
- * @param evaluators initial OR clause (these are wrapped into an AND evaluator).
- */
- Or(Collection<Evaluator> evaluators) {
- super();
- if (evaluators.size() > 1)
- this.evaluators.add(new And(evaluators));
- else // 0 or 1
- this.evaluators.addAll(evaluators);
- }
-
- Or() {
- super();
- }
-
- public void add(Evaluator e) {
- evaluators.add(e);
- }
-
- @Override
- public boolean matches(Element root, Element node) {
- for (Evaluator s : evaluators) {
- if (s.matches(root, node))
- return true;
- }
- return false;
- }
-
- @Override
- public String toString() {
- return String.format(":or%s", evaluators);
- }
- }
-}
diff --git a/src/org/jsoup/select/Elements.java b/src/org/jsoup/select/Elements.java
deleted file mode 100644
index 8302da1e53..0000000000
--- a/src/org/jsoup/select/Elements.java
+++ /dev/null
@@ -1,536 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Element;
-import org.jsoup.nodes.Node;
-
-import java.util.*;
-
-/**
- A list of {@link Element Elements}, with methods that act on every element in the list.
- <p/>
- To get an Elements object, use the {@link Element#select(String)} method.
-
- @author Jonathan Hedley, jonathan@hedley.net */
-public class Elements implements List<Element>, Cloneable {
- private List<Element> contents;
-
- public Elements() {
- contents = new ArrayList<Element>();
- }
-
- public Elements(int initialCapacity) {
- contents = new ArrayList<Element>(initialCapacity);
- }
-
- public Elements(Collection<Element> elements) {
- contents = new ArrayList<Element>(elements);
- }
-
- public Elements(List<Element> elements) {
- contents = elements;
- }
-
- public Elements(Element... elements) {
- this(Arrays.asList(elements));
- }
-
- @Override
- public Elements clone() {
- List<Element> elements = new ArrayList<Element>();
-
- for(Element e : contents)
- elements.add(e.clone());
-
-
- return new Elements(elements);
- }
-
- // attribute methods
- /**
- Get an attribute value from the first matched element that has the attribute.
- @param attributeKey The attribute key.
- @return The attribute value from the first matched element that has the attribute.. If no elements were matched (isEmpty() == true),
- or if the no elements have the attribute, returns empty string.
- @see #hasAttr(String)
- */
- public String attr(String attributeKey) {
- for (Element element : contents) {
- if (element.hasAttr(attributeKey))
- return element.attr(attributeKey);
- }
- return "";
- }
-
- /**
- Checks if any of the matched elements have this attribute set.
- @param attributeKey attribute key
- @return true if any of the elements have the attribute; false if none do.
- */
- public boolean hasAttr(String attributeKey) {
- for (Element element : contents) {
- if (element.hasAttr(attributeKey))
- return true;
- }
- return false;
- }
-
- /**
- * Set an attribute on all matched elements.
- * @param attributeKey attribute key
- * @param attributeValue attribute value
- * @return this
- */
- public Elements attr(String attributeKey, String attributeValue) {
- for (Element element : contents) {
- element.attr(attributeKey, attributeValue);
- }
- return this;
- }
-
- /**
- * Remove an attribute from every matched element.
- * @param attributeKey The attribute to remove.
- * @return this (for chaining)
- */
- public Elements removeAttr(String attributeKey) {
- for (Element element : contents) {
- element.removeAttr(attributeKey);
- }
- return this;
- }
-
- /**
- Add the class name to every matched element's {@code class} attribute.
- @param className class name to add
- @return this
- */
- public Elements addClass(String className) {
- for (Element element : contents) {
- element.addClass(className);
- }
- return this;
- }
-
- /**
- Remove the class name from every matched element's {@code class} attribute, if present.
- @param className class name to remove
- @return this
- */
- public Elements removeClass(String className) {
- for (Element element : contents) {
- element.removeClass(className);
- }
- return this;
- }
-
- /**
- Toggle the class name on every matched element's {@code class} attribute.
- @param className class name to add if missing, or remove if present, from every element.
- @return this
- */
- public Elements toggleClass(String className) {
- for (Element element : contents) {
- element.toggleClass(className);
- }
- return this;
- }
-
- /**
- Determine if any of the matched elements have this class name set in their {@code class} attribute.
- @param className class name to check for
- @return true if any do, false if none do
- */
- public boolean hasClass(String className) {
- for (Element element : contents) {
- if (element.hasClass(className))
- return true;
- }
- return false;
- }
-
- /**
- * Get the form element's value of the first matched element.
- * @return The form element's value, or empty if not set.
- * @see Element#val()
- */
- public String val() {
- if (size() > 0)
- return first().val();
- else
- return "";
- }
-
- /**
- * Set the form element's value in each of the matched elements.
- * @param value The value to set into each matched element
- * @return this (for chaining)
- */
- public Elements val(String value) {
- for (Element element : contents)
- element.val(value);
- return this;
- }
-
- /**
- * Get the combined text of all the matched elements.
- * <p>
- * Note that it is possible to get repeats if the matched elements contain both parent elements and their own
- * children, as the Element.text() method returns the combined text of a parent and all its children.
- * @return string of all text: unescaped and no HTML.
- * @see Element#text()
- */
- public String text() {
- StringBuilder sb = new StringBuilder();
- for (Element element : contents) {
- if (sb.length() != 0)
- sb.append(" ");
- sb.append(element.text());
- }
- return sb.toString();
- }
-
- public boolean hasText() {
- for (Element element: contents) {
- if (element.hasText())
- return true;
- }
- return false;
- }
-
- /**
- * Get the combined inner HTML of all matched elements.
- * @return string of all element's inner HTML.
- * @see #text()
- * @see #outerHtml()
- */
- public String html() {
- StringBuilder sb = new StringBuilder();
- for (Element element : contents) {
- if (sb.length() != 0)
- sb.append("\n");
- sb.append(element.html());
- }
- return sb.toString();
- }
-
- /**
- * Get the combined outer HTML of all matched elements.
- * @return string of all element's outer HTML.
- * @see #text()
- * @see #html()
- */
- public String outerHtml() {
- StringBuilder sb = new StringBuilder();
- for (Element element : contents) {
- if (sb.length() != 0)
- sb.append("\n");
- sb.append(element.outerHtml());
- }
- return sb.toString();
- }
-
- /**
- * Get the combined outer HTML of all matched elements. Alias of {@link #outerHtml()}.
- * @return string of all element's outer HTML.
- * @see #text()
- * @see #html()
- */
- public String toString() {
- return outerHtml();
- }
-
- /**
- * Update the tag name of each matched element. For example, to change each {@code <i>} to a {@code <em>}, do
- * {@code doc.select("i").tagName("em");}
- * @param tagName the new tag name
- * @return this, for chaining
- * @see Element#tagName(String)
- */
- public Elements tagName(String tagName) {
- for (Element element : contents) {
- element.tagName(tagName);
- }
- return this;
- }
-
- /**
- * Set the inner HTML of each matched element.
- * @param html HTML to parse and set into each matched element.
- * @return this, for chaining
- * @see Element#html(String)
- */
- public Elements html(String html) {
- for (Element element : contents) {
- element.html(html);
- }
- return this;
- }
-
- /**
- * Add the supplied HTML to the start of each matched element's inner HTML.
- * @param html HTML to add inside each element, before the existing HTML
- * @return this, for chaining
- * @see Element#prepend(String)
- */
- public Elements prepend(String html) {
- for (Element element : contents) {
- element.prepend(html);
- }
- return this;
- }
-
- /**
- * Add the supplied HTML to the end of each matched element's inner HTML.
- * @param html HTML to add inside each element, after the existing HTML
- * @return this, for chaining
- * @see Element#append(String)
- */
- public Elements append(String html) {
- for (Element element : contents) {
- element.append(html);
- }
- return this;
- }
-
- /**
- * Insert the supplied HTML before each matched element's outer HTML.
- * @param html HTML to insert before each element
- * @return this, for chaining
- * @see Element#before(String)
- */
- public Elements before(String html) {
- for (Element element : contents) {
- element.before(html);
- }
- return this;
- }
-
- /**
- * Insert the supplied HTML after each matched element's outer HTML.
- * @param html HTML to insert after each element
- * @return this, for chaining
- * @see Element#after(String)
- */
- public Elements after(String html) {
- for (Element element : contents) {
- element.after(html);
- }
- return this;
- }
-
- /**
- Wrap the supplied HTML around each matched elements. For example, with HTML
- {@code <p><b>This</b> is <b>Jsoup</b></p>},
- <code>doc.select("b").wrap("&lt;i&gt;&lt;/i&gt;");</code>
- becomes {@code <p><i><b>This</b></i> is <i><b>jsoup</b></i></p>}
- @param html HTML to wrap around each element, e.g. {@code <div class="head"></div>}. Can be arbitrarily deep.
- @return this (for chaining)
- @see Element#wrap
- */
- public Elements wrap(String html) {
- Validate.notEmpty(html);
- for (Element element : contents) {
- element.wrap(html);
- }
- return this;
- }
-
- /**
- * Removes the matched elements from the DOM, and moves their children up into their parents. This has the effect of
- * dropping the elements but keeping their children.
- * <p/>
- * This is useful for e.g removing unwanted formatting elements but keeping their contents.
- * <p/>
- * E.g. with HTML: {@code <div><font>One</font> <font><a href="/">Two</a></font></div>}<br/>
- * {@code doc.select("font").unwrap();}<br/>
- * HTML = {@code <div>One <a href="/">Two</a></div>}
- *
- * @return this (for chaining)
- * @see Node#unwrap
- */
- public Elements unwrap() {
- for (Element element : contents) {
- element.unwrap();
- }
- return this;
- }
-
- /**
- * Empty (remove all child nodes from) each matched element. This is similar to setting the inner HTML of each
- * element to nothing.
- * <p>
- * E.g. HTML: {@code <div><p>Hello <b>there</b></p> <p>now</p></div>}<br>
- * <code>doc.select("p").empty();</code><br>
- * HTML = {@code <div><p></p> <p></p></div>}
- * @return this, for chaining
- * @see Element#empty()
- * @see #remove()
- */
- public Elements empty() {
- for (Element element : contents) {
- element.empty();
- }
- return this;
- }
-
- /**
- * Remove each matched element from the DOM. This is similar to setting the outer HTML of each element to nothing.
- * <p>
- * E.g. HTML: {@code <div><p>Hello</p> <p>there</p> <img /></div>}<br>
- * <code>doc.select("p").remove();</code><br>
- * HTML = {@code <div> <img /></div>}
- * <p>
- * Note that this method should not be used to clean user-submitted HTML; rather, use {@link org.jsoup.safety.Cleaner} to clean HTML.
- * @return this, for chaining
- * @see Element#empty()
- * @see #empty()
- */
- public Elements remove() {
- for (Element element : contents) {
- element.remove();
- }
- return this;
- }
-
- // filters
-
- /**
- * Find matching elements within this element list.
- * @param query A {@link Selector} query
- * @return the filtered list of elements, or an empty list if none match.
- */
- public Elements select(String query) {
- return Selector.select(query, this);
- }
-
- /**
- * Remove elements from this list that match the {@link Selector} query.
- * <p>
- * E.g. HTML: {@code <div class=logo>One</div> <div>Two</div>}<br>
- * <code>Elements divs = doc.select("div").not("#logo");</code><br>
- * Result: {@code divs: [<div>Two</div>]}
- * <p>
- * @param query the selector query whose results should be removed from these elements
- * @return a new elements list that contains only the filtered results
- */
- public Elements not(String query) {
- Elements out = Selector.select(query, this);
- return Selector.filterOut(this, out);
- }
-
- /**
- * Get the <i>nth</i> matched element as an Elements object.
- * <p>
- * See also {@link #get(int)} to retrieve an Element.
- * @param index the (zero-based) index of the element in the list to retain
- * @return Elements containing only the specified element, or, if that element did not exist, an empty list.
- */
- public Elements eq(int index) {
- return contents.size() > index ? new Elements(get(index)) : new Elements();
- }
-
- /**
- * Test if any of the matched elements match the supplied query.
- * @param query A selector
- * @return true if at least one element in the list matches the query.
- */
- public boolean is(String query) {
- Elements children = select(query);
- return !children.isEmpty();
- }
-
- /**
- * Get all of the parents and ancestor elements of the matched elements.
- * @return all of the parents and ancestor elements of the matched elements
- */
- public Elements parents() {
- HashSet<Element> combo = new LinkedHashSet<Element>();
- for (Element e: contents) {
- combo.addAll(e.parents());
- }
- return new Elements(combo);
- }
-
- // list-like methods
- /**
- Get the first matched element.
- @return The first matched element, or <code>null</code> if contents is empty;
- */
- public Element first() {
- return contents.isEmpty() ? null : contents.get(0);
- }
-
- /**
- Get the last matched element.
- @return The last matched element, or <code>null</code> if contents is empty.
- */
- public Element last() {
- return contents.isEmpty() ? null : contents.get(contents.size() - 1);
- }
-
- /**
- * Perform a depth-first traversal on each of the selected elements.
- * @param nodeVisitor the visitor callbacks to perform on each node
- * @return this, for chaining
- */
- public Elements traverse(NodeVisitor nodeVisitor) {
- Validate.notNull(nodeVisitor);
- NodeTraversor traversor = new NodeTraversor(nodeVisitor);
- for (Element el: contents) {
- traversor.traverse(el);
- }
- return this;
- }
-
- // implements List<Element> delegates:
- public int size() {return contents.size();}
-
- public boolean isEmpty() {return contents.isEmpty();}
-
- public boolean contains(Object o) {return contents.contains(o);}
-
- public Iterator<Element> iterator() {return contents.iterator();}
-
- public Object[] toArray() {return contents.toArray();}
-
- public <T> T[] toArray(T[] a) {return contents.toArray(a);}
-
- public boolean add(Element element) {return contents.add(element);}
-
- public boolean remove(Object o) {return contents.remove(o);}
-
- public boolean containsAll(Collection<?> c) {return contents.containsAll(c);}
-
- public boolean addAll(Collection<? extends Element> c) {return contents.addAll(c);}
-
- public boolean addAll(int index, Collection<? extends Element> c) {return contents.addAll(index, c);}
-
- public boolean removeAll(Collection<?> c) {return contents.removeAll(c);}
-
- public boolean retainAll(Collection<?> c) {return contents.retainAll(c);}
-
- public void clear() {contents.clear();}
-
- public boolean equals(Object o) {return contents.equals(o);}
-
- public int hashCode() {return contents.hashCode();}
-
- public Element get(int index) {return contents.get(index);}
-
- public Element set(int index, Element element) {return contents.set(index, element);}
-
- public void add(int index, Element element) {contents.add(index, element);}
-
- public Element remove(int index) {return contents.remove(index);}
-
- public int indexOf(Object o) {return contents.indexOf(o);}
-
- public int lastIndexOf(Object o) {return contents.lastIndexOf(o);}
-
- public ListIterator<Element> listIterator() {return contents.listIterator();}
-
- public ListIterator<Element> listIterator(int index) {return contents.listIterator(index);}
-
- public List<Element> subList(int fromIndex, int toIndex) {return contents.subList(fromIndex, toIndex);}
-}
diff --git a/src/org/jsoup/select/Evaluator.java b/src/org/jsoup/select/Evaluator.java
deleted file mode 100644
index 16a083bd77..0000000000
--- a/src/org/jsoup/select/Evaluator.java
+++ /dev/null
@@ -1,454 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Element;
-
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/**
- * Evaluates that an element matches the selector.
- */
-public abstract class Evaluator {
- protected Evaluator() {
- }
-
- /**
- * Test if the element meets the evaluator's requirements.
- *
- * @param root Root of the matching subtree
- * @param element tested element
- */
- public abstract boolean matches(Element root, Element element);
-
- /**
- * Evaluator for tag name
- */
- public static final class Tag extends Evaluator {
- private String tagName;
-
- public Tag(String tagName) {
- this.tagName = tagName;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return (element.tagName().equals(tagName));
- }
-
- @Override
- public String toString() {
- return String.format("%s", tagName);
- }
- }
-
- /**
- * Evaluator for element id
- */
- public static final class Id extends Evaluator {
- private String id;
-
- public Id(String id) {
- this.id = id;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return (id.equals(element.id()));
- }
-
- @Override
- public String toString() {
- return String.format("#%s", id);
- }
-
- }
-
- /**
- * Evaluator for element class
- */
- public static final class Class extends Evaluator {
- private String className;
-
- public Class(String className) {
- this.className = className;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return (element.hasClass(className));
- }
-
- @Override
- public String toString() {
- return String.format(".%s", className);
- }
-
- }
-
- /**
- * Evaluator for attribute name matching
- */
- public static final class Attribute extends Evaluator {
- private String key;
-
- public Attribute(String key) {
- this.key = key;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key);
- }
-
- @Override
- public String toString() {
- return String.format("[%s]", key);
- }
-
- }
-
- /**
- * Evaluator for attribute name prefix matching
- */
- public static final class AttributeStarting extends Evaluator {
- private String keyPrefix;
-
- public AttributeStarting(String keyPrefix) {
- this.keyPrefix = keyPrefix;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- List<org.jsoup.nodes.Attribute> values = element.attributes().asList();
- for (org.jsoup.nodes.Attribute attribute : values) {
- if (attribute.getKey().startsWith(keyPrefix))
- return true;
- }
- return false;
- }
-
- @Override
- public String toString() {
- return String.format("[^%s]", keyPrefix);
- }
-
- }
-
- /**
- * Evaluator for attribute name/value matching
- */
- public static final class AttributeWithValue extends AttributeKeyPair {
- public AttributeWithValue(String key, String value) {
- super(key, value);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key) && value.equalsIgnoreCase(element.attr(key));
- }
-
- @Override
- public String toString() {
- return String.format("[%s=%s]", key, value);
- }
-
- }
-
- /**
- * Evaluator for attribute name != value matching
- */
- public static final class AttributeWithValueNot extends AttributeKeyPair {
- public AttributeWithValueNot(String key, String value) {
- super(key, value);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return !value.equalsIgnoreCase(element.attr(key));
- }
-
- @Override
- public String toString() {
- return String.format("[%s!=%s]", key, value);
- }
-
- }
-
- /**
- * Evaluator for attribute name/value matching (value prefix)
- */
- public static final class AttributeWithValueStarting extends AttributeKeyPair {
- public AttributeWithValueStarting(String key, String value) {
- super(key, value);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key) && element.attr(key).toLowerCase().startsWith(value); // value is lower case already
- }
-
- @Override
- public String toString() {
- return String.format("[%s^=%s]", key, value);
- }
-
- }
-
- /**
- * Evaluator for attribute name/value matching (value ending)
- */
- public static final class AttributeWithValueEnding extends AttributeKeyPair {
- public AttributeWithValueEnding(String key, String value) {
- super(key, value);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key) && element.attr(key).toLowerCase().endsWith(value); // value is lower case
- }
-
- @Override
- public String toString() {
- return String.format("[%s$=%s]", key, value);
- }
-
- }
-
- /**
- * Evaluator for attribute name/value matching (value containing)
- */
- public static final class AttributeWithValueContaining extends AttributeKeyPair {
- public AttributeWithValueContaining(String key, String value) {
- super(key, value);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key) && element.attr(key).toLowerCase().contains(value); // value is lower case
- }
-
- @Override
- public String toString() {
- return String.format("[%s*=%s]", key, value);
- }
-
- }
-
- /**
- * Evaluator for attribute name/value matching (value regex matching)
- */
- public static final class AttributeWithValueMatching extends Evaluator {
- String key;
- Pattern pattern;
-
- public AttributeWithValueMatching(String key, Pattern pattern) {
- this.key = key.trim().toLowerCase();
- this.pattern = pattern;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.hasAttr(key) && pattern.matcher(element.attr(key)).find();
- }
-
- @Override
- public String toString() {
- return String.format("[%s~=%s]", key, pattern.toString());
- }
-
- }
-
- /**
- * Abstract evaluator for attribute name/value matching
- */
- public abstract static class AttributeKeyPair extends Evaluator {
- String key;
- String value;
-
- public AttributeKeyPair(String key, String value) {
- Validate.notEmpty(key);
- Validate.notEmpty(value);
-
- this.key = key.trim().toLowerCase();
- this.value = value.trim().toLowerCase();
- }
- }
-
- /**
- * Evaluator for any / all element matching
- */
- public static final class AllElements extends Evaluator {
-
- @Override
- public boolean matches(Element root, Element element) {
- return true;
- }
-
- @Override
- public String toString() {
- return "*";
- }
- }
-
- /**
- * Evaluator for matching by sibling index number (e < idx)
- */
- public static final class IndexLessThan extends IndexEvaluator {
- public IndexLessThan(int index) {
- super(index);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.elementSiblingIndex() < index;
- }
-
- @Override
- public String toString() {
- return String.format(":lt(%d)", index);
- }
-
- }
-
- /**
- * Evaluator for matching by sibling index number (e > idx)
- */
- public static final class IndexGreaterThan extends IndexEvaluator {
- public IndexGreaterThan(int index) {
- super(index);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.elementSiblingIndex() > index;
- }
-
- @Override
- public String toString() {
- return String.format(":gt(%d)", index);
- }
-
- }
-
- /**
- * Evaluator for matching by sibling index number (e = idx)
- */
- public static final class IndexEquals extends IndexEvaluator {
- public IndexEquals(int index) {
- super(index);
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return element.elementSiblingIndex() == index;
- }
-
- @Override
- public String toString() {
- return String.format(":eq(%d)", index);
- }
-
- }
-
- /**
- * Abstract evaluator for sibling index matching
- *
- * @author ant
- */
- public abstract static class IndexEvaluator extends Evaluator {
- int index;
-
- public IndexEvaluator(int index) {
- this.index = index;
- }
- }
-
- /**
- * Evaluator for matching Element (and its descendants) text
- */
- public static final class ContainsText extends Evaluator {
- private String searchText;
-
- public ContainsText(String searchText) {
- this.searchText = searchText.toLowerCase();
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return (element.text().toLowerCase().contains(searchText));
- }
-
- @Override
- public String toString() {
- return String.format(":contains(%s", searchText);
- }
- }
-
- /**
- * Evaluator for matching Element's own text
- */
- public static final class ContainsOwnText extends Evaluator {
- private String searchText;
-
- public ContainsOwnText(String searchText) {
- this.searchText = searchText.toLowerCase();
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- return (element.ownText().toLowerCase().contains(searchText));
- }
-
- @Override
- public String toString() {
- return String.format(":containsOwn(%s", searchText);
- }
- }
-
- /**
- * Evaluator for matching Element (and its descendants) text with regex
- */
- public static final class Matches extends Evaluator {
- private Pattern pattern;
-
- public Matches(Pattern pattern) {
- this.pattern = pattern;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- Matcher m = pattern.matcher(element.text());
- return m.find();
- }
-
- @Override
- public String toString() {
- return String.format(":matches(%s", pattern);
- }
- }
-
- /**
- * Evaluator for matching Element's own text with regex
- */
- public static final class MatchesOwn extends Evaluator {
- private Pattern pattern;
-
- public MatchesOwn(Pattern pattern) {
- this.pattern = pattern;
- }
-
- @Override
- public boolean matches(Element root, Element element) {
- Matcher m = pattern.matcher(element.ownText());
- return m.find();
- }
-
- @Override
- public String toString() {
- return String.format(":matchesOwn(%s", pattern);
- }
- }
-}
diff --git a/src/org/jsoup/select/NodeTraversor.java b/src/org/jsoup/select/NodeTraversor.java
deleted file mode 100644
index 9bb081e56c..0000000000
--- a/src/org/jsoup/select/NodeTraversor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.nodes.Node;
-
-/**
- * Depth-first node traversor. Use to iterate through all nodes under and including the specified root node.
- * <p/>
- * This implementation does not use recursion, so a deep DOM does not risk blowing the stack.
- */
-public class NodeTraversor {
- private NodeVisitor visitor;
-
- /**
- * Create a new traversor.
- * @param visitor a class implementing the {@link NodeVisitor} interface, to be called when visiting each node.
- */
- public NodeTraversor(NodeVisitor visitor) {
- this.visitor = visitor;
- }
-
- /**
- * Start a depth-first traverse of the root and all of its descendants.
- * @param root the root node point to traverse.
- */
- public void traverse(Node root) {
- Node node = root;
- int depth = 0;
-
- while (node != null) {
- visitor.head(node, depth);
- if (node.childNodes().size() > 0) {
- node = node.childNode(0);
- depth++;
- } else {
- while (node.nextSibling() == null && depth > 0) {
- visitor.tail(node, depth);
- node = node.parent();
- depth--;
- }
- visitor.tail(node, depth);
- if (node == root)
- break;
- node = node.nextSibling();
- }
- }
- }
-}
diff --git a/src/org/jsoup/select/NodeVisitor.java b/src/org/jsoup/select/NodeVisitor.java
deleted file mode 100644
index 20112e8d29..0000000000
--- a/src/org/jsoup/select/NodeVisitor.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.nodes.Node;
-
-/**
- * Node visitor interface. Provide an implementing class to {@link NodeTraversor} to iterate through nodes.
- * <p/>
- * This interface provides two methods, {@code head} and {@code tail}. The head method is called when the node is first
- * seen, and the tail method when all of the node's children have been visited. As an example, head can be used to
- * create a start tag for a node, and tail to create the end tag.
- */
-public interface NodeVisitor {
- /**
- * Callback for when a node is first visited.
- *
- * @param node the node being visited.
- * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
- * of that will have depth 1.
- */
- public void head(Node node, int depth);
-
- /**
- * Callback for when a node is last visited, after all of its descendants have been visited.
- *
- * @param node the node being visited.
- * @param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
- * of that will have depth 1.
- */
- public void tail(Node node, int depth);
-}
diff --git a/src/org/jsoup/select/QueryParser.java b/src/org/jsoup/select/QueryParser.java
deleted file mode 100644
index d3cc36f91c..0000000000
--- a/src/org/jsoup/select/QueryParser.java
+++ /dev/null
@@ -1,293 +0,0 @@
-package org.jsoup.select;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-import org.jsoup.helper.StringUtil;
-import org.jsoup.helper.Validate;
-import org.jsoup.parser.TokenQueue;
-
-/**
- * Parses a CSS selector into an Evaluator tree.
- */
-class QueryParser {
- private final static String[] combinators = {",", ">", "+", "~", " "};
-
- private TokenQueue tq;
- private String query;
- private List<Evaluator> evals = new ArrayList<Evaluator>();
-
- /**
- * Create a new QueryParser.
- * @param query CSS query
- */
- private QueryParser(String query) {
- this.query = query;
- this.tq = new TokenQueue(query);
- }
-
- /**
- * Parse a CSS query into an Evaluator.
- * @param query CSS query
- * @return Evaluator
- */
- public static Evaluator parse(String query) {
- QueryParser p = new QueryParser(query);
- return p.parse();
- }
-
- /**
- * Parse the query
- * @return Evaluator
- */
- Evaluator parse() {
- tq.consumeWhitespace();
-
- if (tq.matchesAny(combinators)) { // if starts with a combinator, use root as elements
- evals.add(new StructuralEvaluator.Root());
- combinator(tq.consume());
- } else {
- findElements();
- }
-
- while (!tq.isEmpty()) {
- // hierarchy and extras
- boolean seenWhite = tq.consumeWhitespace();
-
- if (tq.matchesAny(combinators)) {
- combinator(tq.consume());
- } else if (seenWhite) {
- combinator(' ');
- } else { // E.class, E#id, E[attr] etc. AND
- findElements(); // take next el, #. etc off queue
- }
- }
-
- if (evals.size() == 1)
- return evals.get(0);
-
- return new CombiningEvaluator.And(evals);
- }
-
- private void combinator(char combinator) {
- tq.consumeWhitespace();
- String subQuery = consumeSubQuery(); // support multi > childs
-
- Evaluator rootEval; // the new topmost evaluator
- Evaluator currentEval; // the evaluator the new eval will be combined to. could be root, or rightmost or.
- Evaluator newEval = parse(subQuery); // the evaluator to add into target evaluator
- boolean replaceRightMost = false;
-
- if (evals.size() == 1) {
- rootEval = currentEval = evals.get(0);
- // make sure OR (,) has precedence:
- if (rootEval instanceof CombiningEvaluator.Or && combinator != ',') {
- currentEval = ((CombiningEvaluator.Or) currentEval).rightMostEvaluator();
- replaceRightMost = true;
- }
- }
- else {
- rootEval = currentEval = new CombiningEvaluator.And(evals);
- }
- evals.clear();
-
- // for most combinators: change the current eval into an AND of the current eval and the new eval
- if (combinator == '>')
- currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediateParent(currentEval));
- else if (combinator == ' ')
- currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.Parent(currentEval));
- else if (combinator == '+')
- currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.ImmediatePreviousSibling(currentEval));
- else if (combinator == '~')
- currentEval = new CombiningEvaluator.And(newEval, new StructuralEvaluator.PreviousSibling(currentEval));
- else if (combinator == ',') { // group or.
- CombiningEvaluator.Or or;
- if (currentEval instanceof CombiningEvaluator.Or) {
- or = (CombiningEvaluator.Or) currentEval;
- or.add(newEval);
- } else {
- or = new CombiningEvaluator.Or();
- or.add(currentEval);
- or.add(newEval);
- }
- currentEval = or;
- }
- else
- throw new Selector.SelectorParseException("Unknown combinator: " + combinator);
-
- if (replaceRightMost)
- ((CombiningEvaluator.Or) rootEval).replaceRightMostEvaluator(currentEval);
- else rootEval = currentEval;
- evals.add(rootEval);
- }
-
- private String consumeSubQuery() {
- StringBuilder sq = new StringBuilder();
- while (!tq.isEmpty()) {
- if (tq.matches("("))
- sq.append("(").append(tq.chompBalanced('(', ')')).append(")");
- else if (tq.matches("["))
- sq.append("[").append(tq.chompBalanced('[', ']')).append("]");
- else if (tq.matchesAny(combinators))
- break;
- else
- sq.append(tq.consume());
- }
- return sq.toString();
- }
-
- private void findElements() {
- if (tq.matchChomp("#"))
- byId();
- else if (tq.matchChomp("."))
- byClass();
- else if (tq.matchesWord())
- byTag();
- else if (tq.matches("["))
- byAttribute();
- else if (tq.matchChomp("*"))
- allElements();
- else if (tq.matchChomp(":lt("))
- indexLessThan();
- else if (tq.matchChomp(":gt("))
- indexGreaterThan();
- else if (tq.matchChomp(":eq("))
- indexEquals();
- else if (tq.matches(":has("))
- has();
- else if (tq.matches(":contains("))
- contains(false);
- else if (tq.matches(":containsOwn("))
- contains(true);
- else if (tq.matches(":matches("))
- matches(false);
- else if (tq.matches(":matchesOwn("))
- matches(true);
- else if (tq.matches(":not("))
- not();
- else // unhandled
- throw new Selector.SelectorParseException("Could not parse query '%s': unexpected token at '%s'", query, tq.remainder());
-
- }
-
- private void byId() {
- String id = tq.consumeCssIdentifier();
- Validate.notEmpty(id);
- evals.add(new Evaluator.Id(id));
- }
-
- private void byClass() {
- String className = tq.consumeCssIdentifier();
- Validate.notEmpty(className);
- evals.add(new Evaluator.Class(className.trim().toLowerCase()));
- }
-
- private void byTag() {
- String tagName = tq.consumeElementSelector();
- Validate.notEmpty(tagName);
-
- // namespaces: if element name is "abc:def", selector must be "abc|def", so flip:
- if (tagName.contains("|"))
- tagName = tagName.replace("|", ":");
-
- evals.add(new Evaluator.Tag(tagName.trim().toLowerCase()));
- }
-
- private void byAttribute() {
- TokenQueue cq = new TokenQueue(tq.chompBalanced('[', ']')); // content queue
- String key = cq.consumeToAny("=", "!=", "^=", "$=", "*=", "~="); // eq, not, start, end, contain, match, (no val)
- Validate.notEmpty(key);
- cq.consumeWhitespace();
-
- if (cq.isEmpty()) {
- if (key.startsWith("^"))
- evals.add(new Evaluator.AttributeStarting(key.substring(1)));
- else
- evals.add(new Evaluator.Attribute(key));
- } else {
- if (cq.matchChomp("="))
- evals.add(new Evaluator.AttributeWithValue(key, cq.remainder()));
-
- else if (cq.matchChomp("!="))
- evals.add(new Evaluator.AttributeWithValueNot(key, cq.remainder()));
-
- else if (cq.matchChomp("^="))
- evals.add(new Evaluator.AttributeWithValueStarting(key, cq.remainder()));
-
- else if (cq.matchChomp("$="))
- evals.add(new Evaluator.AttributeWithValueEnding(key, cq.remainder()));
-
- else if (cq.matchChomp("*="))
- evals.add(new Evaluator.AttributeWithValueContaining(key, cq.remainder()));
-
- else if (cq.matchChomp("~="))
- evals.add(new Evaluator.AttributeWithValueMatching(key, Pattern.compile(cq.remainder())));
- else
- throw new Selector.SelectorParseException("Could not parse attribute query '%s': unexpected token at '%s'", query, cq.remainder());
- }
- }
-
- private void allElements() {
- evals.add(new Evaluator.AllElements());
- }
-
- // pseudo selectors :lt, :gt, :eq
- private void indexLessThan() {
- evals.add(new Evaluator.IndexLessThan(consumeIndex()));
- }
-
- private void indexGreaterThan() {
- evals.add(new Evaluator.IndexGreaterThan(consumeIndex()));
- }
-
- private void indexEquals() {
- evals.add(new Evaluator.IndexEquals(consumeIndex()));
- }
-
- private int consumeIndex() {
- String indexS = tq.chompTo(")").trim();
- Validate.isTrue(StringUtil.isNumeric(indexS), "Index must be numeric");
- return Integer.parseInt(indexS);
- }
-
- // pseudo selector :has(el)
- private void has() {
- tq.consume(":has");
- String subQuery = tq.chompBalanced('(', ')');
- Validate.notEmpty(subQuery, ":has(el) subselect must not be empty");
- evals.add(new StructuralEvaluator.Has(parse(subQuery)));
- }
-
- // pseudo selector :contains(text), containsOwn(text)
- private void contains(boolean own) {
- tq.consume(own ? ":containsOwn" : ":contains");
- String searchText = TokenQueue.unescape(tq.chompBalanced('(', ')'));
- Validate.notEmpty(searchText, ":contains(text) query must not be empty");
- if (own)
- evals.add(new Evaluator.ContainsOwnText(searchText));
- else
- evals.add(new Evaluator.ContainsText(searchText));
- }
-
- // :matches(regex), matchesOwn(regex)
- private void matches(boolean own) {
- tq.consume(own ? ":matchesOwn" : ":matches");
- String regex = tq.chompBalanced('(', ')'); // don't unescape, as regex bits will be escaped
- Validate.notEmpty(regex, ":matches(regex) query must not be empty");
-
- if (own)
- evals.add(new Evaluator.MatchesOwn(Pattern.compile(regex)));
- else
- evals.add(new Evaluator.Matches(Pattern.compile(regex)));
- }
-
- // :not(selector)
- private void not() {
- tq.consume(":not");
- String subQuery = tq.chompBalanced('(', ')');
- Validate.notEmpty(subQuery, ":not(selector) subselect must not be empty");
-
- evals.add(new StructuralEvaluator.Not(parse(subQuery)));
- }
-}
diff --git a/src/org/jsoup/select/Selector.java b/src/org/jsoup/select/Selector.java
deleted file mode 100644
index 8fc6286798..0000000000
--- a/src/org/jsoup/select/Selector.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.helper.Validate;
-import org.jsoup.nodes.Element;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-
-/**
- * CSS-like element selector, that finds elements matching a query.
- * <p/>
- * <h2>Selector syntax</h2>
- * A selector is a chain of simple selectors, separated by combinators. Selectors are case insensitive (including against
- * elements, attributes, and attribute values).
- * <p/>
- * The universal selector (*) is implicit when no element selector is supplied (i.e. {@code *.header} and {@code .header}
- * is equivalent).
- * <p/>
- * <table>
- * <tr><th>Pattern</th><th>Matches</th><th>Example</th></tr>
- * <tr><td><code>*</code></td><td>any element</td><td><code>*</code></td></tr>
- * <tr><td><code>tag</code></td><td>elements with the given tag name</td><td><code>div</code></td></tr>
- * <tr><td><code>ns|E</code></td><td>elements of type E in the namespace <i>ns</i></td><td><code>fb|name</code> finds <code>&lt;fb:name></code> elements</td></tr>
- * <tr><td><code>#id</code></td><td>elements with attribute ID of "id"</td><td><code>div#wrap</code>, <code>#logo</code></td></tr>
- * <tr><td><code>.class</code></td><td>elements with a class name of "class"</td><td><code>div.left</code>, <code>.result</code></td></tr>
- * <tr><td><code>[attr]</code></td><td>elements with an attribute named "attr" (with any value)</td><td><code>a[href]</code>, <code>[title]</code></td></tr>
- * <tr><td><code>[^attrPrefix]</code></td><td>elements with an attribute name starting with "attrPrefix". Use to find elements with HTML5 datasets</td><td><code>[^data-]</code>, <code>div[^data-]</code></td></tr>
- * <tr><td><code>[attr=val]</code></td><td>elements with an attribute named "attr", and value equal to "val"</td><td><code>img[width=500]</code>, <code>a[rel=nofollow]</code></td></tr>
- * <tr><td><code>[attr^=valPrefix]</code></td><td>elements with an attribute named "attr", and value starting with "valPrefix"</td><td><code>a[href^=http:]</code></code></td></tr>
- * <tr><td><code>[attr$=valSuffix]</code></td><td>elements with an attribute named "attr", and value ending with "valSuffix"</td><td><code>img[src$=.png]</code></td></tr>
- * <tr><td><code>[attr*=valContaining]</code></td><td>elements with an attribute named "attr", and value containing "valContaining"</td><td><code>a[href*=/search/]</code></td></tr>
- * <tr><td><code>[attr~=<em>regex</em>]</code></td><td>elements with an attribute named "attr", and value matching the regular expression</td><td><code>img[src~=(?i)\\.(png|jpe?g)]</code></td></tr>
- * <tr><td></td><td>The above may be combined in any order</td><td><code>div.header[title]</code></td></tr>
- * <tr><td><td colspan="3"><h3>Combinators</h3></td></tr>
- * <tr><td><code>E F</code></td><td>an F element descended from an E element</td><td><code>div a</code>, <code>.logo h1</code></td></tr>
- * <tr><td><code>E > F</code></td><td>an F direct child of E</td><td><code>ol > li</code></td></tr>
- * <tr><td><code>E + F</code></td><td>an F element immediately preceded by sibling E</td><td><code>li + li</code>, <code>div.head + div</code></td></tr>
- * <tr><td><code>E ~ F</code></td><td>an F element preceded by sibling E</td><td><code>h1 ~ p</code></td></tr>
- * <tr><td><code>E, F, G</code></td><td>all matching elements E, F, or G</td><td><code>a[href], div, h3</code></td></tr>
- * <tr><td><td colspan="3"><h3>Pseudo selectors</h3></td></tr>
- * <tr><td><code>:lt(<em>n</em>)</code></td><td>elements whose sibling index is less than <em>n</em></td><td><code>td:lt(3)</code> finds the first 2 cells of each row</td></tr>
- * <tr><td><code>:gt(<em>n</em>)</code></td><td>elements whose sibling index is greater than <em>n</em></td><td><code>td:gt(1)</code> finds cells after skipping the first two</td></tr>
- * <tr><td><code>:eq(<em>n</em>)</code></td><td>elements whose sibling index is equal to <em>n</em></td><td><code>td:eq(0)</code> finds the first cell of each row</td></tr>
- * <tr><td><code>:has(<em>selector</em>)</code></td><td>elements that contains at least one element matching the <em>selector</em></td><td><code>div:has(p)</code> finds divs that contain p elements </td></tr>
- * <tr><td><code>:not(<em>selector</em>)</code></td><td>elements that do not match the <em>selector</em>. See also {@link Elements#not(String)}</td><td><code>div:not(.logo)</code> finds all divs that do not have the "logo" class.<br /><code>div:not(:has(div))</code> finds divs that do not contain divs.</code></td></tr>
- * <tr><td><code>:contains(<em>text</em>)</code></td><td>elements that contains the specified text. The search is case insensitive. The text may appear in the found element, or any of its descendants.</td><td><code>p:contains(jsoup)</code> finds p elements containing the text "jsoup".</td></tr>
- * <tr><td><code>:matches(<em>regex</em>)</code></td><td>elements whose text matches the specified regular expression. The text may appear in the found element, or any of its descendants.</td><td><code>td:matches(\\d+)</code> finds table cells containing digits. <code>div:matches((?i)login)</code> finds divs containing the text, case insensitively.</td></tr>
- * <tr><td><code>:containsOwn(<em>text</em>)</code></td><td>elements that directly contains the specified text. The search is case insensitive. The text must appear in the found element, not any of its descendants.</td><td><code>p:containsOwn(jsoup)</code> finds p elements with own text "jsoup".</td></tr>
- * <tr><td><code>:matchesOwn(<em>regex</em>)</code></td><td>elements whose own text matches the specified regular expression. The text must appear in the found element, not any of its descendants.</td><td><code>td:matchesOwn(\\d+)</code> finds table cells directly containing digits. <code>div:matchesOwn((?i)login)</code> finds divs containing the text, case insensitively.</td></tr>
- * <tr><td></td><td>The above may be combined in any order and with other selectors</td><td><code>.light:contains(name):eq(0)</code></td></tr>
- * </table>
- *
- * @author Jonathan Hedley, jonathan@hedley.net
- * @see Element#select(String)
- */
-public class Selector {
- private final Evaluator evaluator;
- private final Element root;
-
- private Selector(String query, Element root) {
- Validate.notNull(query);
- query = query.trim();
- Validate.notEmpty(query);
- Validate.notNull(root);
-
- this.evaluator = QueryParser.parse(query);
-
- this.root = root;
- }
-
- /**
- * Find elements matching selector.
- *
- * @param query CSS selector
- * @param root root element to descend into
- * @return matching elements, empty if not
- */
- public static Elements select(String query, Element root) {
- return new Selector(query, root).select();
- }
-
- /**
- * Find elements matching selector.
- *
- * @param query CSS selector
- * @param roots root elements to descend into
- * @return matching elements, empty if not
- */
- public static Elements select(String query, Iterable<Element> roots) {
- Validate.notEmpty(query);
- Validate.notNull(roots);
- LinkedHashSet<Element> elements = new LinkedHashSet<Element>();
-
- for (Element root : roots) {
- elements.addAll(select(query, root));
- }
- return new Elements(elements);
- }
-
- private Elements select() {
- return Collector.collect(evaluator, root);
- }
-
- // exclude set. package open so that Elements can implement .not() selector.
- static Elements filterOut(Collection<Element> elements, Collection<Element> outs) {
- Elements output = new Elements();
- for (Element el : elements) {
- boolean found = false;
- for (Element out : outs) {
- if (el.equals(out)) {
- found = true;
- break;
- }
- }
- if (!found)
- output.add(el);
- }
- return output;
- }
-
- public static class SelectorParseException extends IllegalStateException {
- public SelectorParseException(String msg, Object... params) {
- super(String.format(msg, params));
- }
- }
-}
diff --git a/src/org/jsoup/select/StructuralEvaluator.java b/src/org/jsoup/select/StructuralEvaluator.java
deleted file mode 100644
index 69e8a62e58..0000000000
--- a/src/org/jsoup/select/StructuralEvaluator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.jsoup.select;
-
-import org.jsoup.nodes.Element;
-
-/**
- * Base structural evaluator.
- */
-abstract class StructuralEvaluator extends Evaluator {
- Evaluator evaluator;
-
- static class Root extends Evaluator {
- public boolean matches(Element root, Element element) {
- return root == element;
- }
- }
-
- static class Has extends StructuralEvaluator {
- public Has(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element element) {
- for (Element e : element.getAllElements()) {
- if (e != element && evaluator.matches(root, e))
- return true;
- }
- return false;
- }
-
- public String toString() {
- return String.format(":has(%s)", evaluator);
- }
- }
-
- static class Not extends StructuralEvaluator {
- public Not(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element node) {
- return !evaluator.matches(root, node);
- }
-
- public String toString() {
- return String.format(":not%s", evaluator);
- }
- }
-
- static class Parent extends StructuralEvaluator {
- public Parent(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element element) {
- if (root == element)
- return false;
-
- Element parent = element.parent();
- while (parent != root) {
- if (evaluator.matches(root, parent))
- return true;
- parent = parent.parent();
- }
- return false;
- }
-
- public String toString() {
- return String.format(":parent%s", evaluator);
- }
- }
-
- static class ImmediateParent extends StructuralEvaluator {
- public ImmediateParent(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element element) {
- if (root == element)
- return false;
-
- Element parent = element.parent();
- return parent != null && evaluator.matches(root, parent);
- }
-
- public String toString() {
- return String.format(":ImmediateParent%s", evaluator);
- }
- }
-
- static class PreviousSibling extends StructuralEvaluator {
- public PreviousSibling(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element element) {
- if (root == element)
- return false;
-
- Element prev = element.previousElementSibling();
-
- while (prev != null) {
- if (evaluator.matches(root, prev))
- return true;
-
- prev = prev.previousElementSibling();
- }
- return false;
- }
-
- public String toString() {
- return String.format(":prev*%s", evaluator);
- }
- }
-
- static class ImmediatePreviousSibling extends StructuralEvaluator {
- public ImmediatePreviousSibling(Evaluator evaluator) {
- this.evaluator = evaluator;
- }
-
- public boolean matches(Element root, Element element) {
- if (root == element)
- return false;
-
- Element prev = element.previousElementSibling();
- return prev != null && evaluator.matches(root, prev);
- }
-
- public String toString() {
- return String.format(":prev%s", evaluator);
- }
- }
-}
diff --git a/src/org/jsoup/select/package-info.java b/src/org/jsoup/select/package-info.java
deleted file mode 100644
index a6e6a2fa0f..0000000000
--- a/src/org/jsoup/select/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- Packages to support the CSS-style element selector.
- */
-package org.jsoup.select; \ No newline at end of file