From e85d933b25cc3c5cc85eb7eb4b13b950fd8e1569 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 13 Aug 2012 18:34:33 +0300 Subject: Moved server files to a server src folder (#9299) --- src/com/vaadin/Application.java | 2426 --------- .../RootRequiresMoreInformationException.java | 25 - src/com/vaadin/Vaadin.gwt.xml | 85 - src/com/vaadin/Version.java | 74 - src/com/vaadin/annotations/AutoGenerated.java | 18 - src/com/vaadin/annotations/EagerInit.java | 30 - src/com/vaadin/annotations/JavaScript.java | 41 - src/com/vaadin/annotations/StyleSheet.java | 38 - src/com/vaadin/annotations/Theme.java | 24 - src/com/vaadin/annotations/Widgetset.java | 25 - src/com/vaadin/annotations/package.html | 12 - src/com/vaadin/data/Buffered.java | 280 - src/com/vaadin/data/BufferedValidatable.java | 35 - src/com/vaadin/data/Collapsible.java | 68 - src/com/vaadin/data/Container.java | 1105 ---- src/com/vaadin/data/Item.java | 180 - src/com/vaadin/data/Property.java | 402 -- src/com/vaadin/data/Validatable.java | 110 - src/com/vaadin/data/Validator.java | 175 - src/com/vaadin/data/fieldgroup/BeanFieldGroup.java | 157 - src/com/vaadin/data/fieldgroup/Caption.java | 15 - .../fieldgroup/DefaultFieldGroupFieldFactory.java | 157 - src/com/vaadin/data/fieldgroup/FieldGroup.java | 978 ---- .../data/fieldgroup/FieldGroupFieldFactory.java | 31 - src/com/vaadin/data/fieldgroup/PropertyId.java | 15 - src/com/vaadin/data/package.html | 49 - .../vaadin/data/util/AbstractBeanContainer.java | 856 --- src/com/vaadin/data/util/AbstractContainer.java | 251 - .../data/util/AbstractInMemoryContainer.java | 941 ---- src/com/vaadin/data/util/AbstractProperty.java | 226 - src/com/vaadin/data/util/BeanContainer.java | 168 - src/com/vaadin/data/util/BeanItem.java | 269 - src/com/vaadin/data/util/BeanItemContainer.java | 241 - .../data/util/ContainerHierarchicalWrapper.java | 792 --- .../vaadin/data/util/ContainerOrderedWrapper.java | 644 --- src/com/vaadin/data/util/DefaultItemSorter.java | 210 - src/com/vaadin/data/util/FilesystemContainer.java | 918 ---- .../vaadin/data/util/HierarchicalContainer.java | 814 --- .../util/HierarchicalContainerOrderedWrapper.java | 70 - src/com/vaadin/data/util/IndexedContainer.java | 1109 ---- src/com/vaadin/data/util/ItemSorter.java | 57 - src/com/vaadin/data/util/ListSet.java | 264 - src/com/vaadin/data/util/MethodProperty.java | 784 --- .../vaadin/data/util/MethodPropertyDescriptor.java | 134 - src/com/vaadin/data/util/NestedMethodProperty.java | 257 - .../vaadin/data/util/NestedPropertyDescriptor.java | 60 - src/com/vaadin/data/util/ObjectProperty.java | 141 - src/com/vaadin/data/util/PropertyFormatter.java | 245 - src/com/vaadin/data/util/PropertysetItem.java | 340 -- src/com/vaadin/data/util/QueryContainer.java | 675 --- src/com/vaadin/data/util/TextFileProperty.java | 144 - .../data/util/TransactionalPropertyWrapper.java | 114 - .../vaadin/data/util/VaadinPropertyDescriptor.java | 43 - src/com/vaadin/data/util/converter/Converter.java | 159 - .../data/util/converter/ConverterFactory.java | 23 - .../vaadin/data/util/converter/ConverterUtil.java | 168 - .../data/util/converter/DateToLongConverter.java | 72 - .../util/converter/DefaultConverterFactory.java | 101 - .../data/util/converter/ReverseConverter.java | 84 - .../util/converter/StringToBooleanConverter.java | 108 - .../data/util/converter/StringToDateConverter.java | 112 - .../util/converter/StringToDoubleConverter.java | 107 - .../util/converter/StringToIntegerConverter.java | 88 - .../util/converter/StringToNumberConverter.java | 111 - .../data/util/filter/AbstractJunctionFilter.java | 76 - src/com/vaadin/data/util/filter/And.java | 44 - src/com/vaadin/data/util/filter/Between.java | 74 - src/com/vaadin/data/util/filter/Compare.java | 327 -- src/com/vaadin/data/util/filter/IsNull.java | 79 - src/com/vaadin/data/util/filter/Like.java | 83 - src/com/vaadin/data/util/filter/Not.java | 70 - src/com/vaadin/data/util/filter/Or.java | 63 - .../data/util/filter/SimpleStringFilter.java | 152 - .../util/filter/UnsupportedFilterException.java | 35 - src/com/vaadin/data/util/package.html | 18 - .../data/util/sqlcontainer/CacheFlushNotifier.java | 92 - .../vaadin/data/util/sqlcontainer/CacheMap.java | 31 - .../data/util/sqlcontainer/ColumnProperty.java | 248 - .../util/sqlcontainer/OptimisticLockException.java | 38 - .../data/util/sqlcontainer/ReadOnlyRowId.java | 31 - .../vaadin/data/util/sqlcontainer/Reference.java | 56 - src/com/vaadin/data/util/sqlcontainer/RowId.java | 81 - src/com/vaadin/data/util/sqlcontainer/RowItem.java | 133 - .../data/util/sqlcontainer/SQLContainer.java | 1716 ------ src/com/vaadin/data/util/sqlcontainer/SQLUtil.java | 36 - .../data/util/sqlcontainer/TemporaryRowId.java | 32 - .../connection/J2EEConnectionPool.java | 72 - .../connection/JDBCConnectionPool.java | 41 - .../connection/SimpleJDBCConnectionPool.java | 168 - .../util/sqlcontainer/query/FreeformQuery.java | 507 -- .../sqlcontainer/query/FreeformQueryDelegate.java | 118 - .../query/FreeformStatementDelegate.java | 57 - .../data/util/sqlcontainer/query/OrderBy.java | 46 - .../util/sqlcontainer/query/QueryDelegate.java | 211 - .../data/util/sqlcontainer/query/TableQuery.java | 715 --- .../query/generator/DefaultSQLGenerator.java | 367 -- .../query/generator/MSSQLGenerator.java | 101 - .../query/generator/OracleGenerator.java | 112 - .../sqlcontainer/query/generator/SQLGenerator.java | 88 - .../query/generator/StatementHelper.java | 163 - .../query/generator/filter/AndTranslator.java | 23 - .../query/generator/filter/BetweenTranslator.java | 25 - .../query/generator/filter/CompareTranslator.java | 38 - .../query/generator/filter/FilterTranslator.java | 16 - .../query/generator/filter/IsNullTranslator.java | 22 - .../query/generator/filter/LikeTranslator.java | 30 - .../query/generator/filter/NotTranslator.java | 29 - .../query/generator/filter/OrTranslator.java | 23 - .../query/generator/filter/QueryBuilder.java | 98 - .../generator/filter/SimpleStringTranslator.java | 30 - .../query/generator/filter/StringDecorator.java | 58 - .../data/validator/AbstractStringValidator.java | 42 - .../vaadin/data/validator/AbstractValidator.java | 139 - src/com/vaadin/data/validator/BeanValidator.java | 176 - .../vaadin/data/validator/CompositeValidator.java | 259 - .../vaadin/data/validator/DateRangeValidator.java | 51 - .../data/validator/DoubleRangeValidator.java | 37 - src/com/vaadin/data/validator/DoubleValidator.java | 58 - src/com/vaadin/data/validator/EmailValidator.java | 35 - .../data/validator/IntegerRangeValidator.java | 37 - .../vaadin/data/validator/IntegerValidator.java | 58 - src/com/vaadin/data/validator/NullValidator.java | 92 - src/com/vaadin/data/validator/RangeValidator.java | 186 - src/com/vaadin/data/validator/RegexpValidator.java | 97 - .../data/validator/StringLengthValidator.java | 139 - src/com/vaadin/data/validator/package.html | 23 - src/com/vaadin/event/Action.java | 195 - src/com/vaadin/event/ActionManager.java | 249 - src/com/vaadin/event/ComponentEventListener.java | 11 - src/com/vaadin/event/DataBoundTransferable.java | 66 - src/com/vaadin/event/EventRouter.java | 201 - src/com/vaadin/event/FieldEvents.java | 275 - src/com/vaadin/event/ItemClickEvent.java | 121 - src/com/vaadin/event/LayoutEvents.java | 138 - src/com/vaadin/event/ListenerMethod.java | 663 --- src/com/vaadin/event/MethodEventSource.java | 157 - src/com/vaadin/event/MouseEvents.java | 234 - src/com/vaadin/event/ShortcutAction.java | 373 -- src/com/vaadin/event/ShortcutListener.java | 33 - src/com/vaadin/event/Transferable.java | 57 - src/com/vaadin/event/TransferableImpl.java | 47 - src/com/vaadin/event/dd/DragAndDropEvent.java | 50 - src/com/vaadin/event/dd/DragSource.java | 52 - src/com/vaadin/event/dd/DropHandler.java | 61 - src/com/vaadin/event/dd/DropTarget.java | 42 - src/com/vaadin/event/dd/TargetDetails.java | 37 - src/com/vaadin/event/dd/TargetDetailsImpl.java | 46 - .../vaadin/event/dd/acceptcriteria/AcceptAll.java | 36 - .../event/dd/acceptcriteria/AcceptCriterion.java | 75 - src/com/vaadin/event/dd/acceptcriteria/And.java | 54 - .../dd/acceptcriteria/ClientSideCriterion.java | 61 - .../dd/acceptcriteria/ContainsDataFlavor.java | 53 - src/com/vaadin/event/dd/acceptcriteria/Not.java | 39 - src/com/vaadin/event/dd/acceptcriteria/Or.java | 52 - .../dd/acceptcriteria/ServerSideCriterion.java | 57 - .../vaadin/event/dd/acceptcriteria/SourceIs.java | 67 - .../event/dd/acceptcriteria/SourceIsTarget.java | 51 - .../event/dd/acceptcriteria/TargetDetailIs.java | 72 - src/com/vaadin/event/package.html | 58 - src/com/vaadin/external/json/JSONArray.java | 963 ---- src/com/vaadin/external/json/JSONException.java | 32 - src/com/vaadin/external/json/JSONObject.java | 1693 ------ src/com/vaadin/external/json/JSONString.java | 21 - src/com/vaadin/external/json/JSONStringer.java | 84 - src/com/vaadin/external/json/JSONTokener.java | 451 -- src/com/vaadin/external/json/JSONWriter.java | 355 -- src/com/vaadin/external/json/README | 68 - src/com/vaadin/navigator/FragmentManager.java | 38 - src/com/vaadin/navigator/Navigator.java | 656 --- src/com/vaadin/navigator/View.java | 36 - src/com/vaadin/navigator/ViewChangeListener.java | 118 - src/com/vaadin/navigator/ViewDisplay.java | 29 - src/com/vaadin/navigator/ViewProvider.java | 44 - src/com/vaadin/package.html | 27 - .../portal/gwt/PortalDefaultWidgetSet.gwt.xml | 6 - src/com/vaadin/service/ApplicationContext.java | 165 - src/com/vaadin/service/FileTypeResolver.java | 385 -- src/com/vaadin/service/package.html | 20 - .../vaadin/terminal/AbstractClientConnector.java | 510 -- src/com/vaadin/terminal/AbstractErrorMessage.java | 176 - src/com/vaadin/terminal/AbstractExtension.java | 76 - .../terminal/AbstractJavaScriptExtension.java | 162 - src/com/vaadin/terminal/ApplicationResource.java | 75 - src/com/vaadin/terminal/ClassResource.java | 178 - src/com/vaadin/terminal/CombinedRequest.java | 187 - src/com/vaadin/terminal/CompositeErrorMessage.java | 112 - .../vaadin/terminal/DeploymentConfiguration.java | 123 - src/com/vaadin/terminal/DownloadStream.java | 335 -- src/com/vaadin/terminal/ErrorMessage.java | 126 - src/com/vaadin/terminal/Extension.java | 27 - src/com/vaadin/terminal/ExternalResource.java | 118 - src/com/vaadin/terminal/FileResource.java | 174 - .../vaadin/terminal/JavaScriptCallbackHelper.java | 116 - src/com/vaadin/terminal/KeyMapper.java | 86 - src/com/vaadin/terminal/LegacyPaint.java | 85 - src/com/vaadin/terminal/Page.java | 646 --- src/com/vaadin/terminal/PaintException.java | 54 - src/com/vaadin/terminal/PaintTarget.java | 509 -- src/com/vaadin/terminal/RequestHandler.java | 36 - src/com/vaadin/terminal/Resource.java | 26 - src/com/vaadin/terminal/Scrollable.java | 80 - src/com/vaadin/terminal/Sizeable.java | 242 - src/com/vaadin/terminal/StreamResource.java | 222 - src/com/vaadin/terminal/StreamVariable.java | 157 - src/com/vaadin/terminal/SystemError.java | 82 - src/com/vaadin/terminal/Terminal.java | 80 - src/com/vaadin/terminal/ThemeResource.java | 96 - src/com/vaadin/terminal/UserError.java | 70 - src/com/vaadin/terminal/Vaadin6Component.java | 44 - src/com/vaadin/terminal/VariableOwner.java | 85 - src/com/vaadin/terminal/WrappedRequest.java | 277 - src/com/vaadin/terminal/WrappedResponse.java | 147 - .../gwt/server/AbstractApplicationPortlet.java | 1079 ---- .../gwt/server/AbstractApplicationServlet.java | 1623 ------ .../gwt/server/AbstractCommunicationManager.java | 2790 ---------- .../server/AbstractDeploymentConfiguration.java | 143 - .../gwt/server/AbstractStreamingEvent.java | 46 - .../gwt/server/AbstractWebApplicationContext.java | 268 - .../vaadin/terminal/gwt/server/AddonContext.java | 80 - .../terminal/gwt/server/AddonContextEvent.java | 19 - .../terminal/gwt/server/AddonContextListener.java | 13 - .../terminal/gwt/server/ApplicationPortlet2.java | 38 - .../gwt/server/ApplicationResourceHandler.java | 55 - .../terminal/gwt/server/ApplicationServlet.java | 78 - .../gwt/server/ApplicationStartedEvent.java | 28 - .../gwt/server/ApplicationStartedListener.java | 11 - .../vaadin/terminal/gwt/server/BootstrapDom.java | 9 - .../gwt/server/BootstrapFragmentResponse.java | 28 - .../terminal/gwt/server/BootstrapHandler.java | 570 -- .../terminal/gwt/server/BootstrapListener.java | 13 - .../terminal/gwt/server/BootstrapPageResponse.java | 39 - .../terminal/gwt/server/BootstrapResponse.java | 45 - .../gwt/server/ChangeVariablesErrorEvent.java | 39 - .../terminal/gwt/server/ClientConnector.java | 149 - .../gwt/server/ClientMethodInvocation.java | 71 - .../terminal/gwt/server/CommunicationManager.java | 122 - .../gwt/server/ComponentSizeValidator.java | 664 --- src/com/vaadin/terminal/gwt/server/Constants.java | 80 - .../terminal/gwt/server/DragAndDropService.java | 313 -- .../terminal/gwt/server/GAEApplicationServlet.java | 417 -- .../gwt/server/HttpServletRequestListener.java | 54 - src/com/vaadin/terminal/gwt/server/JsonCodec.java | 792 --- .../terminal/gwt/server/JsonPaintTarget.java | 1022 ---- .../server/LegacyChangeVariablesInvocation.java | 38 - .../gwt/server/NoInputStreamException.java | 9 - .../gwt/server/NoOutputStreamException.java | 9 - .../gwt/server/PortletApplicationContext2.java | 398 -- .../gwt/server/PortletCommunicationManager.java | 170 - .../gwt/server/PortletRequestListener.java | 56 - .../vaadin/terminal/gwt/server/RequestTimer.java | 43 - .../terminal/gwt/server/ResourceReference.java | 67 - .../gwt/server/RestrictedRenderResponse.java | 172 - src/com/vaadin/terminal/gwt/server/RpcManager.java | 48 - src/com/vaadin/terminal/gwt/server/RpcTarget.java | 28 - .../terminal/gwt/server/ServerRpcManager.java | 142 - .../gwt/server/ServerRpcMethodInvocation.java | 113 - .../terminal/gwt/server/ServletPortletHelper.java | 120 - .../gwt/server/SessionExpiredException.java | 9 - .../terminal/gwt/server/StreamingEndEventImpl.java | 16 - .../gwt/server/StreamingErrorEventImpl.java | 25 - .../gwt/server/StreamingProgressEventImpl.java | 17 - .../gwt/server/StreamingStartEventImpl.java | 28 - .../gwt/server/SystemMessageException.java | 57 - .../gwt/server/UnsupportedBrowserHandler.java | 89 - .../terminal/gwt/server/UploadException.java | 15 - .../terminal/gwt/server/WebApplicationContext.java | 180 - src/com/vaadin/terminal/gwt/server/WebBrowser.java | 462 -- .../gwt/server/WrappedHttpServletRequest.java | 118 - .../gwt/server/WrappedHttpServletResponse.java | 75 - .../terminal/gwt/server/WrappedPortletRequest.java | 217 - .../gwt/server/WrappedPortletResponse.java | 111 - src/com/vaadin/terminal/package.html | 21 - src/com/vaadin/tools/ReflectTools.java | 126 - src/com/vaadin/tools/WidgetsetCompiler.java | 94 - src/com/vaadin/ui/AbsoluteLayout.java | 632 --- src/com/vaadin/ui/AbstractComponent.java | 1382 ----- src/com/vaadin/ui/AbstractComponentContainer.java | 351 -- src/com/vaadin/ui/AbstractField.java | 1657 ------ src/com/vaadin/ui/AbstractJavaScriptComponent.java | 165 - src/com/vaadin/ui/AbstractLayout.java | 77 - src/com/vaadin/ui/AbstractMedia.java | 196 - src/com/vaadin/ui/AbstractOrderedLayout.java | 383 -- src/com/vaadin/ui/AbstractSelect.java | 2029 -------- src/com/vaadin/ui/AbstractSplitPanel.java | 521 -- src/com/vaadin/ui/AbstractTextField.java | 674 --- src/com/vaadin/ui/Accordion.java | 19 - src/com/vaadin/ui/Alignment.java | 158 - src/com/vaadin/ui/Audio.java | 55 - src/com/vaadin/ui/Button.java | 539 -- src/com/vaadin/ui/CheckBox.java | 141 - src/com/vaadin/ui/ComboBox.java | 116 - src/com/vaadin/ui/Component.java | 1047 ---- src/com/vaadin/ui/ComponentContainer.java | 222 - src/com/vaadin/ui/ConnectorTracker.java | 320 -- src/com/vaadin/ui/CssLayout.java | 308 -- src/com/vaadin/ui/CustomComponent.java | 189 - src/com/vaadin/ui/CustomField.java | 237 - src/com/vaadin/ui/CustomLayout.java | 329 -- src/com/vaadin/ui/DateField.java | 869 ---- src/com/vaadin/ui/DefaultFieldFactory.java | 146 - src/com/vaadin/ui/DragAndDropWrapper.java | 407 -- src/com/vaadin/ui/Embedded.java | 531 -- src/com/vaadin/ui/Field.java | 97 - src/com/vaadin/ui/Form.java | 1420 ----- src/com/vaadin/ui/FormFieldFactory.java | 41 - src/com/vaadin/ui/FormLayout.java | 31 - src/com/vaadin/ui/GridLayout.java | 1415 ----- src/com/vaadin/ui/HasComponents.java | 49 - src/com/vaadin/ui/HorizontalLayout.java | 24 - src/com/vaadin/ui/HorizontalSplitPanel.java | 34 - src/com/vaadin/ui/Html5File.java | 65 - src/com/vaadin/ui/InlineDateField.java | 46 - src/com/vaadin/ui/JavaScript.java | 157 - src/com/vaadin/ui/JavaScriptFunction.java | 41 - src/com/vaadin/ui/Label.java | 483 -- src/com/vaadin/ui/Layout.java | 229 - src/com/vaadin/ui/Link.java | 242 - src/com/vaadin/ui/ListSelect.java | 96 - src/com/vaadin/ui/LoginForm.java | 353 -- src/com/vaadin/ui/MenuBar.java | 890 ---- src/com/vaadin/ui/NativeButton.java | 21 - src/com/vaadin/ui/NativeSelect.java | 91 - src/com/vaadin/ui/Notification.java | 367 -- src/com/vaadin/ui/OptionGroup.java | 203 - src/com/vaadin/ui/Panel.java | 486 -- src/com/vaadin/ui/PasswordField.java | 67 - src/com/vaadin/ui/PopupDateField.java | 80 - src/com/vaadin/ui/PopupView.java | 453 -- src/com/vaadin/ui/ProgressIndicator.java | 257 - src/com/vaadin/ui/RichTextArea.java | 344 -- src/com/vaadin/ui/Root.java | 1227 ----- src/com/vaadin/ui/Select.java | 803 --- src/com/vaadin/ui/Slider.java | 372 -- src/com/vaadin/ui/TabSheet.java | 1328 ----- src/com/vaadin/ui/Table.java | 5449 -------------------- src/com/vaadin/ui/TableFieldFactory.java | 45 - src/com/vaadin/ui/TextArea.java | 121 - src/com/vaadin/ui/TextField.java | 92 - src/com/vaadin/ui/Tree.java | 1615 ------ src/com/vaadin/ui/TreeTable.java | 824 --- src/com/vaadin/ui/TwinColSelect.java | 180 - src/com/vaadin/ui/UniqueSerializable.java | 30 - src/com/vaadin/ui/Upload.java | 1055 ---- src/com/vaadin/ui/VerticalLayout.java | 25 - src/com/vaadin/ui/VerticalSplitPanel.java | 30 - src/com/vaadin/ui/Video.java | 81 - src/com/vaadin/ui/Window.java | 853 --- .../ui/doc-files/component_class_hierarchy.gif | Bin 11077 -> 0 bytes .../vaadin/ui/doc-files/component_interfaces.gif | Bin 2272 -> 0 bytes src/com/vaadin/ui/package.html | 76 - src/com/vaadin/ui/themes/BaseTheme.java | 59 - src/com/vaadin/ui/themes/ChameleonTheme.java | 365 -- src/com/vaadin/ui/themes/LiferayTheme.java | 31 - src/com/vaadin/ui/themes/Reindeer.java | 217 - src/com/vaadin/ui/themes/Runo.java | 183 - src/com/vaadin/util/SerializerHelper.java | 145 - src/org/jsoup/Connection.java | 481 -- src/org/jsoup/Jsoup.java | 229 - src/org/jsoup/examples/HtmlToPlainText.java | 109 - src/org/jsoup/examples/ListLinks.java | 56 - src/org/jsoup/examples/package-info.java | 4 - src/org/jsoup/helper/DataUtil.java | 135 - src/org/jsoup/helper/DescendableLinkedList.java | 82 - src/org/jsoup/helper/HttpConnection.java | 658 --- src/org/jsoup/helper/StringUtil.java | 140 - src/org/jsoup/helper/Validate.java | 112 - src/org/jsoup/nodes/Attribute.java | 131 - src/org/jsoup/nodes/Attributes.java | 249 - src/org/jsoup/nodes/Comment.java | 46 - src/org/jsoup/nodes/DataNode.java | 62 - src/org/jsoup/nodes/Document.java | 350 -- src/org/jsoup/nodes/DocumentType.java | 46 - src/org/jsoup/nodes/Element.java | 1119 ---- src/org/jsoup/nodes/Entities.java | 184 - src/org/jsoup/nodes/Node.java | 615 --- src/org/jsoup/nodes/TextNode.java | 175 - src/org/jsoup/nodes/XmlDeclaration.java | 48 - src/org/jsoup/nodes/entities-base.properties | 106 - src/org/jsoup/nodes/entities-full.properties | 2032 -------- src/org/jsoup/nodes/package-info.java | 4 - src/org/jsoup/package-info.java | 4 - src/org/jsoup/parser/CharacterReader.java | 230 - src/org/jsoup/parser/HtmlTreeBuilder.java | 672 --- src/org/jsoup/parser/HtmlTreeBuilderState.java | 1482 ------ src/org/jsoup/parser/ParseError.java | 40 - src/org/jsoup/parser/ParseErrorList.java | 34 - src/org/jsoup/parser/Parser.java | 157 - src/org/jsoup/parser/Tag.java | 262 - src/org/jsoup/parser/Token.java | 252 - src/org/jsoup/parser/TokenQueue.java | 393 -- src/org/jsoup/parser/Tokeniser.java | 230 - src/org/jsoup/parser/TokeniserState.java | 1778 ------- src/org/jsoup/parser/TreeBuilder.java | 60 - src/org/jsoup/parser/XmlTreeBuilder.java | 111 - src/org/jsoup/parser/package-info.java | 4 - src/org/jsoup/safety/Cleaner.java | 129 - src/org/jsoup/safety/Whitelist.java | 451 -- src/org/jsoup/safety/package-info.java | 4 - src/org/jsoup/select/Collector.java | 51 - src/org/jsoup/select/CombiningEvaluator.java | 94 - src/org/jsoup/select/Elements.java | 536 -- src/org/jsoup/select/Evaluator.java | 454 -- src/org/jsoup/select/NodeTraversor.java | 47 - src/org/jsoup/select/NodeVisitor.java | 30 - src/org/jsoup/select/QueryParser.java | 293 -- src/org/jsoup/select/Selector.java | 126 - src/org/jsoup/select/StructuralEvaluator.java | 132 - src/org/jsoup/select/package-info.java | 4 - 408 files changed, 107042 deletions(-) delete mode 100644 src/com/vaadin/Application.java delete mode 100644 src/com/vaadin/RootRequiresMoreInformationException.java delete mode 100644 src/com/vaadin/Vaadin.gwt.xml delete mode 100644 src/com/vaadin/Version.java delete mode 100644 src/com/vaadin/annotations/AutoGenerated.java delete mode 100644 src/com/vaadin/annotations/EagerInit.java delete mode 100644 src/com/vaadin/annotations/JavaScript.java delete mode 100644 src/com/vaadin/annotations/StyleSheet.java delete mode 100644 src/com/vaadin/annotations/Theme.java delete mode 100644 src/com/vaadin/annotations/Widgetset.java delete mode 100644 src/com/vaadin/annotations/package.html delete mode 100644 src/com/vaadin/data/Buffered.java delete mode 100644 src/com/vaadin/data/BufferedValidatable.java delete mode 100644 src/com/vaadin/data/Collapsible.java delete mode 100644 src/com/vaadin/data/Container.java delete mode 100644 src/com/vaadin/data/Item.java delete mode 100644 src/com/vaadin/data/Property.java delete mode 100644 src/com/vaadin/data/Validatable.java delete mode 100644 src/com/vaadin/data/Validator.java delete mode 100644 src/com/vaadin/data/fieldgroup/BeanFieldGroup.java delete mode 100644 src/com/vaadin/data/fieldgroup/Caption.java delete mode 100644 src/com/vaadin/data/fieldgroup/DefaultFieldGroupFieldFactory.java delete mode 100644 src/com/vaadin/data/fieldgroup/FieldGroup.java delete mode 100644 src/com/vaadin/data/fieldgroup/FieldGroupFieldFactory.java delete mode 100644 src/com/vaadin/data/fieldgroup/PropertyId.java delete mode 100644 src/com/vaadin/data/package.html delete mode 100644 src/com/vaadin/data/util/AbstractBeanContainer.java delete mode 100644 src/com/vaadin/data/util/AbstractContainer.java delete mode 100644 src/com/vaadin/data/util/AbstractInMemoryContainer.java delete mode 100644 src/com/vaadin/data/util/AbstractProperty.java delete mode 100644 src/com/vaadin/data/util/BeanContainer.java delete mode 100644 src/com/vaadin/data/util/BeanItem.java delete mode 100644 src/com/vaadin/data/util/BeanItemContainer.java delete mode 100644 src/com/vaadin/data/util/ContainerHierarchicalWrapper.java delete mode 100644 src/com/vaadin/data/util/ContainerOrderedWrapper.java delete mode 100644 src/com/vaadin/data/util/DefaultItemSorter.java delete mode 100644 src/com/vaadin/data/util/FilesystemContainer.java delete mode 100644 src/com/vaadin/data/util/HierarchicalContainer.java delete mode 100644 src/com/vaadin/data/util/HierarchicalContainerOrderedWrapper.java delete mode 100644 src/com/vaadin/data/util/IndexedContainer.java delete mode 100644 src/com/vaadin/data/util/ItemSorter.java delete mode 100644 src/com/vaadin/data/util/ListSet.java delete mode 100644 src/com/vaadin/data/util/MethodProperty.java delete mode 100644 src/com/vaadin/data/util/MethodPropertyDescriptor.java delete mode 100644 src/com/vaadin/data/util/NestedMethodProperty.java delete mode 100644 src/com/vaadin/data/util/NestedPropertyDescriptor.java delete mode 100644 src/com/vaadin/data/util/ObjectProperty.java delete mode 100644 src/com/vaadin/data/util/PropertyFormatter.java delete mode 100644 src/com/vaadin/data/util/PropertysetItem.java delete mode 100644 src/com/vaadin/data/util/QueryContainer.java delete mode 100644 src/com/vaadin/data/util/TextFileProperty.java delete mode 100644 src/com/vaadin/data/util/TransactionalPropertyWrapper.java delete mode 100644 src/com/vaadin/data/util/VaadinPropertyDescriptor.java delete mode 100644 src/com/vaadin/data/util/converter/Converter.java delete mode 100644 src/com/vaadin/data/util/converter/ConverterFactory.java delete mode 100644 src/com/vaadin/data/util/converter/ConverterUtil.java delete mode 100644 src/com/vaadin/data/util/converter/DateToLongConverter.java delete mode 100644 src/com/vaadin/data/util/converter/DefaultConverterFactory.java delete mode 100644 src/com/vaadin/data/util/converter/ReverseConverter.java delete mode 100644 src/com/vaadin/data/util/converter/StringToBooleanConverter.java delete mode 100644 src/com/vaadin/data/util/converter/StringToDateConverter.java delete mode 100644 src/com/vaadin/data/util/converter/StringToDoubleConverter.java delete mode 100644 src/com/vaadin/data/util/converter/StringToIntegerConverter.java delete mode 100644 src/com/vaadin/data/util/converter/StringToNumberConverter.java delete mode 100644 src/com/vaadin/data/util/filter/AbstractJunctionFilter.java delete mode 100644 src/com/vaadin/data/util/filter/And.java delete mode 100644 src/com/vaadin/data/util/filter/Between.java delete mode 100644 src/com/vaadin/data/util/filter/Compare.java delete mode 100644 src/com/vaadin/data/util/filter/IsNull.java delete mode 100644 src/com/vaadin/data/util/filter/Like.java delete mode 100644 src/com/vaadin/data/util/filter/Not.java delete mode 100644 src/com/vaadin/data/util/filter/Or.java delete mode 100644 src/com/vaadin/data/util/filter/SimpleStringFilter.java delete mode 100644 src/com/vaadin/data/util/filter/UnsupportedFilterException.java delete mode 100644 src/com/vaadin/data/util/package.html delete mode 100644 src/com/vaadin/data/util/sqlcontainer/CacheFlushNotifier.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/CacheMap.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/ColumnProperty.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/OptimisticLockException.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/ReadOnlyRowId.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/Reference.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/RowId.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/RowItem.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/SQLContainer.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/SQLUtil.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/TemporaryRowId.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/connection/J2EEConnectionPool.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/connection/JDBCConnectionPool.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/connection/SimpleJDBCConnectionPool.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/FreeformQuery.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/FreeformQueryDelegate.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/FreeformStatementDelegate.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/OrderBy.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/QueryDelegate.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/TableQuery.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/DefaultSQLGenerator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/MSSQLGenerator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/OracleGenerator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/SQLGenerator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/StatementHelper.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/AndTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/BetweenTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/CompareTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/FilterTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/IsNullTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/LikeTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/NotTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/OrTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/QueryBuilder.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/SimpleStringTranslator.java delete mode 100644 src/com/vaadin/data/util/sqlcontainer/query/generator/filter/StringDecorator.java delete mode 100644 src/com/vaadin/data/validator/AbstractStringValidator.java delete mode 100644 src/com/vaadin/data/validator/AbstractValidator.java delete mode 100644 src/com/vaadin/data/validator/BeanValidator.java delete mode 100644 src/com/vaadin/data/validator/CompositeValidator.java delete mode 100644 src/com/vaadin/data/validator/DateRangeValidator.java delete mode 100644 src/com/vaadin/data/validator/DoubleRangeValidator.java delete mode 100644 src/com/vaadin/data/validator/DoubleValidator.java delete mode 100644 src/com/vaadin/data/validator/EmailValidator.java delete mode 100644 src/com/vaadin/data/validator/IntegerRangeValidator.java delete mode 100644 src/com/vaadin/data/validator/IntegerValidator.java delete mode 100644 src/com/vaadin/data/validator/NullValidator.java delete mode 100644 src/com/vaadin/data/validator/RangeValidator.java delete mode 100644 src/com/vaadin/data/validator/RegexpValidator.java delete mode 100644 src/com/vaadin/data/validator/StringLengthValidator.java delete mode 100644 src/com/vaadin/data/validator/package.html delete mode 100644 src/com/vaadin/event/Action.java delete mode 100644 src/com/vaadin/event/ActionManager.java delete mode 100644 src/com/vaadin/event/ComponentEventListener.java delete mode 100644 src/com/vaadin/event/DataBoundTransferable.java delete mode 100644 src/com/vaadin/event/EventRouter.java delete mode 100644 src/com/vaadin/event/FieldEvents.java delete mode 100644 src/com/vaadin/event/ItemClickEvent.java delete mode 100644 src/com/vaadin/event/LayoutEvents.java delete mode 100644 src/com/vaadin/event/ListenerMethod.java delete mode 100644 src/com/vaadin/event/MethodEventSource.java delete mode 100644 src/com/vaadin/event/MouseEvents.java delete mode 100644 src/com/vaadin/event/ShortcutAction.java delete mode 100644 src/com/vaadin/event/ShortcutListener.java delete mode 100644 src/com/vaadin/event/Transferable.java delete mode 100644 src/com/vaadin/event/TransferableImpl.java delete mode 100644 src/com/vaadin/event/dd/DragAndDropEvent.java delete mode 100644 src/com/vaadin/event/dd/DragSource.java delete mode 100644 src/com/vaadin/event/dd/DropHandler.java delete mode 100644 src/com/vaadin/event/dd/DropTarget.java delete mode 100644 src/com/vaadin/event/dd/TargetDetails.java delete mode 100644 src/com/vaadin/event/dd/TargetDetailsImpl.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/AcceptAll.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/AcceptCriterion.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/And.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/ClientSideCriterion.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/ContainsDataFlavor.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/Not.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/Or.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/ServerSideCriterion.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/SourceIs.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/SourceIsTarget.java delete mode 100644 src/com/vaadin/event/dd/acceptcriteria/TargetDetailIs.java delete mode 100644 src/com/vaadin/event/package.html delete mode 100644 src/com/vaadin/external/json/JSONArray.java delete mode 100644 src/com/vaadin/external/json/JSONException.java delete mode 100644 src/com/vaadin/external/json/JSONObject.java delete mode 100644 src/com/vaadin/external/json/JSONString.java delete mode 100644 src/com/vaadin/external/json/JSONStringer.java delete mode 100644 src/com/vaadin/external/json/JSONTokener.java delete mode 100644 src/com/vaadin/external/json/JSONWriter.java delete mode 100644 src/com/vaadin/external/json/README delete mode 100644 src/com/vaadin/navigator/FragmentManager.java delete mode 100644 src/com/vaadin/navigator/Navigator.java delete mode 100644 src/com/vaadin/navigator/View.java delete mode 100644 src/com/vaadin/navigator/ViewChangeListener.java delete mode 100644 src/com/vaadin/navigator/ViewDisplay.java delete mode 100644 src/com/vaadin/navigator/ViewProvider.java delete mode 100644 src/com/vaadin/package.html delete mode 100644 src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml delete mode 100644 src/com/vaadin/service/ApplicationContext.java delete mode 100644 src/com/vaadin/service/FileTypeResolver.java delete mode 100644 src/com/vaadin/service/package.html delete mode 100644 src/com/vaadin/terminal/AbstractClientConnector.java delete mode 100644 src/com/vaadin/terminal/AbstractErrorMessage.java delete mode 100644 src/com/vaadin/terminal/AbstractExtension.java delete mode 100644 src/com/vaadin/terminal/AbstractJavaScriptExtension.java delete mode 100644 src/com/vaadin/terminal/ApplicationResource.java delete mode 100644 src/com/vaadin/terminal/ClassResource.java delete mode 100644 src/com/vaadin/terminal/CombinedRequest.java delete mode 100644 src/com/vaadin/terminal/CompositeErrorMessage.java delete mode 100644 src/com/vaadin/terminal/DeploymentConfiguration.java delete mode 100644 src/com/vaadin/terminal/DownloadStream.java delete mode 100644 src/com/vaadin/terminal/ErrorMessage.java delete mode 100644 src/com/vaadin/terminal/Extension.java delete mode 100644 src/com/vaadin/terminal/ExternalResource.java delete mode 100644 src/com/vaadin/terminal/FileResource.java delete mode 100644 src/com/vaadin/terminal/JavaScriptCallbackHelper.java delete mode 100644 src/com/vaadin/terminal/KeyMapper.java delete mode 100644 src/com/vaadin/terminal/LegacyPaint.java delete mode 100644 src/com/vaadin/terminal/Page.java delete mode 100644 src/com/vaadin/terminal/PaintException.java delete mode 100644 src/com/vaadin/terminal/PaintTarget.java delete mode 100644 src/com/vaadin/terminal/RequestHandler.java delete mode 100644 src/com/vaadin/terminal/Resource.java delete mode 100644 src/com/vaadin/terminal/Scrollable.java delete mode 100644 src/com/vaadin/terminal/Sizeable.java delete mode 100644 src/com/vaadin/terminal/StreamResource.java delete mode 100644 src/com/vaadin/terminal/StreamVariable.java delete mode 100644 src/com/vaadin/terminal/SystemError.java delete mode 100644 src/com/vaadin/terminal/Terminal.java delete mode 100644 src/com/vaadin/terminal/ThemeResource.java delete mode 100644 src/com/vaadin/terminal/UserError.java delete mode 100644 src/com/vaadin/terminal/Vaadin6Component.java delete mode 100644 src/com/vaadin/terminal/VariableOwner.java delete mode 100644 src/com/vaadin/terminal/WrappedRequest.java delete mode 100644 src/com/vaadin/terminal/WrappedResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractDeploymentConfiguration.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractStreamingEvent.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AbstractWebApplicationContext.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AddonContext.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AddonContextEvent.java delete mode 100644 src/com/vaadin/terminal/gwt/server/AddonContextListener.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ApplicationPortlet2.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ApplicationResourceHandler.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ApplicationServlet.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ApplicationStartedEvent.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ApplicationStartedListener.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapDom.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapFragmentResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapHandler.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapListener.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapPageResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/BootstrapResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ChangeVariablesErrorEvent.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ClientConnector.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ClientMethodInvocation.java delete mode 100644 src/com/vaadin/terminal/gwt/server/CommunicationManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java delete mode 100644 src/com/vaadin/terminal/gwt/server/Constants.java delete mode 100644 src/com/vaadin/terminal/gwt/server/DragAndDropService.java delete mode 100644 src/com/vaadin/terminal/gwt/server/GAEApplicationServlet.java delete mode 100644 src/com/vaadin/terminal/gwt/server/HttpServletRequestListener.java delete mode 100644 src/com/vaadin/terminal/gwt/server/JsonCodec.java delete mode 100644 src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java delete mode 100644 src/com/vaadin/terminal/gwt/server/LegacyChangeVariablesInvocation.java delete mode 100644 src/com/vaadin/terminal/gwt/server/NoInputStreamException.java delete mode 100644 src/com/vaadin/terminal/gwt/server/NoOutputStreamException.java delete mode 100644 src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java delete mode 100644 src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/PortletRequestListener.java delete mode 100644 src/com/vaadin/terminal/gwt/server/RequestTimer.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ResourceReference.java delete mode 100644 src/com/vaadin/terminal/gwt/server/RestrictedRenderResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/RpcManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/RpcTarget.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ServerRpcManager.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ServerRpcMethodInvocation.java delete mode 100644 src/com/vaadin/terminal/gwt/server/ServletPortletHelper.java delete mode 100644 src/com/vaadin/terminal/gwt/server/SessionExpiredException.java delete mode 100644 src/com/vaadin/terminal/gwt/server/StreamingEndEventImpl.java delete mode 100644 src/com/vaadin/terminal/gwt/server/StreamingErrorEventImpl.java delete mode 100644 src/com/vaadin/terminal/gwt/server/StreamingProgressEventImpl.java delete mode 100644 src/com/vaadin/terminal/gwt/server/StreamingStartEventImpl.java delete mode 100644 src/com/vaadin/terminal/gwt/server/SystemMessageException.java delete mode 100644 src/com/vaadin/terminal/gwt/server/UnsupportedBrowserHandler.java delete mode 100644 src/com/vaadin/terminal/gwt/server/UploadException.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WebApplicationContext.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WebBrowser.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WrappedHttpServletRequest.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WrappedHttpServletResponse.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WrappedPortletRequest.java delete mode 100644 src/com/vaadin/terminal/gwt/server/WrappedPortletResponse.java delete mode 100644 src/com/vaadin/terminal/package.html delete mode 100644 src/com/vaadin/tools/ReflectTools.java delete mode 100644 src/com/vaadin/tools/WidgetsetCompiler.java delete mode 100644 src/com/vaadin/ui/AbsoluteLayout.java delete mode 100644 src/com/vaadin/ui/AbstractComponent.java delete mode 100644 src/com/vaadin/ui/AbstractComponentContainer.java delete mode 100644 src/com/vaadin/ui/AbstractField.java delete mode 100644 src/com/vaadin/ui/AbstractJavaScriptComponent.java delete mode 100644 src/com/vaadin/ui/AbstractLayout.java delete mode 100644 src/com/vaadin/ui/AbstractMedia.java delete mode 100644 src/com/vaadin/ui/AbstractOrderedLayout.java delete mode 100644 src/com/vaadin/ui/AbstractSelect.java delete mode 100644 src/com/vaadin/ui/AbstractSplitPanel.java delete mode 100644 src/com/vaadin/ui/AbstractTextField.java delete mode 100644 src/com/vaadin/ui/Accordion.java delete mode 100644 src/com/vaadin/ui/Alignment.java delete mode 100644 src/com/vaadin/ui/Audio.java delete mode 100644 src/com/vaadin/ui/Button.java delete mode 100644 src/com/vaadin/ui/CheckBox.java delete mode 100644 src/com/vaadin/ui/ComboBox.java delete mode 100644 src/com/vaadin/ui/Component.java delete mode 100644 src/com/vaadin/ui/ComponentContainer.java delete mode 100644 src/com/vaadin/ui/ConnectorTracker.java delete mode 100644 src/com/vaadin/ui/CssLayout.java delete mode 100644 src/com/vaadin/ui/CustomComponent.java delete mode 100644 src/com/vaadin/ui/CustomField.java delete mode 100644 src/com/vaadin/ui/CustomLayout.java delete mode 100644 src/com/vaadin/ui/DateField.java delete mode 100644 src/com/vaadin/ui/DefaultFieldFactory.java delete mode 100644 src/com/vaadin/ui/DragAndDropWrapper.java delete mode 100644 src/com/vaadin/ui/Embedded.java delete mode 100644 src/com/vaadin/ui/Field.java delete mode 100644 src/com/vaadin/ui/Form.java delete mode 100644 src/com/vaadin/ui/FormFieldFactory.java delete mode 100644 src/com/vaadin/ui/FormLayout.java delete mode 100644 src/com/vaadin/ui/GridLayout.java delete mode 100644 src/com/vaadin/ui/HasComponents.java delete mode 100644 src/com/vaadin/ui/HorizontalLayout.java delete mode 100644 src/com/vaadin/ui/HorizontalSplitPanel.java delete mode 100644 src/com/vaadin/ui/Html5File.java delete mode 100644 src/com/vaadin/ui/InlineDateField.java delete mode 100644 src/com/vaadin/ui/JavaScript.java delete mode 100644 src/com/vaadin/ui/JavaScriptFunction.java delete mode 100644 src/com/vaadin/ui/Label.java delete mode 100644 src/com/vaadin/ui/Layout.java delete mode 100644 src/com/vaadin/ui/Link.java delete mode 100644 src/com/vaadin/ui/ListSelect.java delete mode 100644 src/com/vaadin/ui/LoginForm.java delete mode 100644 src/com/vaadin/ui/MenuBar.java delete mode 100644 src/com/vaadin/ui/NativeButton.java delete mode 100644 src/com/vaadin/ui/NativeSelect.java delete mode 100644 src/com/vaadin/ui/Notification.java delete mode 100644 src/com/vaadin/ui/OptionGroup.java delete mode 100644 src/com/vaadin/ui/Panel.java delete mode 100644 src/com/vaadin/ui/PasswordField.java delete mode 100644 src/com/vaadin/ui/PopupDateField.java delete mode 100644 src/com/vaadin/ui/PopupView.java delete mode 100644 src/com/vaadin/ui/ProgressIndicator.java delete mode 100644 src/com/vaadin/ui/RichTextArea.java delete mode 100644 src/com/vaadin/ui/Root.java delete mode 100644 src/com/vaadin/ui/Select.java delete mode 100644 src/com/vaadin/ui/Slider.java delete mode 100644 src/com/vaadin/ui/TabSheet.java delete mode 100644 src/com/vaadin/ui/Table.java delete mode 100644 src/com/vaadin/ui/TableFieldFactory.java delete mode 100644 src/com/vaadin/ui/TextArea.java delete mode 100644 src/com/vaadin/ui/TextField.java delete mode 100644 src/com/vaadin/ui/Tree.java delete mode 100644 src/com/vaadin/ui/TreeTable.java delete mode 100644 src/com/vaadin/ui/TwinColSelect.java delete mode 100644 src/com/vaadin/ui/UniqueSerializable.java delete mode 100644 src/com/vaadin/ui/Upload.java delete mode 100644 src/com/vaadin/ui/VerticalLayout.java delete mode 100644 src/com/vaadin/ui/VerticalSplitPanel.java delete mode 100644 src/com/vaadin/ui/Video.java delete mode 100644 src/com/vaadin/ui/Window.java delete mode 100644 src/com/vaadin/ui/doc-files/component_class_hierarchy.gif delete mode 100644 src/com/vaadin/ui/doc-files/component_interfaces.gif delete mode 100644 src/com/vaadin/ui/package.html delete mode 100644 src/com/vaadin/ui/themes/BaseTheme.java delete mode 100644 src/com/vaadin/ui/themes/ChameleonTheme.java delete mode 100644 src/com/vaadin/ui/themes/LiferayTheme.java delete mode 100644 src/com/vaadin/ui/themes/Reindeer.java delete mode 100644 src/com/vaadin/ui/themes/Runo.java delete mode 100644 src/com/vaadin/util/SerializerHelper.java delete mode 100644 src/org/jsoup/Connection.java delete mode 100644 src/org/jsoup/Jsoup.java delete mode 100644 src/org/jsoup/examples/HtmlToPlainText.java delete mode 100644 src/org/jsoup/examples/ListLinks.java delete mode 100644 src/org/jsoup/examples/package-info.java delete mode 100644 src/org/jsoup/helper/DataUtil.java delete mode 100644 src/org/jsoup/helper/DescendableLinkedList.java delete mode 100644 src/org/jsoup/helper/HttpConnection.java delete mode 100644 src/org/jsoup/helper/StringUtil.java delete mode 100644 src/org/jsoup/helper/Validate.java delete mode 100644 src/org/jsoup/nodes/Attribute.java delete mode 100644 src/org/jsoup/nodes/Attributes.java delete mode 100644 src/org/jsoup/nodes/Comment.java delete mode 100644 src/org/jsoup/nodes/DataNode.java delete mode 100644 src/org/jsoup/nodes/Document.java delete mode 100644 src/org/jsoup/nodes/DocumentType.java delete mode 100644 src/org/jsoup/nodes/Element.java delete mode 100644 src/org/jsoup/nodes/Entities.java delete mode 100644 src/org/jsoup/nodes/Node.java delete mode 100644 src/org/jsoup/nodes/TextNode.java delete mode 100644 src/org/jsoup/nodes/XmlDeclaration.java delete mode 100644 src/org/jsoup/nodes/entities-base.properties delete mode 100644 src/org/jsoup/nodes/entities-full.properties delete mode 100644 src/org/jsoup/nodes/package-info.java delete mode 100644 src/org/jsoup/package-info.java delete mode 100644 src/org/jsoup/parser/CharacterReader.java delete mode 100644 src/org/jsoup/parser/HtmlTreeBuilder.java delete mode 100644 src/org/jsoup/parser/HtmlTreeBuilderState.java delete mode 100644 src/org/jsoup/parser/ParseError.java delete mode 100644 src/org/jsoup/parser/ParseErrorList.java delete mode 100644 src/org/jsoup/parser/Parser.java delete mode 100644 src/org/jsoup/parser/Tag.java delete mode 100644 src/org/jsoup/parser/Token.java delete mode 100644 src/org/jsoup/parser/TokenQueue.java delete mode 100644 src/org/jsoup/parser/Tokeniser.java delete mode 100644 src/org/jsoup/parser/TokeniserState.java delete mode 100644 src/org/jsoup/parser/TreeBuilder.java delete mode 100644 src/org/jsoup/parser/XmlTreeBuilder.java delete mode 100644 src/org/jsoup/parser/package-info.java delete mode 100644 src/org/jsoup/safety/Cleaner.java delete mode 100644 src/org/jsoup/safety/Whitelist.java delete mode 100644 src/org/jsoup/safety/package-info.java delete mode 100644 src/org/jsoup/select/Collector.java delete mode 100644 src/org/jsoup/select/CombiningEvaluator.java delete mode 100644 src/org/jsoup/select/Elements.java delete mode 100644 src/org/jsoup/select/Evaluator.java delete mode 100644 src/org/jsoup/select/NodeTraversor.java delete mode 100644 src/org/jsoup/select/NodeVisitor.java delete mode 100644 src/org/jsoup/select/QueryParser.java delete mode 100644 src/org/jsoup/select/Selector.java delete mode 100644 src/org/jsoup/select/StructuralEvaluator.java delete mode 100644 src/org/jsoup/select/package-info.java (limited to 'src') 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; - -/** - *

- * 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. - *

- * - *

- * 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 Application - * needs to do is implement the init 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. - *

- * - *

- * See the class com.vaadin.demo.HelloWorld for a simple example of - * a fully working application. - *

- * - *

- * Window access. Application provides methods to - * list, add and remove the windows it contains. - *

- * - *

- * Execution control. 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. - *

- * - *

- * Theme selection. 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. - *

- * - * @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 legacyRootNames = new HashMap(); - - /** - * 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. - * - *

- * The main window is the window attached to the application URL ( - * {@link #getURL()}) and thus which is show by default to the user. - *

- *

- * Note that each application must have at least one main window. - *

- * - * @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. - *

- * Note that this theme can be overridden for a specific root with - * {@link Application#getThemeForRoot(Root)}. Setting theme to be - * null selects the default theme. For the available theme - * names, see the contents of the VAADIN/themes directory. - *

- * - * @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, - * null 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)} - *

- * {@inheritDoc} - */ - - @Override - public String getThemeForRoot(Root root) { - return theme; - } - - /** - *

- * Gets a root by name. Returns null if the application is - * not running or it does not contain a window corresponding to the - * name. - *

- * - * @param name - * the name of the requested window - * @return a root corresponding to the name, or null 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)}. - * - *

- * Note that removing window from the application does not close the - * browser window - the window is only removed from the server-side. - *

- * - * @param root - * the root to remove - */ - public void removeWindow(Root.LegacyWindow root) { - for (Entry entry : legacyRootNames - .entrySet()) { - if (entry.getValue() == root) { - legacyRootNames.remove(entry.getKey()); - } - } - } - - /** - * Gets the set of windows contained by the application. - * - *

- * Note that the returned set of windows can not be modified. - *

- * - * @return the unmodifiable collection of windows. - */ - public Collection 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 - * null 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 true if in production mode, else - * false - * - * @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 null 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 userChangeListeners = null; - - /** - * Application resource mapping: key <-> resource. - */ - private final Hashtable resourceKeyMap = new Hashtable(); - - private final Hashtable keyResourceMap = new Hashtable(); - - 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 requestHandlers = new LinkedList(); - - private int nextRootId = 0; - private Map roots = new HashMap(); - - private boolean productionMode = true; - - private final Map retainOnRefreshRoots = new HashMap(); - - private final EventRouter eventRouter = new EventRouter(); - - /** - * Keeps track of which roots have been inited. - *

- * TODO Investigate whether this might be derived from the different states - * in getRootForRrequest. - *

- */ - private Set initedRoots = new HashSet(); - - /** - * Gets the user of the application. - * - *

- * 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)}. - *

- * - * @return the User of the application. - */ - public Object getUser() { - return user; - } - - /** - *

- * 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. - *

- *

- * 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. - *

- *

- * 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()}. - *

- * - * @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. - * - *

- * 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()}). - *

- * - * @return the application's URL. - */ - public URL getURL() { - return applicationUrl; - } - - /** - * Ends the Application. - * - *

- * 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. - *

- * . - */ - public void close() { - applicationIsRunning = false; - } - - /** - * Starts the application on the given URL. - * - *

- * 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. - *

- * - *

- * 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}. - *

- * - * @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. - * - *

- * Application starts running when its - * {@link #start(URL, Properties, ApplicationContext)} method has been - * called and stops when the {@link #close()} is called. - *

- * - * @return true if the application is running, - * false if not. - */ - public boolean isRunning() { - return applicationIsRunning; - } - - /** - *

- * Main initializer of the application. The init method is - * called by the framework when the application is started, and it should - * perform whatever initialization operations the application needs. - *

- */ - public void init() { - // Default implementation does nothing - } - - /** - * Returns an enumeration of all the names in this application. - * - *

- * See {@link #start(URL, Properties, ApplicationContext)} how properties - * are defined. - *

- * - * @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 null 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; - } - - /** - *

- * An event that characterizes a change in the current selection. - *

- * 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 null - */ - public Object getPreviousUser() { - return prevUser; - } - - /** - * Gets the application where the user change occurred. - * - * @return the Application. - */ - public Application getApplication() { - return (Application) getSource(); - } - } - - /** - * The UserChangeListener interface for listening application - * user changes. - * - * @version - * @VERSION@ - * @since 3.0 - */ - public interface UserChangeListener extends EventListener, Serializable { - - /** - * The applicationUserChanged 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(); - } - 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 - * null, 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. - *

- * - * @return the URL. - */ - public String getLogoutURL() { - return logoutURL; - } - - /** - * Sets the URL user is redirected to on application close. If the URL is - * null, 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; - } - - /** - *

- * Invoked by the terminal on any exception that occurs in application and - * is thrown by the setVariable to the terminal. The default - * implementation sets the exceptions as ComponentErrors to the - * component that initiated the exception and prints stack trace to standard - * error stream. - *

- *

- * You can safely override this method in your application in order to - * direct the errors to some other destination (for example log). - *

- * - * @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. - *

- * 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. - *

- *

- * 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}. - *

- * - * @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. - *

- * 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). - *

- *

- * 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)}. - *

- *

- * 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. - *

- * Customize by overriding the static - * {@link Application#getSystemMessages()} and returning - * {@link CustomizedSystemMessages}. - *

- *

- * The defaults defined in this class are: - *

    - *
  • sessionExpiredURL = null
  • - *
  • sessionExpiredNotificationEnabled = true
  • - *
  • sessionExpiredCaption = ""
  • - *
  • sessionExpiredMessage = - * "Take note of any unsaved data, and click here to continue."
  • - *
  • communicationErrorURL = null
  • - *
  • communicationErrorNotificationEnabled = true
  • - *
  • communicationErrorCaption = "Communication problem"
  • - *
  • communicationErrorMessage = - * "Take note of any unsaved data, and click here to continue."
  • - *
  • internalErrorURL = null
  • - *
  • internalErrorNotificationEnabled = true
  • - *
  • internalErrorCaption = "Internal error"
  • - *
  • internalErrorMessage = "Please notify the administrator.
    - * Take note of any unsaved data, and click here to continue."
  • - *
  • outOfSyncURL = null
  • - *
  • outOfSyncNotificationEnabled = true
  • - *
  • outOfSyncCaption = "Out of sync"
  • - *
  • outOfSyncMessage = "Something has caused us to be out of sync - * with the server.
    - * Take note of any unsaved data, and click here to re-sync."
  • - *
  • cookiesDisabledURL = null
  • - *
  • cookiesDisabledNotificationEnabled = true
  • - *
  • cookiesDisabledCaption = "Cookies disabled"
  • - *
  • cookiesDisabledMessage = "This application requires cookies to - * function.
    - * Please enable cookies in your browser and click here to try again. - *
  • - *
- *

- * - */ - 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 click here 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 click here 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 click here to continue."; - - protected String internalErrorURL = null; - protected boolean internalErrorNotificationEnabled = true; - protected String internalErrorCaption = "Internal error"; - protected String internalErrorMessage = "Please notify the administrator.
Take note of any unsaved data, and click here 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.
Take note of any unsaved data, and click here 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.
Please enable cookies in your browser and click here 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 click here 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 click here 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 click here 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.
- * Take note of any unsaved data, and click here 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.
- * Take note of any unsaved data, and click here 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. - *

- * 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. - *

- *

- * The default behavior is to show a notification, and restart the - * application the the user clicks the message.
- * Instead of restarting the application, you can set a specific URL that - * the user is taken to.
- * 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. - *

- *

- * The situations are: - *

  • Session expired: the user session has expired, usually due to - * inactivity.
  • - *
  • Communication error: the client failed to contact the server, or the - * server returned and invalid response.
  • - *
  • Internal error: unhandled critical server error (e.g out of memory, - * database crash) - *
  • 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. - *

    - */ - - 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. - * - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - * @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 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 Root class that should be used for - * a request. The class must have an accessible no-args constructor. - *

    - * The default implementation uses the {@value #ROOT_PARAMETER} parameter - * from web.xml. - *

    - *

    - * 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. - *

    - * - * @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, null 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 null 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, null 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 null 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 null if the - * annotation is not present on the class - */ - private static T getAnnotationFor(Class type, - Class 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}). - *

    - * 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. - *

    - * - * @param request - * the wrapped request to get information from - * @param response - * the response to which data can be written - * @return returns true if a {@link RequestHandler} has - * produced a response and false 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( - 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. - *

    - * Handlers are called in reverse order of addition, so the most recently - * added handler will be called first. - *

    - * - * @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 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 - * null 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 currentApplication = new ThreadLocal(); - - 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 - * null - * - * @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. - *

    - * 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. - *

    - * - * @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. - *

    - * Please note that this method can also return a newly created - * Root 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. - *

    - * - * @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 null 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. - *

    - * 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. - *

    - * - * @param rootPreserved - * trueif 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 trueif 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 true of the initialization is pending, - * false 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 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. - *

    - * This is meant for framework internal use. - *

    - * - * @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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - *

    - * 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. - *

    - * 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. - *

    - * 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 @@ - - - - - - - -

    Contains annotations used in Vaadin. Note that some annotations -are also found in other packages e.g., {@link com.vaadin.ui.ClientWidget}.

    - - - 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; - -/** - *

    - * Defines the interface to commit and discard changes to an object, supporting - * read-through and write-through modes. - *

    - * - *

    - * Read-through mode means that the value read from the buffered object - * is constantly up to date with the data source. Write-through mode - * means that all changes to the object are immediately updated to the data - * source. - *

    - * - *

    - * Since these modes are independent, their combinations may result in some - * behaviour that may sound surprising. - *

    - * - *

    - * For example, if a Buffered 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. - *

    - * - * @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 commit 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 - * commit being called after the modification. - * - * @return true if the object is in write-through mode, - * false 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 commit 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. - *

    - * 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. - *

    - * - * @return true if the object is in read-through mode, - * false 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. - *

    - * 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. - *

    - *

    - * 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. - *

    - *

    - * 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. - *

    - * - * @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. - *

    - * This method only returns true if both read and write buffering is used. - *

    - * - * @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 true if the value in the object has been modified - * since the last data source update, false 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; - -/** - *

    - * This interface defines the combination of Validatable and - * Buffered interfaces. The combination of the interfaces defines - * if the invalid data is committed to datasource. - *

    - * - * @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 - * false. - */ - public boolean isInvalidCommitted(); - - /** - * Sets if the invalid data should be committed to datasource. The default - * is false. - */ - 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. - *

    - * 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. - *

    - * 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. - *

    - * - */ -public interface Collapsible extends Hierarchical, Ordered { - - /** - *

    - * Collapsing the {@link Item} indicated by itemId hides all - * children, and their respective children, from the {@link Container}. - *

    - * - *

    - * If called on a leaf {@link Item}, this method does nothing. - *

    - * - * @param itemId - * the identifier of the collapsed {@link Item} - * @param collapsed - * true if you want to collapse the children below - * this {@link Item}. false if you want to - * uncollapse the children. - */ - public void setCollapsed(Object itemId, boolean collapsed); - - /** - *

    - * Checks whether the {@link Item}, identified by itemId is - * collapsed or not. - *

    - * - *

    - * If an {@link Item} is "collapsed" its children are not included in - * methods used to list Items in this container. - *

    - * - * @param itemId - * The {@link Item}'s identifier that is to be checked. - * @return true iff the {@link Item} identified by - * itemId is currently collapsed, otherwise - * false. - */ - 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; - -/** - *

    - * 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: - *

    - * - *
      - *
    • All Items in the Container must have the same number of Properties. - *
    • All Items in the Container must have the same Property ID's (see - * {@link Item#getItemPropertyIds()}). - *
    • All Properties in the Items corresponding to the same Property ID must - * have the same data type. - *
    • All Items within a container are uniquely identified by their non-null - * IDs. - *
    - * - *

    - * 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 null values. - *

    - * - *

    - * Note that though uniquely identified, the Items in a Container are not - * necessarily {@link Container.Ordered ordered} or {@link Container.Indexed - * indexed}. - *

    - * - *

    - * Containers can derive Item ID's from the item properties or use other, - * container specific or user specified identifiers. - *

    - * - *

    - * 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). - *

    - * - *

    - * - *

    - * - *

    - * The Container interface is split to several subinterfaces so that a class can - * implement only the ones it needs. - *

    - * - * @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, null 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 null 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, null 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 null - */ - 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. - * - *

    - * The new Item is returned, and it is ready to have its Properties - * modified. Returns null if the operation fails or the - * Container already contains a Item with the given ID. - *

    - * - *

    - * This functionality is optional. - *

    - * - * @param itemId - * ID of the Item to be created - * @return Created new Item, or null 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. - * - *

    - * The new ID is returned, or null if the operation fails. - * After a successful call you can use the {@link #getItem(Object ItemId) - * getItem}method to fetch the Item. - *

    - * - *

    - * This functionality is optional. - *

    - * - * @return ID of the newly created Item, or null 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 ItemId from the Container. - * - *

    - * Containers that support filtering should also allow removing an item that - * is currently filtered out. - *

    - * - *

    - * This functionality is optional. - *

    - * - * @param itemId - * ID of the Item to remove - * @return true if the operation succeeded, false - * 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 true if the operation succeeded, false - * 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 true if the operation succeeded, false - * 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. - * - *

    - * Note that Property ID and type information is preserved. This - * functionality is optional. - *

    - * - * @return true if the operation succeeded, false - * 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. - * - *

    - * If the container is filtered or sorted, the traversal applies to the - * filtered and sorted view. - *

    - *

    - * The addItemAfter() 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. - *

    - */ - public interface Ordered extends Container { - - /** - * Gets the ID of the Item following the Item that corresponds to - * itemId. If the given Item is the last or not found in - * the Container, null is returned. - * - * @param itemId - * ID of a visible Item in the Container - * @return ID of the next visible Item or null - */ - public Object nextItemId(Object itemId); - - /** - * Gets the ID of the Item preceding the Item that corresponds to - * itemId. If the given Item is the first or not found in - * the Container, null is returned. - * - * @param itemId - * ID of a visible Item in the Container - * @return ID of the previous visible Item or null - */ - 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 true if the Item is first visible item in the - * Container, false 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 true if the Item is last visible item in the - * Container, false if not - */ - public boolean isLastId(Object itemId); - - /** - * Adds a new item after the given item. - *

    - * Adding an item after null item adds the item as first item of the - * ordered container. - *

    - * - * @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. - *

    - * Adding an item after null item adds the item as first item of the - * ordered container. - *

    - * - * @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. - *

    - * 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 addItem*() methods may add - * items that will be filtered out after addition or moved to another - * position based on sorting. - *

    - *

    - * 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. - *

    - *

    - * Depending on the container type, sorting a container may permanently - * change the internal order of items in the container. - *

    - */ - 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 true to - * sort in ascending order, false 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. - *

    - * If the container is filtered or sorted, all indices refer to the filtered - * and sorted view. However, the addItemAt() methods may add - * items that will be filtered out after addition or moved to another - * position based on sorting. - *

    - */ - public interface Indexed extends Ordered { - - /** - * Gets the index of the Item corresponding to the itemId. The following - * is true 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). - *

    - * The indices of the item currently in the given position and all the - * following items are incremented. - *

    - *

    - * 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. - *

    - * - * @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). - *

    - * The indexes of the item currently in the given position and all the - * following items are incremented. - *

    - *

    - * 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. - *

    - * - * @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; - - } - - /** - *

    - * Interface for Container 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: - *

    - * - *
      - *
    • The Item structure may have more than one root elements - *
    • The Items in the hierarchy can be declared explicitly to be able or - * unable to have children. - *
    - */ - 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 null 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 root 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(); - - /** - *

    - * Sets the parent of an Item. The new parent item must exist and be - * able to have children. ( - * {@link #areChildrenAllowed(Object)} == true ). It is - * also possible to detach a node from the hierarchy (and thus make it - * root) by setting the parent null. - *

    - * - *

    - * This operation is optional. - *

    - * - * @param itemId - * ID of the item to be set as the child of the Item - * identified with newParentId - * @param newParentId - * ID of the Item that's to be the new parent of the Item - * identified with itemId - * @return true if the operation succeeded, - * false 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 true if the specified Item exists in the - * Container and it can have children, false if - * it's not found from the container or it can't have children. - */ - public boolean areChildrenAllowed(Object itemId); - - /** - *

    - * Sets the given Item's capability to have children. If the Item - * identified with itemId already has children and - * {@link #areChildrenAllowed(Object)} is false this method - * fails and false 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)}. - *

    - * - *

    - * This operation is optional. If it is not implemented, the method - * always returns false. - *

    - * - * @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 true if the operation succeeded, - * false if not - */ - public boolean setChildrenAllowed(Object itemId, - boolean areChildrenAllowed) - throws UnsupportedOperationException; - - /** - * Tests if the Item specified with itemId 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 null for root Items. - * - * @param itemId - * ID of the Item whose root status is to be tested - * @return true if the specified Item is a root, - * false if not - */ - public boolean isRoot(Object itemId); - - /** - *

    - * Tests if the Item specified with itemId has child Items - * or if it is a leaf. The {@link #getChildren(Object itemId)} method - * always returns null for leaf Items. - *

    - * - *

    - * Note that being a leaf does not imply whether or not an Item is - * allowed to have children. - *

    - * . - * - * @param itemId - * ID of the Item to be tested - * @return true if the specified Item has children, - * false if not (is a leaf) - */ - public boolean hasChildren(Object itemId); - - /** - *

    - * Removes the Item identified by ItemId from the - * Container. - *

    - * - *

    - * Note that this does not remove any children the item might have. - *

    - * - * @param itemId - * ID of the Item to remove - * @return true if the operation succeeded, - * false 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. - *

    - * 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. - *

    - *

    - * 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. - *

    - *

    - * How filtering is performed when a {@link Hierarchical} container - * implements {@link SimpleFilterable} is implementation specific and should - * be documented in the implementing class. - *

    - *

    - * 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. - *

    - *

    - * The functionality of SimpleFilterable can be implemented using the - * {@link Filterable} API and {@link SimpleStringFilter}. - *

    - * - * @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. - *

    - * 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. - *

    - *

    - * 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 addItem*() methods may add items that - * will be filtered out after addition or moved to another position based on - * sorting. - *

    - *

    - * How filtering is performed when a {@link Hierarchical} container - * implements {@link Filterable} is implementation specific and should be - * documented in the implementing class. - *

    - *

    - * 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. - *

    - * - *

    - * This API replaces the old Filterable interface, renamed to - * {@link SimpleFilterable} in Vaadin 6.6. - *

    - * - * @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(); - - } - - /** - *

    - * 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. - *

    - *

    - * Note that not implementing the Container.Editor interface - * does not restrict the class from editing the Container contents - * internally. - *

    - */ - public interface Editor extends Container.Viewer, Serializable { - - } - - /* Contents change event */ - - /** - * An Event 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 ItemSetChangeEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate a ItemSetChangeEvent 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. - * - *

    - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - */ - 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 Event 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 PropertySetChangeEvent - * 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); - } - - /** - *

    - * The interface for adding and removing PropertySetChangeEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate a PropertySetChangeEvent when the set - * of property IDs supported by the container is modified. - *

    - * - *

    - * 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. - *

    - * - *

    - * Note that the general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - */ - 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; - -/** - *

    - * 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. - *

    - * - * @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, null is - * returned. - * - * @param id - * identifier of the Property to get - * @return the Property with the given ID or null - */ - 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. - * - *

    - * This functionality is optional. - *

    - * - * @param id - * ID of the new Property - * @param property - * the Property to be added and associated with the id - * @return true if the operation succeeded, false - * 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. - * - *

    - * This functionality is optional. - *

    - * - * @param id - * ID of the Property to be removed - * @return true if the operation succeeded - * @throws UnsupportedOperationException - * if the operation is not supported. false 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 Editor 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. - *

    - * Note : Not implementing the Item.Editor interface does not - * restrict the class from editing the contents of an internally. - *

    - */ - public interface Editor extends Item.Viewer, Serializable { - - } - - /* Property set change event */ - - /** - * An Event object specifying the Item whose contents has been - * changed through the Property interface. - *

    - * Note: The values stored in the Properties may change without triggering - * this event. - *

    - */ - 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 PropertySetChangeEvent - * 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 PropertySetChangeEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate a PropertySetChangeEvent when its - * Property set is modified. - *

    - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - */ - 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; - -/** - *

    - * The Property 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. - *

    - * - *

    - * The Property also defines the events - * ReadOnlyStatusChangeEvent and ValueChangeEvent, and - * the associated listener and notifier interfaces. - *

    - * - *

    - * The Property.Viewer 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 Property interface. - *

    - * - *

    - * The Property.editor interface should be implemented if the value - * needs to be changed through the implementing class. - *

    - * - * @param T - * type of values of the property - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Property 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. - *

    - * Implementing this functionality is optional. If the functionality is - * missing, one should declare the Property to be in read-only mode and - * throw Property.ReadOnlyException in this function. - *

    - * - * 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 getValue and - * setValue must be compatible with this type: one must be able - * to safely cast the value returned from getValue to the given - * type and pass any variable assignable to this type as an argument to - * setValue. - * - * @return type of the Property - */ - public Class getType(); - - /** - * Tests if the Property is in read-only mode. In read-only mode calls to - * the method setValue will throw - * ReadOnlyException and will not modify the value of the - * Property. - * - * @return true if the Property is in read-only mode, - * false 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 - * isReadOnly 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 - * The type of the property - * @author Vaadin Ltd - * @version @version@ - * @since 7.0 - */ - public interface Transactional extends Property { - - /** - * Starts a transaction. - * - *

    - * 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. - *

    - *

    - * {@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. - *

    - */ - public void startTransaction(); - - /** - * Commits and ends the transaction that is in progress. - *

    - * If the value is changed as a result of this operation, a - * {@link ValueChangeEvent} is emitted if such are supported. - *

    - * This method has no effect if there is no transaction is in progress. - *

    - * This method must never throw an exception. - */ - public void commit(); - - /** - * Aborts and rolls back the transaction that is in progress. - *

    - * The value is reset to the value before the transaction started. No - * {@link ValueChangeEvent} is emitted as a result of this. - *

    - * This method has no effect if there is no transaction is in progress. - *

    - * This method must never throw an exception. - */ - public void rollback(); - } - - /** - * Exception 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 ReadOnlyException without a detail - * message. - */ - public ReadOnlyException() { - } - - /** - * Constructs a new ReadOnlyException 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. - *

    - * 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 - * ReadOnlyException being thrown. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ - public interface Editor extends Property.Viewer, Serializable { - - } - - /* Value change event */ - - /** - * An Event 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 listener interface for receiving - * ValueChangeEvent 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 ValueChangeEvent - * listeners. If a Property wishes to allow other objects to receive - * ValueChangeEvent generated by it, it must implement this - * interface. - *

    - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @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 Event 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 - * ReadOnlyStatusChangeEvent 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 - * ReadOnlyStatusChangeEvent listeners. If a Property wishes to - * allow other objects to receive ReadOnlyStatusChangeEvent - * generated by it, it must implement this interface. - *

    - * Note : The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @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; - -/** - *

    - * 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. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - * @see com.vaadin.data.Validator - */ -public interface Validatable extends Serializable { - - /** - *

    - * 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. - *

    - * - * @param validator - * the new validator - */ - void addValidator(Validator validator); - - /** - *

    - * Removes a previously registered validator from the object. The specified - * validator is removed from the object and its validate method - * is no longer called in {@link #isValid()}. - *

    - * - * @param validator - * the validator to remove - */ - void removeValidator(Validator validator); - - /** - *

    - * Lists all validators currently registered for the object. If no - * validators are registered, returns null. - *

    - * - * @return collection of validators or null - */ - public Collection getValidators(); - - /** - *

    - * 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 - * false. - *

    - * - * @return true if the registered validators concur that the - * value is valid, false otherwise - */ - public boolean isValid(); - - /** - *

    - * 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 - * Validator.InvalidValueException - *

    - * - * @throws Validator.InvalidValueException - * if the value is not valid - */ - public void validate() throws Validator.InvalidValueException; - - /** - *

    - * Checks the validabtable object accept invalid values.The default value is - * true. - *

    - * - */ - public boolean isInvalidAllowed(); - - /** - *

    - * Should the validabtable object accept invalid values. Supporting this - * configuration possibility is optional. By default invalid values are - * allowed. - *

    - * - * @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. - *

    - * Implementors of this class can be added to any - * {@link com.vaadin.data.Validatable Validatable} implementor to verify its - * value. - *

    - *

    - * {@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. - *

    - *

    - * Validators must not have any side effects. - *

    - *

    - * 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. - *

    - * - * @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. - * - *

    - * 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. - *

    - * - * @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 extends FieldGroup { - - private Class beanType; - - private static Boolean beanValidationImplementationAvailable = null; - - public BeanFieldGroup(Class 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 getItemDataSource() { - return (BeanItem) 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 createField(Class type, Class 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 createEnumField(Class type, - Class fieldType) { - if (AbstractSelect.class.isAssignableFrom(fieldType)) { - AbstractSelect s = createCompatibleSelect((Class) fieldType); - populateWithEnumData(s, (Class) type); - return (T) s; - } - - return null; - } - - protected AbstractSelect createCompatibleSelect( - Class 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 createBooleanField(Class 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) fieldType); - } - - return null; - } - - protected T createAbstractTextField( - Class fieldType) { - if (fieldType == AbstractTextField.class) { - fieldType = (Class) 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 - * 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 createDefaultField(Class type, - Class 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 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. - *

    - * 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. - *

    - *

    - * {@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. - *

    - * - * @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> propertyIdToField = new HashMap>(); - private LinkedHashMap, Object> fieldToPropertyId = new LinkedHashMap, Object>(); - private List commitHandlers = new ArrayList(); - - /** - * 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. - *

    - * - * @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. - *

    - * 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. - *

    - *

    - * The default is to use buffered mode. - *

    - * - * @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. - *

    - * 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. - *

    - * 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. - *

    - * The fields are not returned in any specific order. - *

    - * - * @return A collection with all bound Fields - */ - public Collection> 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)}. - *

    - * This method also adds validators when applicable. - *

    - * - * @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 Property.Transactional wrapInTransactionalProperty( - Property itemProperty) { - return new TransactionalPropertyWrapper(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. - *

    - * 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. - *

    - * 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. - *

    - * 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. - *

    - *

    - * No guarantee is given for the order of the property ids - *

    - * - * @return A collection of bound property ids - */ - public Collection 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. - *

    - * Will always return an empty collection before an item has been set using - * {@link #setItemDataSource(Item)}. - *

    - *

    - * No guarantee is given for the order of the property ids - *

    - * - * @return A collection of property ids that have not been bound to fields - */ - public Collection getUnboundPropertyIds() { - if (getItemDataSource() == null) { - return new ArrayList(); - } - List unboundPropertyIds = new ArrayList(); - unboundPropertyIds.addAll(getItemDataSource().getItemPropertyIds()); - unboundPropertyIds.removeAll(propertyIdToField.keySet()); - return unboundPropertyIds; - } - - /** - * Commits all changes done to the bound fields. - *

    - * 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. - *

    - * 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. - *

    - * 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}. - *

    - * Use {@link #addCommitHandler(CommitHandler)} and - * {@link #removeCommitHandler(CommitHandler)} to register or unregister a - * commit handler. - * - * @return A collection of commit handlers - */ - protected Collection 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. - *

    - * 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.. - *

    - * 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. - *

    - * 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. - *

    - * 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. - *

    - *

    - * For example: - * - *

    -     * 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);
    -     * 
    - * - *

    - * 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. - *

    - * 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. - *

    - *

    - * For example: - * - *

    -     * 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);
    -     * 
    - * - *

    - *

    - * 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. - *

    - * - * @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. - *

    - * 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. - *

    - * - * @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 fieldType = (Class) 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 buildAndBind(String caption, Object propertyId, - Class 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. - *

    - * 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. - *

    - * - * @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 build(String caption, Class dataType, - Class 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 createField(Class dataType, Class 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 @@ - - - - - - - -

    Contains interfaces for the data layer, mainly for binding typed -data and data collections to components, and for validating data.

    - -

    Data binding

    - -

    The package contains a three-tiered structure for typed data -objects and collections of them:

    - -
      -
    • A {@link com.vaadin.data.Property Property} represents a - single, typed data value. - -
    • An {@link com.vaadin.data.Item Item} embodies a set of Properties. - A locally unique (inside the {@link com.vaadin.data.Item Item}) - Property identifier corresponds to each Property inside the Item.
    • -
    • 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.
    • -
    - -

    For more information on the data model, see the Data model -chapter in Book of Vaadin.

    - -

    Buffering

    - -

    A {@link com.vaadin.data.Buffered Buffered} implementor is able -to track and buffer changes and commit or discard them later.

    - -

    Validation

    - -

    {@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.

    - - - - 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. - * - *

    - * 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. - *

    - * - *

    - * 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)}. - *

    - * - * @param - * The type of the item identifier - * @param - * The type of the Bean - * - * @since 6.5 - */ -public abstract class AbstractBeanContainer extends - AbstractInMemoryContainer> 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 - * @param - * - * @since 6.5 - */ - public static interface BeanIdResolver 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 { - - 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 pd = model.get(propertyId); - if (null == pd) { - throw new IllegalStateException("Property " + propertyId - + " not found"); - } - try { - Property property = (Property) 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 beanIdResolver = null; - - /** - * Maps all item ids in the container (including filtered) to their - * corresponding BeanItem. - */ - private final Map> itemIdToItem = new HashMap>(); - - /** - * The type of the beans in the container. - */ - private final Class 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> 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 type) { - if (type == null) { - throw new IllegalArgumentException( - "The bean type passed to AbstractBeanContainer must not be null"); - } - this.type = type; - model = BeanItem.getPropertyDescriptors((Class) 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 createBeanItem(BEANTYPE bean) { - return bean == null ? null : new BeanItem(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 getBeanType() { - return type; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getContainerPropertyIds() - */ - @Override - public Collection 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 getItem(Object itemId) { - // TODO return only if visible? - return getUnfilteredItem(itemId); - } - - @Override - protected BeanItem getUnfilteredItem(Object itemId) { - return itemIdToItem.get(itemId); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Container#getItemIds() - */ - @Override - @SuppressWarnings("unchecked") - public List getItemIds() { - return (List) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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> pds = BeanItem - .getPropertyDescriptors((Class) propertyType); - for (String subPropertyId : pds.keySet()) { - String qualifiedPropertyId = propertyId + "." + subPropertyId; - NestedPropertyDescriptor pd = new NestedPropertyDescriptor( - qualifiedPropertyId, (Class) type); - model.put(qualifiedPropertyId, pd); - model.remove(propertyId); - for (BeanItem 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 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 propertySetChangeListeners = null; - - /** - * List of all container Item set change event listeners. - */ - private Collection itemSetChangeListeners = null; - - /** - * An event 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 event 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()); - } - 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()); - } - 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 propertySetChangeListeners) { - this.propertySetChangeListeners = propertySetChangeListeners; - } - - /** - * Returns the property set change listener collection. For internal use - * only. - */ - protected Collection getPropertySetChangeListeners() { - return propertySetChangeListeners; - } - - /** - * Sets the item set change listener collection. For internal use only. - * - * @param itemSetChangeListeners - */ - protected void setItemSetChangeListeners( - Collection itemSetChangeListeners) { - this.itemSetChangeListeners = itemSetChangeListeners; - } - - /** - * Returns the item set change listener collection. For internal use only. - */ - protected Collection 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: - *
      - *
    • {@link Container.Ordered} - *
    • {@link Container.Indexed} - *
    • {@link Filterable} and {@link SimpleFilterable} (internal implementation, - * does not implement the interface directly) - *
    • {@link Sortable} (internal implementation, does not implement the - * interface directly) - *
    - * - * To implement {@link Sortable}, subclasses need to implement - * {@link #getSortablePropertyIds()} and call the superclass method - * {@link #sortContainer(Object[], boolean[])} in the method - * sort(Object[], boolean[]). - * - * 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 - * the class of item identifiers in the container, use Object if can - * be any class - * @param - * the class of property identifiers for the items in the container, - * use Object if can be any class - * @param - * the (base) class of the Item instances in the container, use - * {@link Item} if unknown - * - * @since 6.6 - */ -public abstract class AbstractInMemoryContainer - 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 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 filteredItemIds; - - /** - * Filters that are applied to the container to limit the items visible in - * it - */ - private Set filters = new HashSet(); - - /** - * 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()); - } - - // 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 cannot - // be cast to Collection - - // public abstract Collection getContainerPropertyIds(); - // public abstract Collection 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 originalFilteredItemIds = getFilteredItemIds(); - boolean wasUnfiltered = false; - if (originalFilteredItemIds == null) { - originalFilteredItemIds = Collections.emptyList(); - wasUnfiltered = true; - } - setFilteredItemIds(new ListSet()); - - // Filter - boolean equal = true; - Iterator origIt = originalFilteredItemIds.iterator(); - for (final Iterator 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 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 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 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 removed filters - */ - protected Collection removeFilters(Object propertyId) { - if (getFilters().isEmpty() || propertyId == null) { - return Collections.emptyList(); - } - List removedFilters = new LinkedList(); - for (Iterator 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 itemSorter has been prepared for the sort - * operation. Typically this method calls - * Collections.sort(aCollection, getItemSorter()) 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 sortables = new LinkedList(); - 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. - * - *

    - * Caller should initiate filtering after calling this method. - *

    - * - * 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 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 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 - */ - protected List 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 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 - */ - protected List 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 - * remove*Filter* (which also re-filter the container) instead - * when possible. - * - * @param filters - */ - protected void setFilters(Set filters) { - this.filters = filters; - } - - /** - * Returns the internal collection of filters. The returned collection - * should not be modified by callers outside this class. - * - * @return Set - */ - protected Set 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 implements Property, - Property.ValueChangeNotifier, Property.ReadOnlyStatusChangeNotifier { - - /** - * List of listeners who are interested in the read-only status changes of - * the Property - */ - private LinkedList readOnlyStatusChangeListeners = null; - - /** - * List of listeners who are interested in the value changes of the Property - */ - private LinkedList 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 Property 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 Event 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(); - } - 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 Event 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(); - } - 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. - * - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - *

    - * To use explicit item IDs, use the methods {@link #addItem(Object, Object)}, - * {@link #addItemAfter(Object, Object, Object)} and - * {@link #addItemAt(int, Object, Object)}. - *

    - * - *

    - * 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). - *

    - * - *

    - * 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. - *

    - * - *

    - * It is not possible to add additional properties to the container and nested - * bean properties are not supported. - *

    - * - * @param - * The type of the item identifier - * @param - * The type of the Bean - * - * @see AbstractBeanContainer - * @see BeanItemContainer - * - * @since 6.5 - */ -public class BeanContainer extends - AbstractBeanContainer { - - public BeanContainer(Class type) { - super(type); - } - - /** - * Adds the bean to the Container. - * - * @see com.vaadin.data.Container#addItem(Object) - */ - @Override - public BeanItem 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 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 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 beanIdResolver) { - super.setBeanIdResolver(beanIdResolver); - } - - @Override - // overridden to make public - public BeanItem addBean(BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBean(bean); - } - - @Override - // overridden to make public - public BeanItem addBeanAfter(IDTYPE previousItemId, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAfter(previousItemId, bean); - } - - @Override - // overridden to make public - public BeanItem addBeanAt(int index, BEANTYPE bean) - throws IllegalStateException, IllegalArgumentException { - return super.addBeanAt(index, bean); - } - - @Override - // overridden to make public - public void addAll(Collection 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 extends PropertysetItem { - - /** - * The bean which this Item is based on. - */ - private final BT bean; - - /** - *

    - * Creates a new instance of BeanItem and adds all properties - * of a Java Bean to it. The properties are identified by their respective - * bean names. - *

    - * - *

    - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone is and - * are methods are not supported. - *

    - * - * @param bean - * the Java Bean to copy properties from. - * - */ - public BeanItem(BT bean) { - this(bean, getPropertyDescriptors((Class) bean.getClass())); - } - - /** - *

    - * Creates a new instance of BeanItem using a pre-computed set - * of properties. The properties are identified by their respective bean - * names. - *

    - * - * @param bean - * the Java Bean to copy properties from. - * @param propertyDescriptors - * pre-computed property descriptors - */ - BeanItem(BT bean, - Map> propertyDescriptors) { - - this.bean = bean; - - for (VaadinPropertyDescriptor pd : propertyDescriptors.values()) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - /** - *

    - * Creates a new instance of BeanItem and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - *

    - * - *

    - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone is and - * are methods are not supported. - *

    - * - * @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> pds = getPropertyDescriptors((Class) bean - .getClass()); - - // Add all the bean properties as MethodProperties to this Item - for (Object id : propertyIds) { - VaadinPropertyDescriptor pd = pds.get(id); - if (pd != null) { - addItemProperty(pd.getName(), pd.createProperty(bean)); - } - } - - } - - /** - *

    - * Creates a new instance of BeanItem and adds all listed - * properties of a Java Bean to it - in specified order. The properties are - * identified by their respective bean names. - *

    - * - *

    - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone is and - * are methods are not supported. - *

    - * - * @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)); - } - - /** - *

    - * Perform introspection on a Java Bean class to find its properties. - *

    - * - *

    - * Note : This version only supports introspectable bean properties and - * their getter and setter methods. Stand-alone is and - * are methods are not supported. - *

    - * - * @param beanClass - * the Java Bean class to get properties for. - * @return an ordered map from property names to property descriptors - */ - static LinkedHashMap> getPropertyDescriptors( - final Class beanClass) { - final LinkedHashMap> pdMap = new LinkedHashMap>(); - - // Try to introspect, if it fails, we just have an empty Item - try { - List 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 vaadinPropertyDescriptor = new MethodPropertyDescriptor( - 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 getBeanPropertyDescriptor( - final Class beanClass) throws IntrospectionException { - // Oracle bug 4275879: Introspector does not consider superinterfaces of - // an interface - if (beanClass.isInterface()) { - List propertyDescriptors = new ArrayList(); - - 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 subPropertySet = new HashSet( - Arrays.asList(subPropertyIds)); - - if (0 == subPropertyIds.length) { - // Enumerate all sub-properties - Class propertyType = getItemProperty(propertyId).getType(); - Map 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( - 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. - * - *

    - * 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. - *

    - * - *

    - * 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()}. - *

    - * - *

    - * 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. - *

    - * - *

    - * It is not possible to add additional properties to the container and nested - * bean properties are not supported. - *

    - * - * @param - * The type of the Bean - * - * @since 5.4 - */ -@SuppressWarnings("serial") -public class BeanItemContainer extends - AbstractBeanContainer { - - /** - * 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 - * - * @since 6.5 - */ - private static class IdentityBeanIdResolver implements - BeanIdResolver { - - @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 type) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver()); - } - - /** - * 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 collection) - throws IllegalArgumentException { - // must assume the class is BT - // the class information is erased by the compiler - this((Class) getBeanClassForCollection(collection), - collection); - } - - /** - * Internal helper method to support the deprecated {@link Collection} - * container. - * - * @param - * @param collection - * @return - * @throws IllegalArgumentException - */ - @SuppressWarnings("unchecked") - @Deprecated - private static Class getBeanClassForCollection( - Collection 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) 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 type, - Collection collection) - throws IllegalArgumentException { - super(type); - super.setBeanIdResolver(new IdentityBeanIdResolver()); - - 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 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 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 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 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 addBean(BEANTYPE bean) { - return addItem(bean); - } - - /** - * Unsupported in BeanItemContainer. - */ - @Override - protected void setBeanIdResolver( - AbstractBeanContainer.BeanIdResolver 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; - -/** - *

    - * A wrapper class for adding external hierarchy to containers not implementing - * the {@link com.vaadin.data.Container.Hierarchical} interface. - *

    - * - *

    - * 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. - *

    - * - * @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 noChildrenAllowed = null; - - /** Mapping from Item ID to parent Item ID */ - private Hashtable parent = null; - - /** Mapping from Item ID to a list of child IDs */ - private Hashtable> children = null; - - /** List that contains all root elements of the container. */ - private LinkedHashSet 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, 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 - * Container.Hierarchical 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(); - parent = new Hashtable(); - children = new Hashtable>(); - roots = new LinkedHashSet(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(); - parent = new Hashtable(); - children = new Hashtable>(); - roots = new LinkedHashSet(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 basedOnOrderFromWrappedContainer = new ListedItemsFirstComparator( - itemIds); - - // Calculate the set of all items in the hierarchy - final HashSet s = new HashSet(); - s.addAll(parent.keySet()); - s.addAll(children.keySet()); - s.addAll(roots); - - // Remove unnecessary items - for (final Iterator 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(); - for (int i = 0; i < array.length; i++) { - roots.add(array[i]); - } - for (Object object : children.keySet()) { - LinkedList object2 = children.get(object); - Collections.sort(object2, basedOnOrderFromWrappedContainer); - } - - } - } - } - - /** - * Removes the specified Item from the wrapper's internal hierarchy - * structure. - *

    - * Note : The Item is not removed from the underlying Container. - *

    - * - * @param itemId - * the ID of the item to remove from the hierarchy. - */ - private void removeFromHierarchyWrapper(Object itemId) { - - LinkedList 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 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 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); - } - - /** - *

    - * 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 false 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)}. - *

    - * - * @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 true if the operation succeeded, false - * 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; - } - - /** - *

    - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (canHaveChildren(newParentId) == true). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent null. - *

    - * - * @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 true if the operation succeeded, false - * 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 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 pcl = children.get(newParentId); - if (pcl == null) { - pcl = new LinkedList(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Remove from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList 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 null 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 null 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 true if the operation succeeded, false - * 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 true if the operation succeeded, false - * 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 true if the operation succeeded, false - * 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. - *

    - * Note : The Property will be removed from all Items in the Container. - *

    - * - * @param propertyId - * the ID of the Property to remove. - * @return true if the operation succeeded, false - * 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; - -/** - *

    - * A wrapper class for adding external ordering to containers not implementing - * the {@link com.vaadin.data.Container.Ordered} interface. - *

    - * - *

    - * 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. - *

    - * - * @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 next; - - /** - * Reverse ordering information for convenience and performance reasons. - */ - private Hashtable 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. - *

    - * Note : The Item is not removed from the underlying Container. - *

    - * - * @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. - *

    - * 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. - *

    - */ - 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(); - prev = new Hashtable(); - } - - // Filter out all the missing items - final LinkedList l = new LinkedList(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 true if the operation succeeded, false - * 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 null 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 null 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 true if the operation succeeded, otherwise - * false - * @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 true if the operation succeeded, false - * 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. - *

    - * Note : The Property will be removed from all the Items in the Container. - *

    - * - * @param propertyId - * the ID of the Property to remove. - * @return true if the operation succeeded, false - * 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 - * DefaultItemSorter adheres to the - * {@link Sortable#sort(Object[], boolean[])} rules and sorts the container - * according to the properties given using - * {@link #setSortProperties(Sortable, Object[], boolean[])}. - *

    - * A Comparator is used for comparing the individual Property - * 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 propertyValueComparator; - - /** - * Constructs a DefaultItemSorter using the default Comparator - * for comparing Propertyvalues. - * - */ - public DefaultItemSorter() { - this(new DefaultPropertyValueComparator()); - } - - /** - * Constructs a DefaultItemSorter which uses the Comparator - * indicated by the propertyValueComparator parameter for - * comparing Propertyvalues. - * - * @param propertyValueComparator - * The comparator to use when comparing individual - * Property values - */ - public DefaultItemSorter(Comparator 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 propertyId in the items - * indicated by item1 and item2 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 sortDirection is false the - * returned value is negated. - *

    - * The comparator set for this DefaultItemSorter 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 ids = new ArrayList(); - final List orders = new ArrayList(); - 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 DefaultPropertyValueComparator assumes all objects it - * compares can be cast to Comparable. - * - */ - public static class DefaultPropertyValueComparator implements - Comparator, 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) 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 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(); - 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 FileSystemContainer 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 FileSystemContainer 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 FileSystemContainer 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 FileSystemContainer 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 FilesystemContainer. - * - * @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 - * FileSystemContainer contains files and directories, this - * method returns true for directory Items only. - * - * @param itemId - * the id of the item. - * @return true if the specified Item is a directory, - * false 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 getChildren(Object itemId) { - - if (!(itemId instanceof File)) { - return Collections.unmodifiableCollection(new LinkedList()); - } - File[] f; - if (filter != null) { - f = ((File) itemId).listFiles(filter); - } else { - f = ((File) itemId).listFiles(); - } - - if (f == null) { - return Collections.unmodifiableCollection(new LinkedList()); - } - - final List 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 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()); - } - - final List l = Arrays.asList(f); - Collections.sort(l); - - return Collections.unmodifiableCollection(l); - } - - /** - * Returns false 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 true if the operaton is successful otherwise - * false. - * @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 false 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 true if the operation is successful otherwise - * false. - * @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 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 ll = Arrays.asList(l); - Collections.sort(ll); - - for (final Iterator 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 getItemIds() { - - if (recursive) { - final Collection col = new ArrayList(); - 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()); - } - - final List 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, null 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 null - */ - @Override - public Property getContainerProperty(Object itemId, Object propertyId) { - - if (!(itemId instanceof File)) { - return null; - } - - if (propertyId.equals(PROPERTY_NAME)) { - return new MethodProperty(getType(propertyId), - new FileItem((File) itemId), FILEITEM_NAME, null); - } - - if (propertyId.equals(PROPERTY_ICON)) { - return new MethodProperty(getType(propertyId), - new FileItem((File) itemId), FILEITEM_ICON, null); - } - - if (propertyId.equals(PROPERTY_SIZE)) { - return new MethodProperty(getType(propertyId), - new FileItem((File) itemId), FILEITEM_SIZE, null); - } - - if (propertyId.equals(PROPERTY_LASTMODIFIED)) { - return new MethodProperty(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 getContainerPropertyIds() { - return FILE_PROPERTIES; - } - - /** - * Gets the specified property's data type. "Name" is a String, - * "Size" is a Long, "Last Modified" is a Date. If - * propertyId is not one of those, null is returned. - * - * @param propertyId - * the ID of the property whose type is requested. - * @return data type of the requested property, or null - */ - @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 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 true if the given object is the same as this - * object, false 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. null 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 true if container is recursive, false - * otherwise. - */ - public boolean isRecursive() { - return recursive; - } - - /** - * Sets the container recursive property. Set this to false to limit the - * files directly under the root file. - *

    - * Note : This is meaningful only if the root really is a directory. - *

    - * - * @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 noChildrenAllowed = new HashSet(); - - /** - * Mapping from Item ID to parent Item ID. - */ - private final HashMap parent = new HashMap(); - - /** - * Mapping from Item ID to parent Item ID for items included in the filtered - * container. - */ - private HashMap filteredParent = null; - - /** - * Mapping from Item ID to a list of child IDs. - */ - private final HashMap> children = new HashMap>(); - - /** - * Mapping from Item ID to a list of child IDs when filtered - */ - private HashMap> filteredChildren = null; - - /** - * List that contains all root elements of the container. - */ - private final LinkedList roots = new LinkedList(); - - /** - * List that contains all filtered root elements of the container. - */ - private LinkedList 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 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); - } - } - - /** - *

    - * 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 false 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)}. - *

    - * - * @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 true if the operation succeeded, false - * 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; - } - - /** - *

    - * Sets the parent of an Item. The new parent item must exist and be able to - * have children. (canHaveChildren(newParentId) == true). It is - * also possible to detach a node from the hierarchy (and thus make it root) - * by setting the parent null. - *

    - * - * @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 true if the operation succeeded, false - * 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 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 pcl = children.get(newParentId); - if (pcl == null) { - // Create an empty list for holding children if one were not - // previously created - pcl = new LinkedList(); - children.put(newParentId, pcl); - } - pcl.add(itemId); - - // Removes from old parent or root - if (oldParentId == null) { - roots.remove(itemId); - } else { - final LinkedList 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 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 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 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 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 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(); - filteredChildren = new HashMap>(); - filteredParent = new HashMap(); - - if (includeParentsWhenFiltering) { - // Filter so that parents for items that match the filter are also - // included - HashSet includedItems = new HashSet(); - 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 filteredItemIds = new LinkedHashSet( - 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 parentToChildrenList = filteredChildren - .get(parentItemId); - if (parentToChildrenList == null) { - parentToChildrenList = new LinkedList(); - 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 includedItems) { - LinkedList 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 includedItems) { - boolean toBeIncluded = passesFilters(itemId); - - LinkedList 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 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 {@link Container.Indexed} interface - * with all important features.

    - * - * Features: - *
      - *
    • {@link Container.Indexed} - *
    • {@link Container.Ordered} - *
    • {@link Container.Sortable} - *
    • {@link Container.Filterable} - *
    • {@link Cloneable} (deprecated, might be removed in the future) - *
    • Sends all needed events on content changes. - *
    - * - * @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 implements - Container.PropertySetChangeNotifier, Property.ValueChangeNotifier, - Container.Sortable, Cloneable, Container.Filterable, - Container.SimpleFilterable { - - /* Internal structure */ - - /** - * Linked list of ordered Property IDs. - */ - private ArrayList propertyIds = new ArrayList(); - - /** - * Property ID to type mapping. - */ - private Hashtable> types = new Hashtable>(); - - /** - * Hash of Items, where each Item is implemented as a mapping from Property - * ID to Property value. - */ - private Hashtable> items = new Hashtable>(); - - /** - * Set of properties that are read-only. - */ - private HashSet> readOnlyProperties = new HashSet>(); - - /** - * List of all Property value change event listeners listening all the - * properties. - */ - private LinkedList 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>> singlePropertyValueChangeListeners = null; - - private HashMap 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(); - } - 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 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 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 t = new Hashtable(); - items.put(newItemId, t); - addDefaultValues(t); - } - - /* Event notifiers */ - - /** - * An event 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 event 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(); - } - 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> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(source.propertyId); - if (propertySetToListenerListMap != null) { - final List 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>>(); - } - Map> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap == null) { - propertySetToListenerListMap = new Hashtable>(); - singlePropertyValueChangeListeners.put(propertyId, - propertySetToListenerListMap); - } - List listenerList = propertySetToListenerListMap - .get(itemId); - if (listenerList == null) { - listenerList = new LinkedList(); - 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> propertySetToListenerListMap = singlePropertyValueChangeListeners - .get(propertyId); - if (propertySetToListenerListMap != null) { - final List 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 String representation of the contents of the - * Item. The format of the string is a space separated catenation of the - * String representations of the values of the Properties - * contained by the Item. - * - * @return String 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 true if the given object is the same as this - * object, false 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, - 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 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 setValue - * method if the Property is not in read-only mode. - * - * @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 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 true if the given object is the same as this - * object, false 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) ((ListSet) getAllItemIds()) - .clone() : null); - nc.setItemSetChangeListeners(getItemSetChangeListeners() != null ? new LinkedList( - getItemSetChangeListeners()) : null); - nc.propertyIds = propertyIds != null ? (ArrayList) propertyIds - .clone() : null; - nc.setPropertySetChangeListeners(getPropertySetChangeListeners() != null ? new LinkedList( - getPropertySetChangeListeners()) : null); - nc.propertyValueChangeListeners = propertyValueChangeListeners != null ? (LinkedList) propertyValueChangeListeners - .clone() : null; - nc.readOnlyProperties = readOnlyProperties != null ? (HashSet>) readOnlyProperties - .clone() : null; - nc.singlePropertyValueChangeListeners = singlePropertyValueChangeListeners != null ? (Hashtable>>) singlePropertyValueChangeListeners - .clone() : null; - - nc.types = types != null ? (Hashtable>) types.clone() - : null; - - nc.setFilters((HashSet) ((HashSet) getFilters()) - .clone()); - - nc.setFilteredItemIds(getFilteredItemIds() == null ? null - : (ListSet) ((ListSet) getFilteredItemIds()) - .clone()); - - // Clone property-values - if (items == null) { - nc.items = null; - } else { - nc.items = new Hashtable>(); - for (final Iterator i = items.keySet().iterator(); i.hasNext();) { - final Object id = i.next(); - final Hashtable it = (Hashtable) items - .get(id); - nc.items.put(id, (Map) 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 ItemSorter interface can be used in Sortable - * implementations to provide a custom sorting method. - */ -public interface ItemSorter extends Comparator, Cloneable, Serializable { - - /** - * Sets the parameters for an upcoming sort operation. The parameters - * determine what container to sort and how the ItemSorter - * sorts the container. - * - * @param container - * The container that will be sorted. The container must contain - * the propertyIds given in the propertyId - * 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 - * container.getSortableContainerPropertyIds(). 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. - *

    - * The parameters for the ItemSorter compare() - * 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 extends ArrayList { - private HashSet 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 duplicates = new HashMap(); - - public ListSet() { - super(); - itemSet = new HashSet(); - } - - public ListSet(Collection c) { - super(c); - itemSet = new HashSet(c.size()); - itemSet.addAll(c); - } - - public ListSet(int initialCapacity) { - super(initialCapacity); - itemSet = new HashSet(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 c) { - boolean modified = false; - Iterator 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 c) { - ensureCapacity(size() + c.size()); - - boolean modified = false; - Iterator 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 toRemove = new HashSet(); - 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 v = (ListSet) super.clone(); - v.itemSet = new HashSet(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; - -/** - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - *

    - * A valid getter method must always be available, but instance of this class - * can be constructed with a null setter method in which case the - * resulting MethodProperty is read-only. - *

    - * - *

    - * 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. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class MethodProperty extends AbstractProperty { - - /** - * 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 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 class1 = (Class) 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); - } - }; - - /** - *

    - * Creates a new instance of MethodProperty 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. - *

    - *

    - * The getter method of a MethodProperty instantiated with this - * constructor will be called with no arguments, and the setter method with - * only the new value as the sole argument. - *

    - * - *

    - * If the setter method is unavailable, the resulting - * MethodProperty will be read-only, otherwise it will be - * read-write. - *

    - * - *

    - * 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. - *

    - * - * @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) convertPrimitiveType(returnType); - if (type.isPrimitive()) { - throw new MethodException(this, "Bean property " - + beanPropertyName - + " getter return type must not be void"); - } - } else { - type = (Class) returnType; - } - - setArguments(new Object[] {}, new Object[] { null }, 0); - this.instance = instance; - } - - /** - *

    - * Creates a new instance of MethodProperty from named getter - * and setter methods. The getter method of a MethodProperty - * instantiated with this constructor will be called with no arguments, and - * the setter method with only the new value as the sole argument. - *

    - * - *

    - * If the setter method is null, the resulting - * MethodProperty will be read-only, otherwise it will be - * read-write. - *

    - * - * @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 type, Object instance, - String getMethodName, String setMethodName) { - this(type, instance, getMethodName, setMethodName, new Object[] {}, - new Object[] { null }, 0); - } - - /** - *

    - * Creates a new instance of MethodProperty with the getter and - * setter methods. The getter method of a MethodProperty - * instantiated with this constructor will be called with no arguments, and - * the setter method with only the new value as the sole argument. - *

    - * - *

    - * If the setter method is null, the resulting - * MethodProperty will be read-only, otherwise it will be - * read-write. - *

    - * - * @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 type, Object instance, - Method getMethod, Method setMethod) { - this(type, instance, getMethod, setMethod, new Object[] {}, - new Object[] { null }, 0); - } - - /** - *

    - * Creates a new instance of MethodProperty from named getter - * and setter methods and argument lists. The getter method of a - * MethodProperty 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. - *

    - * - *

    - * For example, if the setArgs contains A, - * B and C, and setArgumentIndex = - * 1, the call methodProperty.setValue(X) would result - * in the setter method to be called with the parameter set of - * {A, X, C} - *

    - * - * @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 setArgs to be - * replaced with newValue when - * {@link #setValue(Object newValue)} is called. - */ - @SuppressWarnings("unchecked") - public MethodProperty(Class 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) convertPrimitiveType(type); - - setArguments(getArgs, setArgs, setArgumentIndex); - this.instance = instance; - } - - /** - *

    - * Creates a new instance of MethodProperty from the getter and - * setter methods, and argument lists. - *

    - *

    - * 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. - *

    - * - * @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 setArgs to be - * replaced with newValue when - * {@link #setValue(Object newValue)} is called. - */ - @SuppressWarnings("unchecked") - // cannot use "Class" 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 convertedType = (Class) 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 getValue and - * setValue must be compatible with this type: one must be able - * to safely cast the value returned from getValue to the given - * type and pass any variable assignable to this type as an argument to - * setValue. - * - * @return type of the Property - */ - @Override - public final Class getType() { - return type; - } - - /** - * Tests if the object is in read-only mode. In read-only mode calls to - * setValue will throw ReadOnlyException and will - * not modify the value of the Property. - * - * @return true if the object is in read-only mode, - * false 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); - } - } - - /** - *

    - * Sets the setter method and getter method argument lists. - *

    - * - * @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 setArgs to be - * replaced with newValue 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 Property.ReadOnlyException 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); - } - } - - /** - * Exception 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 MethodException 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 MethodException 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 - * bean type - * - * @since 6.6 - */ -public class MethodPropertyDescriptor implements - VaadinPropertyDescriptor { - - 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 class1 = (Class) 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(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 extends AbstractProperty { - - // needed for de-serialization - private String propertyName; - - // chain of getter methods - private transient List 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 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 getMethods = new ArrayList(); - - 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) MethodProperty - .convertPrimitiveType(type); - this.propertyName = propertyName; - this.getMethods = getMethods; - this.setMethod = setMethod; - } - - @Override - public Class 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 Property.ReadOnlyException 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 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 - * bean type - * - * @since 6.6 - */ -public class NestedPropertyDescriptor implements - VaadinPropertyDescriptor { - - 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 beanType) - throws IllegalArgumentException { - this.name = name; - NestedMethodProperty property = new NestedMethodProperty( - 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(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 extends AbstractProperty { - - /** - * The value contained by the Property. - */ - private T value; - - /** - * Data type of the Property's value. - */ - private final Class 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 - public ObjectProperty(T value) { - this(value, (Class) 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 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. value must be assignable - * to this type. - * @param readOnly - * Sets the read-only mode. - */ - public ObjectProperty(T value, Class type, boolean readOnly) { - this(value, type); - setReadOnly(readOnly); - } - - /** - * Returns the type of the ObjectProperty. The methods getValue - * and setValue must be compatible with this type: one must be - * able to safely cast the value returned from getValue to the - * given type and pass any variable assignable to this type as an argument - * to setValue. - * - * @return type of the Property - */ - @Override - public final Class 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 Property.ReadOnlyException 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}. - * - *

    - * 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. - *

    - * - *

    - * For example - *

    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);
    -            }
    -
    -        });
    adds formatter for Double-typed property that extends - * standard "1.0" notation with more zeroes. - *

    - * - * @param T - * type of the underlying property (a PropertyFormatter is always a - * Property<String>) - * - * @deprecated Since 7.0 replaced by {@link Converter} - * @author Vaadin Ltd. - * @since 5.3.0 - */ -@SuppressWarnings("serial") -@Deprecated -public abstract class PropertyFormatter extends AbstractProperty - implements Property.Viewer, Property.ValueChangeListener, - Property.ReadOnlyStatusChangeListener { - - /** Datasource that stores the actual value. */ - Property 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 propertyDataSource) { - - setPropertyDataSource(propertyDataSource); - } - - /** - * Gets the current data source of the formatter, if any. - * - * @return the current data source as a Property, or null if - * none defined. - */ - @Override - public Property getPropertyDataSource() { - return dataSource; - } - - /** - * Sets the specified Property as the data source for the formatter. - * - * - *

    - * Remember that new data sources getValue() must return objects that are - * compatible with parse() and format() methods. - *

    - * - * @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 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 MapItem 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> map = new HashMap>(); - - /** - * List of all property ids to maintain the order. - */ - private LinkedList list = new LinkedList(); - - /** - * List of property set modification listeners. - */ - private LinkedList 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, null is - * returned. - * - * @param id - * the identifier of the Property to get. - * @return the Property with the given ID or null - */ - @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 - * false. - * - * @param id - * the ID of the Property to be removed. - * @return true if the operation succeeded false - * 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 true if the operation succeeded, false - * 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 String representation of the contents of the Item. - * The format of the string is a space separated catenation of the - * String representations of the Properties contained by the - * Item. - * - * @return String 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 event 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 Item - */ - @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(); - } - 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. - *

    - * The method clone performs a shallow copy of the - * PropertysetItem. - *

    - *

    - * 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. - *

    - * - * @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) list.clone() : null; - npsi.propertySetChangeListeners = propertySetChangeListeners != null ? (LinkedList) propertySetChangeListeners - .clone() : null; - npsi.map = (HashMap>) 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; - -/** - *

    - * The QueryContainer 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. - *

    - * - *

    - * The QueryContainer 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. - *

    - * - *

    - * 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()} - *

    - * - * @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 propertyIds; - - private final HashMap> propertyTypes = new HashMap>(); - - private int size = -1; - - private Statement statement; - - /** - * Constructs new QueryContainer with the specified - * queryStatement. - * - * @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 QueryContainer 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 list = new ArrayList(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); - } - - /** - *

    - * Restores items in the container. This method will update the latest data - * to the container. - *

    - * 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 statement. - * - * @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 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 c = new ArrayList(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 - * null 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; null - * 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(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 true if given id is in the container; - * false 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 null 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 null 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 true if the operation succeeded; false - * 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 true if the operation succeeded; false - * 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 true if the operation succeeded; false - * 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 true if the operation succeeded; false - * 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 null 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 null 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 true 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 true 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 Row 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 true if the operation succeeded; - * false 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 null - */ - @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 getItemPropertyIds() { - return propertyIds; - } - - /** - * Removes given item property. - * - * @param id - * ID of the Property to be removed. - * @return true if the item property is removed; - * false 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 null 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 null 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 { - - 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 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 - */ -public class TransactionalPropertyWrapper extends AbstractProperty - implements ValueChangeNotifier, Property.Transactional { - - private Property wrappedProperty; - private boolean inTransaction = false; - private boolean valueChangePending; - private T valueBeforeTransaction; - - public TransactionalPropertyWrapper(Property 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 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 - * bean type - * - * @since 6.6 - */ -public interface VaadinPropertyDescriptor 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. - *

    - * 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. - *

    - *

    - * Converters must not have any side effects (never update UI from inside a - * converter). - *

    - *

    - * All Converters must be stateless and thread safe. - *

    - *

    - * If conversion of a value fails, a {@link ConversionException} is thrown. - *

    - * - * @param - * The model type. Must be compatible with what - * {@link #getModelType()} returns. - * @param - * The presentation type. Must be compatible with what - * {@link #getPresentationType()} returns. - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -public interface Converter extends Serializable { - - /** - * Converts the given value from target type to source type. - *

    - * A converter can optionally use locale to do the conversion. - *

    - * 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. - *

    - * A converter can optionally use locale to do the conversion. - *

    - * 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 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 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 ConversionException without a detail - * message. - */ - public ConversionException() { - } - - /** - * Constructs a new ConversionException 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 ConversionException 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 Converter createConverter( - Class presentationType, Class 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 - * The presentation type - * @param - * 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 Converter getConverter( - Class presentationType, - Class modelType, Application application) { - Converter 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 - * 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 convertFromModel( - MODELTYPE modelValue, - Class presentationType, - Converter 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 - * @param - * @param presentationValue - * @param modelType - * @param converter - * @param locale - * @return - * @throws Converter.ConversionException - */ - public static MODELTYPE convertToModel( - PRESENTATIONTYPE presentationValue, Class modelType, - Converter 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 { - - /* - * (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 getModelType() { - return Long.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class 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}.

    - *

    - * Custom converters can be provided by extending this class and using - * {@link Application#setConverterFactory(ConverterFactory)}. - *

    - * - * @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 Converter createConverter( - Class presentationType, Class modelType) { - Converter converter = findConverter( - presentationType, modelType); - if (converter != null) { - log.finest(getClass().getName() + " created a " - + converter.getClass()); - return converter; - } - - // Try to find a reverse converter - Converter reverseConverter = findConverter( - modelType, presentationType); - if (reverseConverter != null) { - log.finest(getClass().getName() + " created a reverse " - + reverseConverter.getClass()); - return new ReverseConverter(reverseConverter); - } - - log.finest(getClass().getName() + " could not find a converter for " - + presentationType.getName() + " to " + modelType.getName() - + " conversion"); - return null; - - } - - protected Converter findConverter( - Class presentationType, Class modelType) { - if (presentationType == String.class) { - // TextField converters and more - Converter converter = (Converter) createStringConverter(modelType); - if (converter != null) { - return converter; - } - } else if (presentationType == Date.class) { - // DateField converters and more - Converter converter = (Converter) createDateConverter(modelType); - if (converter != null) { - return converter; - } - } - - return null; - - } - - protected Converter createDateConverter(Class sourceType) { - if (Long.class.isAssignableFrom(sourceType)) { - return new DateToLongConverter(); - } else { - return null; - } - } - - protected Converter 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 - * The source type - * @param - * The target type - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class ReverseConverter implements - Converter { - - private Converter 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 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 getModelType() { - return realConverter.getPresentationType(); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getTargetType() - */ - @Override - public Class 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(). - *

    - * Leading and trailing white spaces are ignored when converting from a String. - *

    - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToBooleanConverter implements Converter { - - /* - * (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 getModelType() { - return Boolean.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class 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. - *

    - * Leading and trailing white spaces are ignored when converting from a String. - *

    - *

    - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - *

    - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToDateConverter implements Converter { - - /** - * 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 getModelType() { - return Date.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class 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. - *

    - * Leading and trailing white spaces are ignored when converting from a String. - *

    - *

    - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - *

    - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToDoubleConverter implements Converter { - - /** - * 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 getModelType() { - return Double.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class 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. - *

    - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - *

    - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToIntegerConverter implements Converter { - - /** - * 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 getModelType() { - return Integer.class; - } - - @Override - public Class 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. - *

    - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - *

    - * - * @author Vaadin Ltd - * @version - * @VERSION@ - * @since 7.0 - */ -public class StringToNumberConverter implements Converter { - - /** - * 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 getModelType() { - return Number.class; - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getPresentationType() - */ - @Override - public Class 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 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 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 value. - * - * 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 @@ - - - - - - - - -

    Provides implementations of Property, Item and Container -interfaces, and utilities for the data layer.

    - -

    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.

    - - - 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> allInstances = new ArrayList>(); - private static ReferenceQueue deadInstances = new ReferenceQueue(); - - /** - * 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(c, deadInstances)); - } - } - - /** - * Removes dead references from instance list - */ - private static void removeDeadReferences() { - java.lang.ref.Reference 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 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 extends LinkedHashMap { - private static final long serialVersionUID = 679999766473555231L; - private int cacheLimit = SQLContainer.CACHE_RATIO - * SQLContainer.DEFAULT_PAGE_LENGTH; - - @Override - protected boolean removeEldestEntry(Map.Entry 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 null value was passed to - * the setValue method, but the value of this property can not - * be set to null. - */ - @SuppressWarnings("serial") - public class NotNullableException extends RuntimeException { - - /** - * Constructs a new NotNullableException without a detail - * message. - */ - public NotNullableException() { - } - - /** - * Constructs a new NotNullableException with the specified - * detail message. - * - * @param msg - * the detail message - */ - public NotNullableException(String msg) { - super(msg); - } - - /** - * Constructs a new NotNullableException 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 properties; - - /** - * Prevent instantiation without required parameters. - */ - @SuppressWarnings("unused") - private RowItem() { - } - - public RowItem(SQLContainer container, RowId id, - Collection 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 ids = new ArrayList(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 itemIndexes = new HashMap(); - private final CacheMap cachedItems = new CacheMap(); - - /** Container properties = column names, data types and statuses */ - private final List propertyIds = new ArrayList(); - private final Map> propertyTypes = new HashMap>(); - private final Map propertyReadOnly = new HashMap(); - private final Map propertyNullable = new HashMap(); - - /** Filters (WHERE) and sorters (ORDER BY) */ - private final List filters = new ArrayList(); - private final List sorters = new ArrayList(); - - /** - * 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 itemSetChangeListeners; - - /** Temporary storage for modified items and items to be removed and added */ - private final Map removedItems = new HashMap(); - private final List addedItems = new ArrayList(); - private final List modifiedItems = new ArrayList(); - - /** List of references to other SQLContainers */ - private final Map references = new HashMap(); - - /** 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 itemProperties = new ArrayList(); - 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. - * NOTE: 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 ids = new ArrayList(); - ResultSet rs = null; - try { - // Load ALL rows :( - delegate.beginTransaction(); - rs = delegate.getResults(0, 0); - List 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 toRemove = new ArrayList(); - 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 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 itemProperties = new ArrayList(); - /* 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 propertiesToAdd = new ArrayList( - 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 getFilteredAddedItems() { - ArrayList filtered = new ArrayList(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(); - } - 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: - * - *
  • ' is replaced with ''
  • \x00 is removed
  • \ is - * replaced with \\
  • " is replaced with \"
  • - * \x1a is removed
  • - * - * 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 availableConnections; - private transient Set 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(initialConnections); - reservedConnections = new HashSet(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 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 primaryKeyColumns, - JDBCConnectionPool connectionPool) { - if (primaryKeyColumns == null) { - primaryKeyColumns = new ArrayList(); - } - 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 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 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 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 ThingTM. 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 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 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 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 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 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 Event 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 RowIdChangeEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate a RowIdChangeEvent 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 primaryKeyColumns; - private String versionColumn; - - /** Currently set Filters and OrderBys */ - private List filters; - private List 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 rowIdChangeListeners; - /** Row ID change events, stored until commit() is called */ - private final List bufferedEvents = new ArrayList(); - - /** 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 ob = new ArrayList(); - 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 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 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 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 names = new ArrayList(); - 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 values = new HashMap(); - 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 newRowId = new ArrayList(); - 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 filtersAndKeys = new ArrayList(); - 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(); - } - 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 statementHelperClass = null; - - public DefaultSQLGenerator() { - - } - - /** - * Create a new DefaultSqlGenerator instance that uses the given - * implementation of {@link StatementHelper} - * - * @param statementHelper - */ - public DefaultSQLGenerator( - Class 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 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 filters, List 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 columnToValueMap = generateColumnToValueMap(item); - Map 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 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 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 generateColumnToValueMap(RowItem item) { - Map columnToValueMap = new HashMap(); - 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 generateRowIdentifiers(RowItem item) { - Map rowIdentifiers = new HashMap(); - 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 filters, List 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 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 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 filters, List 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 filters, List 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 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 parameters = new ArrayList(); - private Map> dataTypes = new HashMap>(); - - 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> 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 filterTranslators = new ArrayList(); - 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 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 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. - *

    - * 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. - *

    - * - * @author Vaadin Ltd. - * @version @VERSION@ - * @since 5.4 - */ -@SuppressWarnings("serial") -public abstract class AbstractStringValidator extends AbstractValidator { - - /** - * Constructs a validator for strings. - * - *

    - * Null and empty string values are always accepted. To reject empty values, - * set the field being validated as required. - *

    - * - * @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 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. - *

    - * 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. - *

    - *

    - * 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)}. - *

    - *

    - * 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. - *

    - * - * @param - * The type - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 5.4 - */ -public abstract class AbstractValidator 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 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 exceptions = new ArrayList(); - 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("
    "); - } - 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 CompositeValidator 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 - * AND and OR. - * - * @author Vaadin Ltd. - * @version @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public class CompositeValidator implements Validator { - - public enum CombinationMode { - /** - * The validators are combined with AND clause: validity of - * the composite implies validity of the all validators it is composed - * of must be valid. - */ - AND, - /** - * The validators are combined with OR 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 validators = new LinkedList(); - - /** - * Construct a composite validator in AND 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. - *

    - * The value is valid, if: - *

      - *
    • MODE_AND: All of the sub-validators are valid - *
    • MODE_OR: Any of the sub-validators are valid - *
    - * - * 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. - *

    - * - * @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: - *
      - *
    • {@link CombinationMode#AND} (default) - *
    • {@link CombinationMode#OR} - *
    - * - * @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. - * - *

    - * 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 AND mode composite - * validators. - *

    - * - *

    - * If the validator is in OR mode or does not contain any - * validators of given type null is returned. - *

    - * - * @param validatorType - * The type of validators to return - * - * @return Collection of validators compatible with given type - * that must apply or null if none found. - */ - public Collection getSubValidators(Class validatorType) { - if (mode != CombinationMode.AND) { - return null; - } - - final HashSet found = new HashSet(); - for (Validator v : validators) { - if (validatorType.isAssignableFrom(v.getClass())) { - found.add(v); - } - if (v instanceof CompositeValidator - && ((CompositeValidator) v).getMode() == MODE_AND) { - final Collection 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. - * - *

    - * 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. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 7.0 - */ -public class DateRangeValidator extends RangeValidator { - - /** - * Creates a validator for checking that an Date 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. - *

    - *

    - * 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. - *

    - * - * @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 { - - /** - * 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 { - - /** - * 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 true if nulls are allowed otherwise - * false. - */ - 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. - *

    - * 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)}. - *

    - * - * @param - * 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 extends AbstractValidator { - - private T minValue = null; - private boolean minValueIncluded = true; - private T maxValue = null; - private boolean maxValueIncluded = true; - private Class 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 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 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. - * - *

    - * For the Java regular expression syntax, see - * {@link java.util.regex.Pattern#sum} - *

    - *

    - * See {@link com.vaadin.data.validator.AbstractStringValidator} for more - * information. - *

    - * - * @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 StringLengthValidator 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 true for valid value, otherwise false. - */ - @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 true if null strings are allowed. - * - * @return true if allows null string, otherwise - * false. - */ - @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 @@ - - - - - - - - - - -

    Provides various {@link com.vaadin.data.Validator} -implementations.

    - -

    {@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.

    - - - - 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 String. - */ - 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 addAction() - * -method, which in many cases is easier than implementing the - * Action.Handler interface.
    - * - */ - 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 void addAction(T action); - - public 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: - *

    - * 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) - *

    - * - * - */ -public class ActionManager implements Action.Container, Action.Handler, - Action.Notifier { - - private static final long serialVersionUID = 1641868163608066491L; - - /** List of action handlers */ - protected HashSet ownActions = null; - - /** List of action handlers */ - protected HashSet actionHandlers = null; - - /** Action mapper */ - protected KeyMapper actionMapper = null; - - protected Component viewer; - - private boolean clientHasActions = false; - - public ActionManager() { - - } - - public ActionManager( - T viewer) { - this.viewer = viewer; - } - - private void requestRepaint() { - if (viewer != null) { - viewer.requestRepaint(); - } - } - - public 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 void addAction(T action) { - if (ownActions == null) { - ownActions = new HashSet(); - } - if (ownActions.add(action)) { - requestRepaint(); - } - } - - @Override - public 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(); - } - - 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 actions = new HashSet(); - 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(); - - 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 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 actions = new HashSet(); - 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 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; - -/** - * EventRouter 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 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(); - } - 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(); - } - 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 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 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 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 listeners = new ArrayList(); - 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 FocusEvent listeners. - * By implementing this interface a class explicitly announces that it will - * generate a FocusEvent when it receives keyboard focus. - *

    - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @since 6.2 - * @see FocusListener - * @see FocusEvent - */ - public interface FocusNotifier extends Serializable { - /** - * Adds a FocusListener to the Component which gets fired - * when a Field receives keyboard focus. - * - * @param listener - * @see FocusListener - * @since 6.2 - */ - public void addListener(FocusListener listener); - - /** - * Removes a FocusListener from the Component. - * - * @param listener - * @see FocusListener - * @since 6.2 - */ - public void removeListener(FocusListener listener); - } - - /** - * The interface for adding and removing BlurEvent listeners. - * By implementing this interface a class explicitly announces that it will - * generate a BlurEvent when it loses keyboard focus. - *

    - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @since 6.2 - * @see BlurListener - * @see BlurEvent - */ - public interface BlurNotifier extends Serializable { - /** - * Adds a BlurListener to the Component which gets fired - * when a Field loses keyboard focus. - * - * @param listener - * @see BlurListener - * @since 6.2 - */ - public void addListener(BlurListener listener); - - /** - * Removes a BlurListener from the Component. - * - * @param listener - * @see BlurListener - * @since 6.2 - */ - public void removeListener(BlurListener listener); - } - - /** - * FocusEvent class for holding additional event information. - * Fired when a Field 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); - } - } - - /** - * FocusListener interface for listening for - * FocusEvent fired by a Field. - * - * @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); - } - - /** - * BlurEvent class for holding additional event information. - * Fired when a Field 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); - } - } - - /** - * BlurListener interface for listening for - * BlurEvent fired by a Field. - * - * @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. - *

    - * 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. - *

    - * 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 ItemClickEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate an ItemClickEvent when one of its - * items is clicked. - *

    - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @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 LayoutClickEvent - * listeners. By implementing this interface a class explicitly announces - * that it will generate a LayoutClickEvent when a component - * inside it is clicked and a LayoutClickListener is - * registered. - *

    - * Note: The general Java convention is not to explicitly declare that a - * class generates events, but to directly define the - * addListener and removeListener 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. - *

    - * - * @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; - -/** - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - *

    - * 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. - *

    - * - * @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 arguments 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; - } - - /** - *

    - * 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. - *

    - * - *

    - * This constructor gets the trigger method as a parameter so it does not - * need to reflect to find it out. - *

    - * - * @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 method is not a member of target - * . - */ - 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; - } - - /** - *

    - * 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 - * object, and java.lang.IllegalArgumentException - * is thrown unless exactly one match is found. - *

    - * - * @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 - * java.lang.IllegalArgumentException 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 methodName is found in - * target. - */ - 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; - } - - /** - *

    - * 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. - *

    - * - *

    - * This constructor gets the trigger method as a parameter so it does not - * need to reflect to find it out. - *

    - * - * @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 method is not a member of target - * . - */ - 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; - } - - /** - *

    - * 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. - *

    - * - *

    - * The actual trigger method is reflected from target, and - * java.lang.IllegalArgumentException is thrown unless exactly - * one match is found. - *

    - * - * @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 - * java.lang.IllegalArgumentException is thrown. - * @param arguments - * the arguments to be passed to the trigger method. - * @throws java.lang.IllegalArgumentException - * unless exactly one match methodName is found in - * object. - */ - 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; - } - - /** - *

    - * 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. - *

    - * - *

    - * This constructor gets the trigger method as a parameter so it does not - * need to reflect to find it out. - *

    - * - * @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 method is not a member of object - * . - */ - 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"); - } - } - - /** - *

    - * 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. - *

    - * - *

    - * The actual trigger method is reflected from object, and - * java.lang.IllegalArgumentException is thrown unless exactly - * one match is found. - *

    - * - * @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 - * java.lang.IllegalArgumentException is thrown. - * @throws java.lang.IllegalArgumentException - * unless exactly one match methodName is found in - * target. - */ - 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 EventRouter 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 true if target is the same object as - * the one stored in this object and eventType 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 true if target is the same object as - * the one stored in this object, eventType equals with - * the event type stored in this object and method - * 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 - * ListenerMethod invokes the target method, it may throw - * arbitrary exception. The original exception is wrapped into - * MethodException instance and rethrown by the ListenerMethod. - * - * @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; - -/** - *

    - * Interface for classes supporting registration of methods as event receivers. - *

    - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -public interface MethodEventSource extends Serializable { - - /** - *

    - * 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. - *

    - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @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 method has exactly one match in - * object - */ - public void addListener(Class eventType, Object object, Method method); - - /** - *

    - * 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. - *

    - * - *

    - * This version of addListener gets the name of the activation - * method as a parameter. The actual method is reflected from - * object, and unless exactly one match is found, - * java.lang.IllegalArgumentException is thrown. - *

    - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @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 method has exactly one match in - * object - */ - 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 object's methods that are - * registered to listen to events of type eventType generated - * by this component. - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType 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. - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @param eventType - * the exact event type the object 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); - - /** - *

    - * 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. - *

    - * - *

    - * This version of removeListener 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, - * java.lang.IllegalArgumentException is thrown. - *

    - * - *

    - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

    - * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType with one or more methods. - * @param methodName - * the name of the method owned by target that's - * registered to listen to events of type eventType. - */ - 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 - * Component. - * - * 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 Component. - * - * @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. - *

    - * The ShortcutAction is triggered when the user presses a given key in - * combination with the (optional) given modifier keys. - *

    - *

    - * 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}. - *

    - *

    - * 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. - *

    - * - * @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.
    - * 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.
    - * 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. - *

    - * Insert one or more modifier characters before the character to use as - * keycode. E.g "&Save" will make a shortcut responding to - * ALT-S, "E^xit" will respond to CTRL-X.
    - * Multiple modifiers can be used, e.g "&^Delete" will respond - * to CTRL-ALT-D (the order of the modifier characters is not important). - *

    - *

    - * 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 - * "Save&&&close" will respond to ALT-C, and the caption will - * say "Save&close". - *

    - * - * @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. - *

    - * 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.
    - * E.g - * new ShortcutAction("Do &stuff", new int[]{ShortcutAction.ModifierKey.CTRL})); - * will respond to CTRL-S. - *

    - * - * @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. - *

    - * 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 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 rawVariables = new HashMap(); - private Component sourceComponent; - - public TransferableImpl(Component sourceComponent, - Map 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 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. - *

    - * 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. - *

    - * 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. - * - *

    - * 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. - *

    - * - * @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 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. - *

    - * 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. - *

    - * Based on information from {@link AcceptCriterion} components may display - * some hints for the end user whether the drop will be accepted or not. - *

    - * 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. - *

    - * 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 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}. - *

    - * 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 data = new HashMap(); - private DropTarget dropTarget; - - protected TargetDetailsImpl(Map rawDropData) { - data.putAll(rawDropData); - } - - public TargetDetailsImpl(Map 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. - *

    - * 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. - *

    - * 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}). - *

    - * Subclasses should implement the - * {@link AcceptCriterion#accept(com.vaadin.event.dd.DragAndDropEvent)} method. - *

    - * 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. - *

    - * 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 @@ - - - - - - - - - -

    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.

    - -

    Package Specification

    - -

    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.

    - -

    The power of the event inheritance arises from the possibility of -receiving not only the events of the registered type, but also the -ones which are inherited from it. For example, let's assume that there -are the events GeneralEvent and SpecializedEvent -so that the latter inherits the former. Furthermore we have an object -A which registers to receive GeneralEvent type -events from the object B. A would of course -receive all GeneralEvents generated by B, but in -addition to this, A would also receive all -SpecializedEvents generated by B. However, if -B generates some other events that do not have -GeneralEvent as an ancestor, A would not receive -them unless it registers to listen for them, too.

    - -

    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.

    - -

    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.

    - -

    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.

    - - - - - 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 get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

    - * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

    - * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

    - * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. - *

    - * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

      - *
    • An extra , (comma) may appear just - * before the closing bracket.
    • - *
    • The null value will be inserted when there is , - *  (comma) elision.
    • - *
    • Strings may be quoted with ' (single - * quote).
    • - *
    • 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: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
    • - *
    • Values can be separated by ; (semicolon) as - * well as by , (comma).
    • - *
    • Numbers may have the 0x- (hex) prefix.
    • - *
    - * - * @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 [ (left - * bracket) and ends with ] - *  (right bracket). - * @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 - * separator 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. - *

    - * 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 [ (left - * bracket) and ending with ] - *  (right bracket). - * @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. - *

    - * 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 get and opt methods for accessing the - * values by name, and put methods for adding or replacing values - * by name. The values can be any of these types: Boolean, - * JSONArray, JSONObject, Number, - * String, or the JSONObject.NULL 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 get and - * opt methods, or to convert values into a JSON text using the - * put and toString methods. A get method - * returns a value if one can be found, and throws an exception if one cannot be - * found. An opt method returns a default value instead of throwing - * an exception, and so is useful for obtaining optional values. - *

    - * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt 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. - *

    - * The put methods add or replace values in an object. For example, - * - *

    - * myString = new JSONObject().put("JSON", "Hello, World!").toString();
    - * 
    - * - * produces the string {"JSON": "Hello, World"}. - *

    - * The texts produced by the toString methods strictly conform to - * the JSON syntax rules. The constructors are more forgiving in the texts they - * will accept: - *

      - *
    • An extra , (comma) may appear just - * before the closing brace.
    • - *
    • Strings may be quoted with ' (single - * quote).
    • - *
    • 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: - * { } [ ] / \ : , = ; # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
    • - *
    • Keys can be followed by = or => as well as by - * :.
    • - *
    • Values can be followed by ; (semicolon) as - * well as by , (comma).
    • - *
    • Numbers may have the 0x- (hex) prefix.
    • - *
    - * - * @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 - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - 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 "get" or - * "is" 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 "get" or "is" - * 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 "getName", and - * if the result of calling object.getName() is - * "Larry Fine", then the JSONObject will contain - * "name": "Larry Fine". - * - * @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 { (left - * brace) and ending with } - *  (right brace). - * @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 = '\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. - *

    - * Warning: This method assumes that the data structure is acyclical. - * - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - */ - @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. - *

    - * 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 { (left - * brace) and ending with } (right - * brace). - * @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. - *

    - * 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 { (left - * brace) and ending with } (right - * brace). - * @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. - * - *

    - * 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 { (left - * brace) and ending with } (right - * brace). - * @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. - *

    - * 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 { (left - * brace) and ending with } (right - * brace). - * @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. - *

    - * 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 JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), and - * JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString extends Serializable { - /** - * The toJSONString 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. - *

    - * A JSONStringer instance provides a value method for appending - * values to the text, and a key method for adding keys before - * values in objects. There are array and endArray - * methods that make and bound array values, and object and - * endObject methods which make and bound object values. All of - * these methods return the JSONWriter instance, permitting cascade style. For - * example, - * - *

    - * myString = new JSONStringer().object().key("JSON").value("Hello, World!")
    - *         .endObject().toString();
    - * 
    - * - * which produces the string - * - *
    - * {"JSON":"Hello, World!"}
    - * 
    - *

    - * The first method called must be array or object. - * 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. - *

    - * 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 null if there was a - * problem in the construction of the JSON text (such as the calls to - * array were not properly balanced with calls to - * endArray). - * - * @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 " - *  (double quote) or ' - *  (single quote). - * @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. - *

    - * A JSONWriter instance provides a value method for appending - * values to the text, and a key method for adding keys before - * values in objects. There are array and endArray - * methods that make and bound array values, and object and - * endObject methods which make and bound object values. All of - * these methods return the JSONWriter instance, permitting a cascade style. For - * example, - * - *

    - * new JSONWriter(myWriter).object().key("JSON").value("Hello, World!")
    - *         .endObject();
    - * 
    - * - * which writes - * - *
    - * {"JSON":"Hello, World!"}
    - * 
    - *

    - * The first method called must be array or object. - * 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. - *

    - * 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 - * endArray will be appended to this array. The - * endArray 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 - * array. - * - * @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 - * object. - * - * @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 - * endObject will be appended to this object. The - * endObject 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 true or the value false - * . - * - * @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 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 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 getViewClass() { - return viewClass; - } - } - - private final FragmentManager fragmentManager; - private final ViewDisplay display; - private View currentView = null; - private List listeners = new LinkedList(); - private List providers = new LinkedList(); - - /** - * 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. - * - *

    - * After all {@link View}s and {@link ViewProvider}s have been registered, - * the application should trigger navigation to the current fragment using - * e.g. - * - *

    -     * navigator.navigateTo(Page.getCurrent().getFragment());
    -     * 
    - * - * @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. - * - *

    - * After all {@link View}s and {@link ViewProvider}s have been registered, - * the application should trigger navigation to the current fragment using - * e.g. - * - *

    -     * navigator.navigateTo(Page.getCurrent().getFragment());
    -     * 
    - * - * @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 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 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 @@ - - - - - - - -

    The Vaadin base package. Contains the Application class, the -starting point of any application that uses Vaadin.

    - -

    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).

    - -

    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).

    - -

    All classes in Vaadin are serializable unless otherwise noted. -This allows Vaadin applications to run in cluster and cloud -environments.

    - - - - 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 @@ - - - - - - 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; - -/** - * ApplicationContext 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 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. - *

    - * Note : The icons are associated purely to mime-types, so a file may not have - * a custom icon accessible with this class. - *

    - * - * @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 extToMIMEMap = new Hashtable(); - - /** - * MIME type to Icon mapping. - */ - static private Hashtable MIMEToIconMap = new Hashtable(); - - 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 String 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 String - */ - 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 - * MIMEType. - * @param MIMEType - * the new mime-type for extension. - */ - 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 MIMEType. - */ - 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 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 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 @@ - - - - - - - - - -

    Provides some general service classes used throughout Vaadin -based applications.

    - - - - - - - - - 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, RpcManager> rpcManagerMap = new HashMap, RpcManager>(); - - /** - * A map from server to client RPC interface class to the RPC proxy that - * sends ourgoing RPC calls for that interface. - */ - private Map, ClientRpc> rpcProxyMap = new HashMap, 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 pendingInvocations = new ArrayList(); - - private String connectorId; - - private ArrayList extensions = new ArrayList(); - - 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 void registerRpc(T implementation, Class rpcInterfaceType) { - rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager( - 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 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 rpcInterfaceType) if the Rpc implementation implements more than one interface"); - } - @SuppressWarnings("unchecked") - Class type = (Class) 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. - *

    - * 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. - *

    - *

    - * 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 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 getRpcProxy(final Class 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, Serializable { - private final ClientConnector connector; - - private AllChildrenIterable(ClientConnector connector) { - this.connector = connector; - } - - @Override - public Iterator iterator() { - CombinedIterator iterator = new CombinedIterator(); - 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 retrievePendingRpcCalls() { - if (pendingInvocations.isEmpty()) { - return Collections.emptyList(); - } else { - List result = pendingInvocations; - pendingInvocations = new ArrayList(); - 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, null is returned. - * - * @return The connector's application, or null 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. null 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 null 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 implements Iterator, - Serializable { - - private final Collection> iterators = new ArrayList>(); - - public void addIterator(Iterator iterator) { - iterators.add(iterator); - } - - @Override - public boolean hasNext() { - for (Iterator i : iterators) { - if (i.hasNext()) { - return true; - } - } - return false; - } - - @Override - public T next() { - for (Iterator 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 getAllChildrenIterable( - final ClientConnector connector) { - return new AllChildrenIterable(connector); - } - - @Override - public Collection 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} - * - *

    - * The {@link #getApplication()} and {@link #getRoot()} methods might return - * null after this method is called. - *

    - */ - @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 causes = new ArrayList(); - - 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 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 = "
    "
    -                    + AbstractApplicationServlet
    -                            .safeEscapeForHtml(getMessage()) + "
    "; - 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("
    "); - sb.append(childMessage); - sb.append("
    \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. - *

    - * Extensions can use shared state and RPC in the same way as components. - *

    - * 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 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 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. - *

    - * 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 com_example_MyExtension for the - * server-side - * com.example.MyExtension extends AbstractJavaScriptExtension - * class. If MyExtension instead extends com.example.SuperExtension - * , then com_example_SuperExtension will also be attempted if - * com_example_MyExtension has not been defined. - *

    - * - * The initialization function will be called with this pointing to - * a connector wrapper object providing integration to Vaadin with the following - * functions: - *

      - *
    • getConnectorId() - returns a string with the id of the - * connector.
    • - *
    • getParentId([connectorId]) - returns a string with the id of - * the connector's parent. If connectorId is provided, the id of - * the parent of the corresponding connector with the passed id is returned - * instead.
    • - *
    • getElement([connectorId]) - returns the DOM Element that is - * the root of a connector's widget. null is returned if the - * connector can not be found or if the connector doesn't have a widget. If - * connectorId is not provided, the connector id of the current - * connector will be used.
    • - *
    • getState() - returns an object corresponding to the shared - * state defined on the server. The scheme for conversion between Java and - * JavaScript types is described bellow.
    • - *
    • registerRpc([name, ] rpcObject) - registers the - * rpcObject as a RPC handler. rpcObject should be an - * object with field containing functions for all eligible RPC functions. If - * name is provided, the RPC handler will only used for RPC calls - * for the RPC interface with the same fully qualified Java name. If no - * name 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.
    • - *
    • getRpcProxy([name]) - returns an RPC proxy object. If - * name 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 - * name 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.
    • - *
    • translateVaadinUri(uri) - Translates a Vaadin URI to a URL - * that can be used in the browser. This is just way of accessing - * {@link ApplicationConnection#translateVaadinUri(String)}
    • - *
    - * The connector wrapper also supports these special functions: - *
      - *
    • onStateChange - If the JavaScript code assigns a function to - * the field, that function is called whenever the contents of the shared state - * is changed.
    • - *
    • 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.
    • - *
    • 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.
    • - *
    - *

    - * - * Values in the Shared State and in RPC calls are converted between Java and - * JavaScript using the following conventions: - *

      - *
    • Primitive Java numbers (byte, char, int, long, float, double) and their - * boxed types (Byte, Character, Integer, Long, Float, Double) are represented - * by JavaScript numbers.
    • - *
    • The primitive Java boolean and the boxed Boolean are represented by - * JavaScript booleans.
    • - *
    • Java Strings are represented by JavaScript strings.
    • - *
    • List, Set and all arrays in Java are represented by JavaScript arrays.
    • - *
    • Map in Java is represented by JavaScript object with fields - * corresponding to the map keys.
    • - *
    • 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.
    • - *
    • A Java Bean is represented by a JavaScript object with fields - * corresponding to the bean's properties.
    • - *
    • A Java Connector is represented by a JavaScript string containing the - * connector's id.
    • - *
    • A pluggable serialization mechanism is provided for types not described - * here. Please refer to the documentation for specific types for serialization - * information.
    • - *
    - * - * @author Vaadin Ltd - * @version @VERSION@ - * @since 7.0.0 - */ -public abstract class AbstractJavaScriptExtension extends AbstractExtension { - private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( - this); - - @Override - protected void registerRpc(T implementation, Class 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 this). 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. - *

    - * ApplicationResource 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. - *

    - * - * @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. - * - *

    - * 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 DEFAULT_CACHETIME. - *

    - * - * @return Cache time in milliseconds - */ - public long getCacheTime(); - - /** - * Gets the size of the download buffer used for this resource. - * - *

    - * If the buffer size is 0, the buffer size is decided by the terminal - * adapter. The default value is 0. - *

    - * - * @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; - -/** - * ClassResource 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. - * - *

    - * 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; - } -} 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 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 map = new HashMap(); - 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 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 errorMessages) { - super(null); - setErrorLevel(ErrorLevel.INFORMATION); - - for (final Iterator 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 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 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. null indicates that the default class - * loader should be used. - * - * @return the class loader to use, or null - */ - 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 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 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(); - } - 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 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 - * DEFAULT_CACHETIME. - * - * @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 Location, 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 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, null 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, null 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. - *

    - * An extension can only be attached once. It is not supported to move an - * extension from one target to another. - *

    - * 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; - -/** - * ExternalResource 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; - -/** - * FileResources 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 - * DownloadStream.DEFAULT_CACHETIME. - * - * @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}. - *

    - * 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 callbacks = new HashMap(); - 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> rpcInterfaces = getConnectorState() - .getRpcInterfaces(); - String interfaceName = rpcInterfaceType.getName(); - if (!rpcInterfaces.containsKey(interfaceName)) { - Set methodNames = new HashSet(); - - 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; - -/** - * KeyMapper 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 implements Serializable { - - private int lastKey = 0; - - private final HashMap objectKeyMap = new HashMap(); - - private final HashMap keyObjectMap = new HashMap(); - - /** - * 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 { - /** - * - *

    - * Paints the Paintable into a UIDL stream. This method creates the UIDL - * sequence describing it and outputs it to the given UIDL stream. - *

    - * - *

    - * 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. - *

    - * - *

    - * Do not override this to paint your component. Override - * {@link #paintContent(PaintTarget)} instead. - *

    - * - * - * @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. - *

    - * 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 openList = new LinkedList(); - - /** - * 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 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. - *

    - * 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 i = openList.iterator(); i - .hasNext();) { - (i.next()).paintContent(target); - } - openList.clear(); - } - - // Paint notifications - if (notifications != null) { - target.startTag("notifications"); - for (final Iterator 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. - *

    - * 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 - * null window name is also a special case. - *

    - *

    - * "", 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. - *

    - *

    - * "_blank" as {@code windowName} causes the resource to always be opened in - * a new window or tab (depends on the browser and browser settings). - *

    - *

    - * "_top" and "_parent" as {@code windowName} works as specified by the HTML - * standard. - *

    - *

    - * 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. - *

    - * - * @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(); - } - 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 - * null - */ - 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; - -/** - * PaintExcepection 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 PaintExeception with the specified - * detail message. - * - * @param msg - * the detail message. - */ - public PaintException(String msg) { - super(msg); - } - - /** - * Constructs an instance of PaintExeception 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 PaintExeception 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. - *

    - * 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. - *

    - *

    - * This method may also add only a reference to the paintable and queue the - * paintable to be painted separately. - *

    - *

    - * Each paintable being painted should be closed by a matching - * {@link #endPaintable(Component)} regardless of the {@link PaintStatus} - * returned. - *

    - * - * @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. - * - *
    -     * Todo:
    -     * Checking of input values
    -     * 
    - * - * @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. - *

    - * 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)}. - *

    - * Note that in current terminal implementation StreamVariables are cleaned - * from the terminal only when: - *

      - *
    • a StreamVariable with same name replaces an old one - *
    • the variable owner is no more attached - *
    • the developer signals this by calling - * {@link StreamingStartEvent#disposeStreamVariable()} - *
    - * 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. - *

    - * Prints full XML section. The section data must be XML and it is - * surrounded by XML start and end-tags. - *

    - * - * @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 false 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; - -/** - * Resource 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; - -/** - *

    - * This interface is implemented by all visual objects that can be scrolled - * programmatically from the server-side. The unit of scrolling is pixel. - *

    - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -public interface Scrollable extends Serializable { - - /** - * Gets scroll left offset. - * - *

    - * Scrolling offset is the number of pixels this scrollable has been - * scrolled right. - *

    - * - * @return Horizontal scrolling position in pixels. - */ - public int getScrollLeft(); - - /** - * Sets scroll left offset. - * - *

    - * Scrolling offset is the number of pixels this scrollable has been - * scrolled right. - *

    - * - * @param scrollLeft - * the xOffset. - */ - public void setScrollLeft(int scrollLeft); - - /** - * Gets scroll top offset. - * - *

    - * Scrolling offset is the number of pixels this scrollable has been - * scrolled down. - *

    - * - * @return Vertical scrolling position in pixels. - */ - public int getScrollTop(); - - /** - * Sets scroll top offset. - * - *

    - * Scrolling offset is the number of pixels this scrollable has been - * scrolled down. - *

    - * - *

    - * 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. - *

    - * - * @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 CSS - * specification 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 CSS - * specification 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; - -/** - * StreamResource 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 StreamResource. 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 StreamResource. - * StreamSource 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. - * - *

    - * 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; - } - -} 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. - *

    - * 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. - *

    - * - * @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. - *

    - * {@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. - *

    - * 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; - -/** - * SystemError 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("

    "); - sb.append(AbstractApplicationServlet - .safeEscapeForHtml(getMessage())); - sb.append("

    "); - } - 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.

    - * - * @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. - *

    - * 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. - *

    - * - * @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. - * - *

    - * 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. - *

    - * - * @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; - -/** - * ThemeResource 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 true if the given object equals this Icon, - * false 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; - -/** - * UserError 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 { - - /** - *

    - * Paints the Paintable into a UIDL stream. This method creates the UIDL - * sequence describing it and outputs it to the given UIDL stream. - *

    - * - *

    - * 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. - *

    - * - * @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; - -/** - *

    - * Listener interface for UI variable changes. The user communicates with the - * application using the so-called variables. 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. - *

    - * - * @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 variables); - - /** - *

    - * Tests if the variable owner is enabled or not. The terminal should not - * send any variable changes to disabled variable owners. - *

    - * - * @return true if the variable owner is enabled, - * false if not - */ - public boolean isEnabled(); - - /** - *

    - * 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. - *

    - * - *

    - * Note: VariableOwner 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 false - * in {@link #isImmediate()}. - *

    - * - * @return true if the component is in immediate mode, - * false 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 null 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 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 null 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 null if no path information is available. Does - * always start with / if the path isn't null. - * - * @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 null 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 null 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 null 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 null 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 OutputStream for writing binary data in the - * response. - *

    - * Either this method or getWriter() may be called to write the response, - * not both. - * - * @return a OutputStream 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 PrintWriter object that can send character text to - * the client. The PrintWriter uses the character encoding defined using - * setContentType. - *

    - * Either this method or getOutputStream() may be called to write the - * response, not both. - * - * @return a PrintWriter 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 getParameterMap() { - Map 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 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 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("dummy page"); - 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 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 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 += "

    " + 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 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 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 += "

    " + 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 += ""; - } - if (caption != null) { - output += "" + caption + "
    "; - } - if (message != null) { - output += message; - output += "

    "; - } - - if (details != null) { - output += details; - output += "

    "; - } - if (url != null) { - output += "
    "; - } - 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 CHAR_BLACKLIST = new HashSet( - 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 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 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 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 applications = context.getApplications(); - - // Search for the application (using the application URI) from the list - for (final Iterator 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: - *

      - *
    • An application runner servlet that runs different Vaadin applications - * based on an identifier.
    • - *
    • 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)
    • - * - * @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 rootToClientCache = new HashMap(); - - 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 locales; - - private int pendingLocalesIndex; - - private int timeoutInterval = -1; - - private DragAndDropService dragAndDropService; - - private String requestThemeName; - - private int maxInactiveInterval; - - private Connector highlightedConnector; - - private Map> connectorResourceContexts = new HashMap>(); - - private Map> pidToNameToStreamVariable; - - private Map 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()); - } - } - 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()); - } - } - 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("download handled"); - 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 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 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 h = new LinkedList(); - 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 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 dirtyVisibleConnectors = new ArrayList(); - 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 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 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 rpcPendingQueue = new LinkedList( - dirtyVisibleConnectors); - List 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 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> usedClientConnectors = paintTarget - .getUsedClientConnectors(); - boolean typeMappingsOpen = false; - ClientCache clientCache = getClientCache(root); - - List> newConnectorTypes = new ArrayList>(); - - for (Class 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 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) 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>() { - @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 scriptDependencies = new ArrayList(); - List styleDependencies = new ArrayList(); - - for (Class 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 dirtyVisibleConnectors) - throws PaintException { - List legacyComponents = new ArrayList(); - 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 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() { - - @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 true if the connector is visible to the client, - * false 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 implements Iterator { - - @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 collectPendingRpcCalls( - List rpcPendingQueue) { - List pendingInvocations = new ArrayList(); - for (ClientConnector connector : rpcPendingQueue) { - List paintablePendingRpc = connector - .retrievePendingRpcCalls(); - if (null != paintablePendingRpc && !paintablePendingRpc.isEmpty()) { - List oldPendingRpc = pendingInvocations; - int totalCalls = pendingInvocations.size() - + paintablePendingRpc.size(); - pendingInvocations = new ArrayList( - 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) 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 enabledConnectors = new HashSet(); - - List 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 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 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 parseInvocations( - ConnectorTracker connectorTracker, final String burst) - throws JSONException { - JSONArray invocationsJson = new JSONArray(burst); - - ArrayList invocations = new ArrayList(); - - 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 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 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 getDirtyVisibleConnectors( - ConnectorTracker connectorTracker) { - ArrayList dirtyConnectors = new ArrayList(); - 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(); - 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, Integer> typeToKey = new HashMap, Integer>(); - private int nextTypeKey = 0; - - private BootstrapHandler bootstrapHandler; - - String getTagForType(Class 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 res = new HashSet(); - - /** - * - * @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>(); - } - Map nameToStreamVariable = pidToNameToStreamVariable - .get(paintableId); - if (nameToStreamVariable == null) { - nameToStreamVariable = new HashMap(); - pidToNameToStreamVariable.put(paintableId, nameToStreamVariable); - } - nameToStreamVariable.put(name, value); - - if (streamVariableToSeckey == null) { - streamVariableToSeckey = new HashMap(); - } - 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 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 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 getAddonContextListeners() { - // Called once for init and then no more, so there's no point in caching - // the instance - ServiceLoader 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 listeners = Collections - .synchronizedList(new LinkedList()); - - protected final HashSet applications = new HashSet(); - - protected WebBrowser browser = new WebBrowser(); - - protected HashMap applicationToAjaxAppMgrMap = new HashMap(); - - 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 currentListeners; - synchronized (listeners) { - currentListeners = new ArrayList(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 exceptions = null; - - ArrayList currentListeners; - synchronized (listeners) { - currentListeners = new ArrayList(listeners); - } - - for (TransactionListener listener : currentListeners) { - try { - listener.transactionEnd(application, request); - } catch (final RuntimeException t) { - if (exceptions == null) { - exceptions = new LinkedList(); - } - 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 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 bootstrapListeners = new ArrayList(); - - private List initedListeners = new ArrayList(); - - public AddonContext(DeploymentConfiguration deploymentConfiguration) { - this.deploymentConfiguration = deploymentConfiguration; - deploymentConfiguration.setAddonContext(this); - } - - public DeploymentConfiguration getDeploymentConfiguration() { - return deploymentConfiguration; - } - - public void init() { - AddonContextEvent event = new AddonContextEvent(this); - Iterator 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 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 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 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 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 fragmentNodes; - - public BootstrapFragmentResponse(BootstrapHandler handler, - WrappedRequest request, List fragmentNodes, - Application application, Integer rootId) { - super(handler, request, application, rootId); - this.fragmentNodes = fragmentNodes; - } - - public List 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 headers = new LinkedHashMap(); - Document document = Document.createShell(""); - BootstrapPageResponse pageResponse = new BootstrapPageResponse( - this, request, document, headers, context.getApplication(), - context.getRootId()); - List 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 headers) { - Set> entrySet = headers.entrySet(); - for (Entry 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(), 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. - *

      - * 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- - *- Additionally added from javascript: - * .v-theme- - */ - - String appClass = "v-app-" - + context.getApplication().getClass().getSimpleName(); - - String classNames = "v-app " + appClass; - List 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("//"); - 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 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 headers; - private final Document document; - - public BootstrapPageResponse(BootstrapHandler handler, - WrappedRequest request, Document document, - Map 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 variableChanges; - - public ChangeVariablesErrorEvent(Component component, Throwable throwable, - Map variableChanges) { - this.component = component; - this.throwable = throwable; - this.variableChanges = variableChanges; - } - - @Override - public Throwable getThrowable() { - return throwable; - } - - public Component getComponent() { - return component; - } - - public Map 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 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 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. - * - *

      - * 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. - *

      - *

      - * 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. - *

      - * - *

      - * It is not possible to change the parent without first setting the parent - * to {@code null}. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * The attachment logic is implemented in {@link AbstractClientConnector}. - *

      - */ - public void attach(); - - /** - * Notifies the component that it is detached from the application. - * - *

      - * 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. - *

      - */ - public void detach(); - - /** - * Get a read-only collection of all extensions attached to this connector. - * - * @return a collection of extensions - */ - public Collection 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 { - 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 validateComponentRelativeSizes( - Component component, List 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(); - } - 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 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 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 subErrors = new Vector(); - - 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 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 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 getHeightAttributes(Component component) { - Stack attributes = new Stack(); - 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 getWidthAttributes(Component component) { - Stack attributes = new Stack(); - 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 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 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 creationLocations = new HashMap(); - private static Map widthLocations = new HashMap(); - private static Map heightLocations = new HashMap(); - - 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 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 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 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 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 variables) { - Map rawDragDropDetails = (Map) 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 variables) { - return getRequestType(variables) == DragEventType.DROP; - } - - private DragEventType getRequestType(Map variables) { - int type = (Integer) variables.get("type"); - return DragEventType.values()[type]; - } - - @SuppressWarnings("unchecked") - private Transferable constructTransferable(DropTarget dropHandlerOwner, - Map variables) { - final Component sourceComponent = (Component) variables - .get("component"); - - variables = (Map) 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 retrievePendingRpcCalls() { - return null; - } - - @Override - public RpcManager getRpcManager(Class rpcInterface) { - // TODO Use rpc for drag'n'drop - return null; - } - - @Override - public Class 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 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: - * - *
      - *      <servlet>
      - *              <servlet-name>HelloWorld</servlet-name>
      - *              <servlet-class>com.vaadin.terminal.gwt.server.GAEApplicationServlet</servlet-class>
      - *              <init-param>
      - *                      <param-name>application</param-name>
      - *                      <param-value>com.vaadin.demo.HelloWorld</param-value>
      - *              </init-param>
      - *      </servlet>
      - * 
      - * - * Session support must be enabled in appengine-web.xml: - * - *
      - *      <sessions-enabled>true</sessions-enabled>
      - * 
      - * - * 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): - * - *
      - * <cronentries>
      - *   <cron>
      - *     <url>/HelloWorld/CLEAN</url>
      - *     <description>Clean up sessions</description>
      - *     <schedule>every 2 hours</schedule>
      - *   </cron>
      - * </cronentries>
      - * 
      - * - * 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: - * - *
      - *      <static-files>
      - *           <include path="/VAADIN/**" />
      - *      </static-files>
      - * 
      - * - * Additional limitations: - *
        - *
      • Do not change application state when serving an ApplicationResource. - *
      • Avoid changing application state in transaction handlers, unless you're - * confident you fully understand the synchronization issues in App Engine. - *
      • The application remains locked while uploading - no progressbar is - * possible. - *
      - */ -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 entities = pq.asList(Builder - .withLimit(CLEANUP_LIMIT)); - if (entities != null) { - getLogger().info( - "Vaadin cleanup deleting " + entities.size() - + " expired Vaadin sessions."); - List keys = new ArrayList(); - 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 entities = pq.asList(Builder - .withLimit(CLEANUP_LIMIT)); - if (entities != null) { - getLogger().info( - "Vaadin cleanup deleting " + entities.size() - + " expired appengine sessions."); - List keys = new ArrayList(); - 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. - *

      - * Interface can be used for several helper tasks including: - *

        - *
      • Opening and closing database connections - *
      • Implementing {@link ThreadLocal} - *
      • Setting/Getting {@link Cookie} - *
      - *

      - * 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, String> typeToTransportType = new HashMap, String>(); - - /** - * Note! This does not contain primitives. - *

      - */ - private static Map> transportTypeToType = new HashMap>(); - - 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. - *

      - * Ensures the encoded value is of the same type as target type. - *

      - *

      - * 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. - *

      - * - * @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 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(); - } - } - - 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 decodeObjectMap(Type keyType, - Type valueType, JSONArray jsonMap, ConnectorTracker connectorTracker) - throws JSONException { - Map map = new HashMap(); - - 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 decodeConnectorMap(Type valueType, - JSONObject jsonMap, ConnectorTracker connectorTracker) - throws JSONException { - Map map = new HashMap(); - - 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 decodeStringMap(Type valueType, - JSONObject jsonMap, ConnectorTracker connectorTracker) - throws JSONException { - Map map = new HashMap(); - - 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 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 tokens = new ArrayList(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 decodeList(Type targetType, - boolean restrictToInternalTypes, JSONArray jsonArray, - ConnectorTracker connectorTracker) throws JSONException { - List list = new ArrayList(); - 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 decodeSet(Type targetType, - boolean restrictToInternalTypes, JSONArray jsonArray, - ConnectorTracker connectorTracker) throws JSONException { - HashSet set = new HashSet(); - 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 mOpenTags; - - private final Stack openJsonTags; - - // these match each other element-wise - private final Stack openPaintables; - private final Stack openPaintableTags; - - private final PrintWriter uidlBuffer; - - private boolean closed = false; - - private final AbstractCommunicationManager manager; - - private int changes = 0; - - private final Set usedResources = new HashSet(); - - private boolean customLayoutArgumentsOpen = false; - - private JsonTag tag; - - private boolean cacheEnabled = false; - - private final Set> usedClientConnectors = new HashSet>(); - - /** - * 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(); - openJsonTags = new Stack(); - - openPaintables = new Stack(); - openPaintableTags = new Stack(); - - cacheEnabled = cachingRequired; - } - - @Override - public void startTag(String tagName) throws PaintException { - startTag(tagName, false); - } - - /** - * Prints the element start tag. - * - *
      -     *   Todo:
      -     *    Checking of input values
      -     * 
      -     * 
      - * - * @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 "&"; // & => & - case '>': - return ">"; // > => > - case '<': - return "<"; // < => < - case '"': - return """; // " => " - case '\'': - return "'"; // ' => ' - 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 getUIDL 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 - * getUIDL 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 variables = new Vector(); - - Vector children = new Vector(); - - Vector attr = new Vector(); - - 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 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 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 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 getUsedResources() { - return usedResources; - } - - @Override - @SuppressWarnings("unchecked") - public String getTag(ClientConnector clientConnector) { - Class clientConnectorClass = clientConnector - .getClass(); - while (clientConnectorClass.isAnonymousClass()) { - clientConnectorClass = (Class) clientConnectorClass - .getSuperclass(); - } - Class clazz = clientConnectorClass; - while (!usedClientConnectors.contains(clazz) - && clazz.getSuperclass() != null - && ClientConnector.class.isAssignableFrom(clazz)) { - usedClientConnectors.add((Class) clazz); - clazz = clazz.getSuperclass(); - } - return manager.getTagForType(clientConnectorClass); - } - - Collection> 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 variableChanges = new HashMap(); - - 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 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> portletListeners = new HashMap>(); - - protected transient PortletSession session; - protected transient PortletConfig portletConfig; - - protected HashMap portletWindowIdToApplicationMap = new HashMap(); - - private transient PortletResponse response; - - private final Map eventActionDestinationMap = new HashMap(); - private final Map eventActionValueMap = new HashMap(); - - private final Map sharedParameterActionNameMap = new HashMap(); - private final Map sharedParameterActionValueMap = new HashMap(); - - @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 - // false - // 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 l = portletListeners.get(app); - if (l == null) { - l = new LinkedHashSet(); - portletListeners.put(app, l); - } - l.add(listener); - } - - public void removePortletListener(Application app, PortletListener listener) { - Set l = portletListeners.get(app); - if (l != null) { - l.remove(listener); - } - } - - public void firePortletRenderRequest(Application app, Root root, - RenderRequest request, RenderResponse response) { - Set 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 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 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 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. - *

      - * Only JSR 286 style Portlets are supported. - *

      - * The interface can be used for several helper tasks including: - *

        - *
      • Opening and closing database connections - *
      • Implementing {@link ThreadLocal} - *
      • Inter-portlet communication - *
      - *

      - * 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 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 implements RpcManager { - - private final T implementation; - private final Class rpcInterface; - - private static final Map, Class> boxedTypes = new HashMap, 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 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 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 invocationMethodCache = new ConcurrentHashMap( - 128, 0.75f, 1); - - private final Method method; - - private Class interfaceClass; - - public ServerRpcMethodInvocation(String connectorId, String interfaceName, - String methodName, int parameterCount) { - super(connectorId, interfaceName, methodName); - - interfaceClass = findClass(); - method = findInvocationMethod(interfaceClass, methodName, - parameterCount); - } - - private Class 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) rpcInterface; - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("The server RPC interface " - + getInterfaceName() + " could not be found", e); - } finally { - - } - } - - public Class 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 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) 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 SystemMessageException with the specified - * detail message. - * - * @param msg - * the detail message. - */ - public SystemMessageException(String msg) { - super(msg); - } - - /** - * Constructs a new SystemMessageException 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 SystemMessageException 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. - * - *

      - * This handler is usually added to the application by - * {@link AbstractCommunicationManager}. - *

      - */ -@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("

      I'm sorry, but your browser is not supported

      " - + "

      The version (" - + b.getBrowserMajorVersion() - + "." - + b.getBrowserMinorVersion() - + ") of the browser you are using " - + " is outdated and not supported.

      " - + "

      You should consider upgrading to a more up-to-date browser.

      " - + "

      The most popular browsers are " - + " Chrome," - + " Firefox," - + (b.isWindows() ? " Internet Explorer," - : "") - + " Opera" - + " and Safari.
      " - + "Upgrading to the latest version of one of these will make the web safer, faster and better looking.

      " - + (b.isIE() ? "" - + "

      If you can not upgrade your browser, please consider trying Chrome Frame.

      " - : "") // - + "

      Continue without updating (not recommended)

      " - + "\n" + ""); - - 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 attrs = new HashMap(); - for (Enumeration 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. - * - *

      - * Note that Internet Explorer in IE7 compatibility mode might return 8 in - * some cases even though it should return 7. - *

      - * - * @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. - *

      - * You can use this to figure out which TimeZones the user could actually be - * in by calling {@link TimeZone#getAvailableIDs(int)}. - *

      - *

      - * 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. - *

      - * - * @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 WrappedHttpServletRequest from a - * WrappedRequest. 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 HttpServletResponse - * - * @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 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 null 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 WrappedPortlettRequest from a - * WrappedRequest. 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 @@ - - - - - - - - - - -

      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.)

      - -

      Package Specification

      - - - - - - - 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. - *

      - * 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. - *

      - * 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 componentToCoordinates = new LinkedHashMap(); - - /** - * 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 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. - *

      - * 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. - *

      - * - * @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 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 connectorToPosition = new HashMap(); - for (Iterator 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. - *

      - * Note that you cannot update the position by updating this object. Call - * {@link #setPosition(Component, ComponentPosition)} with the updated - * {@link ComponentPosition} object. - *

      - * - * @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. - * - *
      -         * setCSSString("top:10px;left:20%;z-index:16;");
      -         * 
      - * - * @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 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()); - } - List 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()); - } - List 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 String. Caption is the visible - * name of the component. This method will trigger a - * {@link RepaintRequestEvent}. - * - * @param caption - * the new caption String 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. - * - *
      -     * // Component for which the locale is meaningful
      -     * InlineDateField date = new InlineDateField("Datum");
      -     * 
      -     * // German language specified with ISO 639-1 language
      -     * // code and ISO 3166-1 alpha-2 country code.
      -     * date.setLocale(new Locale("de", "DE"));
      -     * 
      -     * date.setResolution(DateField.RESOLUTION_DAY);
      -     * layout.addComponent(date);
      -     * 
      - * - * - * @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(); - } - } - - /** - *

      - * 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: - *

      - * - *

      - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      TagDescriptionExample
      <b>boldbold text
      <i>italicitalic text
      <u>underlinedunderlined text
      <br>linebreakN/A
      <ul>
      - * <li>item1
      - * <li>item1
      - * </ul>
      item list - *
        - *
      • item1 - *
      • item2 - *
      - *
      - *

      - * - *

      - * These tags may be nested. - *

      - * - * @return component's description String - */ - 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. - *

      - * To find the Window that contains the component, use {@code Window w = - * getParent(Window.class);} - *

      - * - * @param - * 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 findAncestor(Class 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 ErrorMessage 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. - * - *

      - * 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. - *

      - *

      - * This method is not meant to be overridden. Due to CDI requirements we - * cannot declare it as final even though it should be final. - *

      - * - * @return the parent application of the component or null. - * @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); - - /** - *

      - * 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. - *

      - * - *

      - * This method additionally informs the event-api to route events with the - * given eventIdentifier to the components handleEvent function call. - *

      - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @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 object's methods that are - * registered to listen to events of type eventType generated - * by this component. - * - *

      - * This method additionally informs the event-api to stop routing events - * with the given eventIdentifier to the components handleEvent function - * call. - *

      - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @param eventIdentifier - * the identifier of the event to stop listening for - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType 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(); - } - } - } - - /** - *

      - * 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. - *

      - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @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); - } - - /** - *

      - * 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. - *

      - * - *

      - * This version of addListener gets the name of the activation - * method as a parameter. The actual method is reflected from - * object, and unless exactly one match is found, - * java.lang.IllegalArgumentException is thrown. - *

      - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - *

      - * 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. - *

      - * - * @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 object's methods that are - * registered to listen to events of type eventType generated - * by this component. - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType 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. - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @param eventType - * the exact event type the object listens to. - * @param target - * target object that has registered to listen to events of type - * eventType with one or more methods. - * @param method - * the method owned by target that's registered to - * listen to events of type eventType. - */ - @Override - public void removeListener(Class eventType, Object target, Method method) { - if (eventRouter != null) { - eventRouter.removeListener(eventType, target, method); - } - } - - /** - *

      - * 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. - *

      - * - *

      - * This version of removeListener gets the name of the - * activation method as a parameter. The actual method is reflected from - * target, and unless exactly one match is found, - * java.lang.IllegalArgumentException is thrown. - *

      - * - *

      - * For more information on the inheritable event mechanism see the - * {@link com.vaadin.event com.vaadin.event package documentation}. - *

      - * - * @param eventType - * the exact event type the object listens to. - * @param target - * the target object that has registered to listen to events of - * type eventType with one or more methods. - * @param methodName - * the name of the method owned by target that's - * registered to listen to events of type eventType. - */ - @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 l = new LinkedList(); - - // Adds all components - for (final Iterator i = getComponentIterator(); i.hasNext();) { - l.add(i.next()); - } - - // Removes all component - for (final Iterator 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 components = new LinkedList(); - for (final Iterator i = source.getComponentIterator(); i - .hasNext();) { - components.add(i.next()); - } - - for (final Iterator 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 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 invalidChildren, - boolean childrenMayBecomeUndefined, boolean vertical) { - if (childrenMayBecomeUndefined) { - Collection previouslyInvalidComponents = invalidChildren; - invalidChildren = getInvalidSizedChildren(vertical); - if (previouslyInvalidComponents != null && invalidChildren != null) { - for (Iterator 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 stillInvalidChildren = getInvalidSizedChildren(vertical); - if (stillInvalidChildren != null) { - for (Component component : stillInvalidChildren) { - // didn't become valid - invalidChildren.remove(component); - } - } - } - if (invalidChildren != null) { - repaintChildTrees(invalidChildren); - } - } - - private Collection getInvalidSizedChildren(final boolean vertical) { - HashSet 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(1); - components.add(content); - } - } else { - for (Iterator 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(); - } - components.add(component); - } - } - } - return components; - } - - private void repaintChildTrees(Collection 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 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 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; - -/** - *

      - * 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. - * AbstractField implements that interface itself, too, so - * accessing the Property value represented by it is straightforward. - *

      - * - *

      - * 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. - *

      - * - *

      - * The class also supports {@link com.vaadin.data.Validator validators} to make - * sure the value contained in the field is valid. - *

      - * - * @author Vaadin Ltd. - * @version - * @VERSION@ - * @since 3.0 - */ -@SuppressWarnings("serial") -public abstract class AbstractField extends AbstractComponent implements - Field, 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 converter = null; - /** - * Connected data-source. - */ - private Property dataSource = null; - - /** - * The list of validators. - */ - private LinkedList 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 getValue and - * setValue must be compatible with this type: one must be able - * to safely cast the value returned from getValue to the given - * type and pass any variable assignable to this type as an argument to - * setValue. - * - * @return the type of the Field - */ - @Override - public abstract Class 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. - *

      - * When the field is in buffered mode, changes will not be committed to the - * property data source until {@link #commit()} is called. - *

      - *

      - * Changing buffered mode will change the read through and write through - * state for the field. - *

      - *

      - * Mixing calls to {@link #setBuffered(boolean)} and - * {@link #setReadThrough(boolean)} or {@link #setWriteThrough(boolean)} is - * generally a bad idea. - *

      - * - * @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. - *

      - * 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. - * - *

      - * This is the visible, modified and possible invalid value the user have - * entered to the field. - *

      - * - *

      - * 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. - *

      - * - *

      - * Since Vaadin 7.0, no implicit conversions between other data types and - * String are performed, but a converter is used if set. - *

      - * - * @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 null if - * none defined. - */ - @Override - public Property getPropertyDataSource() { - return dataSource; - } - - /** - *

      - * Sets the specified Property as the data source for the field. All - * uncommitted changes are replaced with a value from the new data source. - *

      - * - *

      - * 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. - *

      - * - *

      - * 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}. - *

      - * - *

      - * 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(). - *

      - * - * @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 validators = ((Validatable) dataSource) - .getValidators(); - if (validators != null) { - for (final Iterator 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 c = (Converter) 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) 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. - *

      - * 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. - *

      - * - * @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(); - } - validators.add(validator); - requestRepaint(); - } - - /** - * Gets the validators of the field. - * - * @return the Unmodifiable collection that holds all validators for the - * field. - */ - @Override - public Collection 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 true if all registered validators claim that the - * current value is valid or if the field is empty and not required, - * false 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. - *

      - * 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 validationExceptions = new ArrayList(); - 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. - *

      - * 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. - *

      - * - * @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 Event 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 true if the field is required, otherwise - * false. - */ - @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 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 converter) { - this.converter = (Converter) 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 - * isListeningToPropertyEvents == true. - */ - 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 isListeningToPropertyEvents == false. - */ - 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. - *

      - * 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 com_example_MyComponent for the - * server-side - * com.example.MyComponent extends AbstractJavaScriptComponent - * class. If MyComponent instead extends com.example.SuperComponent - * , then com_example_SuperComponent will also be attempted if - * com_example_MyComponent has not been defined. - *

      - * JavaScript components have a very simple GWT widget ({@link JavaScriptWidget} - * ) just consisting of a div element to which the JavaScript code - * should initialize its own user interface. - *

      - * The initialization function will be called with this pointing to - * a connector wrapper object providing integration to Vaadin with the following - * functions: - *

        - *
      • getConnectorId() - returns a string with the id of the - * connector.
      • - *
      • getParentId([connectorId]) - returns a string with the id of - * the connector's parent. If connectorId is provided, the id of - * the parent of the corresponding connector with the passed id is returned - * instead.
      • - *
      • getElement([connectorId]) - returns the DOM Element that is - * the root of a connector's widget. null is returned if the - * connector can not be found or if the connector doesn't have a widget. If - * connectorId is not provided, the connector id of the current - * connector will be used.
      • - *
      • getState() - returns an object corresponding to the shared - * state defined on the server. The scheme for conversion between Java and - * JavaScript types is described bellow.
      • - *
      • registerRpc([name, ] rpcObject) - registers the - * rpcObject as a RPC handler. rpcObject should be an - * object with field containing functions for all eligible RPC functions. If - * name is provided, the RPC handler will only used for RPC calls - * for the RPC interface with the same fully qualified Java name. If no - * name 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.
      • - *
      • getRpcProxy([name]) - returns an RPC proxy object. If - * name 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 - * name 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.
      • - *
      • translateVaadinUri(uri) - Translates a Vaadin URI to a URL - * that can be used in the browser. This is just way of accessing - * {@link ApplicationConnection#translateVaadinUri(String)}
      • - *
      - * The connector wrapper also supports these special functions: - *
        - *
      • onStateChange - If the JavaScript code assigns a function to - * the field, that function is called whenever the contents of the shared state - * is changed.
      • - *
      • 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.
      • - *
      • 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.
      • - *
      - *

      - * - * Values in the Shared State and in RPC calls are converted between Java and - * JavaScript using the following conventions: - *

        - *
      • Primitive Java numbers (byte, char, int, long, float, double) and their - * boxed types (Byte, Character, Integer, Long, Float, Double) are represented - * by JavaScript numbers.
      • - *
      • The primitive Java boolean and the boxed Boolean are represented by - * JavaScript booleans.
      • - *
      • Java Strings are represented by JavaScript strings.
      • - *
      • List, Set and all arrays in Java are represented by JavaScript arrays.
      • - *
      • Map in Java is represented by JavaScript object with fields - * corresponding to the map keys.
      • - *
      • 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.
      • - *
      • A Java Bean is represented by a JavaScript object with fields - * corresponding to the bean's properties.
      • - *
      • A Java Connector is represented by a JavaScript string containing the - * connector's id.
      • - *
      • A pluggable serialization mechanism is provided for types not described - * here. Please refer to the documentation for specific types for serialization - * information.
      • - *
      - * - * @author Vaadin Ltd - * @version @VERSION@ - * @since 7.0.0 - */ -public abstract class AbstractJavaScriptComponent extends AbstractComponent { - private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( - this); - - @Override - protected void registerRpc(T implementation, Class 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 this). 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 wikipedia 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 wikipedia 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 getSources() { - ArrayList sources = new ArrayList(); - 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 Mozilla Developer Network 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 components = new LinkedList(); - - /* 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 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 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(); - } - - /** - *

      - * 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. - * - *

      - * Example how to distribute 1:3 (33%) for component1 and 2:3 (67%) for - * component2 : - * - * - * layout.setExpandRatio(component1, 1);
      - * layout.setExpandRatio(component2, 2); - *
      - * - *

      - * If no ratios have been set, the excess space is distributed evenly among - * all components. - * - *

      - * 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; - -/** - *

      - * 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}. - *

      - * - *

      - * A Select component may be in single- or multiselect mode. - * Multiselect mode means that more than one item can be selected - * simultaneously. - *

      - * - * @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 implements - Container, Container.Viewer, Container.PropertySetChangeListener, - Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier, - Container.ItemSetChangeListener, Vaadin6Component { - - public enum ItemCaptionMode { - /** - * Item caption mode: Item's ID's String representation is - * used as caption. - */ - ID, - /** - * Item caption mode: Item's String 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 String representation is used as caption. This - * is the default. - */ - 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 setItemCaptionPropertyId. - */ - 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. - * FILTERINGMODE_OFF (0) turns the filtering off. - * FILTERINGMODE_STARTSWITH (1) matches from the start of the - * caption. FILTERINGMODE_CONTAINS (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 itemIdMapper = new KeyMapper(); - - /** - * Item icons. - */ - private final HashMap itemIcons = new HashMap(); - - /** - * Item captions. - */ - private final HashMap itemCaptions = new HashMap(); - - /** - * 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 propertySetEventListeners = null; - - /** - * List of item set change event listeners. - */ - private Set itemSetEventListeners = null; - - /** - * Item id that represents null selection of this select. - * - *

      - * 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. - *

      - */ - 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 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 acceptedSelections = new LinkedList(); - 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(visibleNotSelected); - // Don't remove those that will be added to preserve order - visibleNotSelected.removeAll(acceptedSelections); - - @SuppressWarnings("unchecked") - Set newsel = (Set) getValue(); - if (newsel == null) { - newsel = new LinkedHashSet(); - } else { - newsel = new LinkedHashSet(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. getValue and - * setValue methods must be compatible with this type: one can - * safely cast getValue to given type and pass any variable - * assignable to this type as a parameter to setValue. - * - * @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(); - } - if (retValue instanceof Set) { - return Collections.unmodifiableSet((Set) retValue); - } else if (retValue instanceof Collection) { - return new HashSet((Collection) retValue); - } else { - final Set s = new HashSet(); - if (items.containsId(retValue)) { - s.add(retValue); - } - return s; - } - - } else { - return retValue; - } - } - - /** - * Sets the visible value of the property. - * - *

      - * 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * @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(), repaintIsNotNeeded); - } else if (Collection.class.isAssignableFrom(newValue.getClass())) { - super.setValue(new LinkedHashSet( - (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 s = new HashSet(); - 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 setItemCaptionMode() 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. - * - *

      - * The mode can be one of the following ones: - *

        - *
      • ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID : Items - * Id-objects toString is used as item caption. If caption is - * explicitly specified, it overrides the id-caption. - *
      • ITEM_CAPTION_MODE_ID : Items Id-objects - * toString is used as item caption.
      • - *
      • ITEM_CAPTION_MODE_ITEM : Item-objects - * toString is used as item caption.
      • - *
      • ITEM_CAPTION_MODE_INDEX : The index of the item is used - * as item caption. The index mode can only be used with the containers - * implementing Container.Indexed interface.
      • - *
      • ITEM_CAPTION_MODE_EXPLICIT : The item captions must be - * explicitly specified.
      • - *
      • ITEM_CAPTION_MODE_PROPERTY : The item captions are read - * from property, that must be specified with - * setItemCaptionPropertyId.
      • - *
      - * The ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID is the default - * mode. - *

      - * - * @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. - * - *

      - * The mode can be one of the following ones: - *

        - *
      • ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID : Items - * Id-objects toString is used as item caption. If caption is - * explicitly specified, it overrides the id-caption. - *
      • ITEM_CAPTION_MODE_ID : Items Id-objects - * toString is used as item caption.
      • - *
      • ITEM_CAPTION_MODE_ITEM : Item-objects - * toString is used as item caption.
      • - *
      • ITEM_CAPTION_MODE_INDEX : The index of the item is used - * as item caption. The index mode can only be used with the containers - * implementing Container.Indexed interface.
      • - *
      • ITEM_CAPTION_MODE_EXPLICIT : The item captions must be - * explicitly specified.
      • - *
      • ITEM_CAPTION_MODE_PROPERTY : The item captions are read - * from property, that must be specified with - * setItemCaptionPropertyId.
      • - *
      - * The ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID is the default - * mode. - *

      - * - * @return the One of the modes listed above. - */ - public ItemCaptionMode getItemCaptionMode() { - return itemCaptionMode; - } - - /** - * Sets the item caption property. - * - *

      - * Setting the id to a existing property implicitly sets the item caption - * mode to ITEM_CAPTION_MODE_PROPERTY. If the object is in - * ITEM_CAPTION_MODE_PROPERTY mode, setting caption property id - * null resets the item caption mode to - * ITEM_CAPTION_EXPLICIT_DEFAULTS_ID. - *

      - *

      - * Note that the type of the property used for caption must be String - *

      - *

      - * Setting the property id to null disables this feature. The id is null by - * default - *

      - * . - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * Note : The icons set with setItemIcon function override the - * icons from the property. - *

      - * - *

      - * Setting the property id to null disables this feature. The id is null by - * default - *

      - * . - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * Note : The icons set with setItemIcon function override the - * icons from the property. - *

      - * - *

      - * Setting the property id to null disables this feature. The id is null by - * default - *

      - * . - * - * @return the Id of the property containing the item icons. - */ - public Object getItemIconPropertyId() { - return itemIconPropertyId; - } - - /** - * Tests if an item is selected. - * - *

      - * In single select mode testing selection status of the item identified by - * {@link #getNullSelectionItemId()} returns true if the value of the - * property is null. - *

      - * - * @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. - * - *

      - * In single select mode selecting item identified by - * {@link #getNullSelectionItemId()} sets the value of the property to null. - *

      - * - * @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 s = new HashSet((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 s = new HashSet((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(); - } - 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(); - } - 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 setNullSelectionItemId(). 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. - * - *

      - * 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * @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 captionChangeNotifiers = new HashSet(); - - 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 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 itemIds = new HashSet(); - 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 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. - *

      - * 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. - * - * AbstractSplitPanel 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, - 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 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 true if locked, false 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 true if locked, false otherwise. - */ - public boolean isLocked() { - return getSplitterState().isLocked(); - } - - /** - * SplitterClickListener interface for listening for - * SplitterClickEvent fired by a SplitPanel. - * - * @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 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 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 getType() { - return String.class; - } - - /** - * Gets the null-string representation. - * - *

      - * 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. - *

      - * - *

      - * The default value is string 'null'. - *

      - * - * @return the String Textual representation for null strings. - * @see TextField#isNullSettingAllowed() - */ - public String getNullRepresentation() { - return nullRepresentation; - } - - /** - * Is setting nulls with null-string representation allowed. - * - *

      - * 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. - *

      - * - *

      - * By default this setting is false - *

      - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * The default value is string 'null' - *

      - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * By default this setting is false. - *

      - * - * @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 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. - *

      - * 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. - *

      - * 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. - *

      - * 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. - * - *

      - * 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 <audio> 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 Mozilla Developer Network. - * - * Multiple sources can be specified. Which of the sources is used is selected - * by the browser depending on which file formats it supports. See wikipedia 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.
      - * 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 - * true if caption is rendered as HTML, - * false otherwise - */ - public void setHtmlContentAllowed(boolean htmlContentAllowed) { - if (getState().isHtmlContentAllowed() != htmlContentAllowed) { - getState().setHtmlContentAllowed(htmlContentAllowed); - requestRepaint(); - } - } - - /** - * Return HTML rendering setting - * - * @return true if the caption text is to be rendered as HTML, - * false 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 { - - 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 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. - * - *

      - * 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 - * parent of the contained components. - *

      - * - *

      - * 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. - *

      - * - *

      - * A component becomes attached 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * @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. - * - *
      -     * Label label = new Label("This text has a lot of style");
      -     * label.setStyleName("myonestyle myotherstyle");
      -     * 
      - * - *

      - * 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: - *

      - * - *
      -     * .myonestyle {background: blue;}
      -     * 
      - * - *

      - * or - *

      - * - *
      -     * .v-button-myonestyle {background: blue;}
      -     * 
      - * - *

      - * 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. - *

      - * - *

      - * This method will trigger a {@link RepaintRequestEvent}. - *

      - * - * @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. - * - *
      -     * Label label = new Label("This text has style");
      -     * label.addStyleName("mystyle");
      -     * 
      - * - *

      - * 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: - *

      - * - *
      -     * .mystyle {font-style: italic;}
      -     * 
      - * - *

      - * or - *

      - * - *
      -     * .v-button-mystyle {font-style: italic;}
      -     * 
      - * - *

      - * This method will trigger a {@link RepaintRequestEvent}. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * * 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. - * - *

      - * As a security feature, all updates for disabled components are blocked on - * the server-side. - *

      - * - *

      - * 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. - *

      - * - * @return true if the component and its parent are enabled, - * false 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. - * - *
      -     * Button enabled = new Button("Enabled");
      -     * enabled.setEnabled(true); // The default
      -     * layout.addComponent(enabled);
      -     * 
      -     * Button disabled = new Button("Disabled");
      -     * disabled.setEnabled(false);
      -     * layout.addComponent(disabled);
      -     * 
      - * - *

      - * This method will trigger a {@link RepaintRequestEvent} for the component - * and, if it is a {@link ComponentContainer}, for all its children - * recursively. - *

      - * - * @param enabled - * a boolean value specifying if the component should be enabled - * or not - */ - public void setEnabled(boolean enabled); - - /** - * Tests the visibility property of the component. - * - *

      - * 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. - *

      - * - *

      - * 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. - *

      - * - * @return true if the component has been set to be visible in - * the user interface, false if not - * @see #setVisible(boolean) - * @see #attach() - */ - public boolean isVisible(); - - /** - * Sets the visibility of the component. - * - *

      - * 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. - *

      - * - *
      -     * TextField readonly = new TextField("Read-Only");
      -     * readonly.setValue("You can't see this!");
      -     * readonly.setVisible(false);
      -     * layout.addComponent(readonly);
      -     * 
      - * - *

      - * 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * @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. - * - *

      - * Notice that the read-only mode only affects whether the user can change - * the value of the component; it is possible to, for example, scroll - * a read-only table. - *

      - * - *

      - * The method will return {@code true} if the component or any of its - * parents is in the read-only mode. - *

      - * - * @return true if the component or any of its parents is in - * read-only mode, false 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. - * - *

      - * 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. - *

      - * - *

      - * Notice that the read-only mode only affects whether the user can change - * the value of the component; it is possible to, for example, scroll - * a read-only table. - *

      - * - *

      - * This method will trigger a {@link RepaintRequestEvent}. - *

      - * - * @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. - * - *

      - * See {@link #setCaption(String)} for a detailed description of the - * caption. - *

      - * - * @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. - * - *

      - * A caption is an explanatory textual label accompanying a user - * interface component, usually shown above, left of, or inside the - * component. Icon (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. - *

      - * - *

      - * The caption can usually also be given as the first parameter to a - * constructor, though some components do not support it. - *

      - * - *
      -     * RichTextArea area = new RichTextArea();
      -     * area.setCaption("You can edit stuff here");
      -     * area.setValue("<h1>Helpful Heading</h1>"
      -     *         + "<p>All this is for you to edit.</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. - *

      - * - *

      - * 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. - *

      - * - *

      - * This method will trigger a {@link RepaintRequestEvent}. A - * reimplementation should call the superclass implementation. - *

      - * - * @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. - * - *

      - * See {@link #setIcon(Resource)} for a detailed description of the icon. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - *

      - * The image is loaded by the browser from a resource, typically a - * {@link com.vaadin.terminal.ThemeResource}. - *

      - * - *
      -     * // Component with an icon from a custom theme
      -     * TextField name = new TextField("Name");
      -     * name.setIcon(new ThemeResource("icons/user.png"));
      -     * layout.addComponent(name);
      -     * 
      -     * // Component with an icon from another theme ('runo')
      -     * Button ok = new Button("OK");
      -     * ok.setIcon(new ThemeResource("../runo/icons/16/ok.png"));
      -     * layout.addComponent(ok);
      -     * 
      - * - *

      - * 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. - *

      - * - *

      - * 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} . - *

      - * - * 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. - * - *

      - * If the component is not attached to a Root through a component - * containment hierarchy, null is returned. - *

      - * - * @return the Root of the component or null if it is not - * attached to a Root - */ - @Override - public Root getRoot(); - - /** - * Gets the application object to which the component is attached. - * - *

      - * The method will return {@code null} if the component is not currently - * attached to an application. - *

      - * - *

      - * 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. - *

      - * - * @return the parent application of the component or null. - * @see #attach() - */ - public Application getApplication(); - - /** - * {@inheritDoc} - * - *

      - * 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: - *

      - * - *
      -     * public class AttachExample extends CustomComponent {
      -     *     public AttachExample() {
      -     *         // ERROR: We can't access the application object yet.
      -     *         ClassResource r = new ClassResource("smiley.jpg", getApplication());
      -     *         Embedded image = new Embedded("Image:", r);
      -     *         setCompositionRoot(image);
      -     *     }
      -     * }
      -     * 
      - * - *

      - * 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)}. - *

      - *

      - * This method must call {@link Root#componentAttached(Component)} to let - * the Root know that a new Component has been attached. - *

      - * - * - *
      -     * public class AttachExample extends CustomComponent {
      -     *     public AttachExample() {
      -     *     }
      -     * 
      -     *     @Override
      -     *     public void attach() {
      -     *         super.attach(); // Must call.
      -     * 
      -     *         // Now we know who ultimately owns us.
      -     *         ClassResource r = new ClassResource("smiley.jpg", getApplication());
      -     *         Embedded image = new Embedded("Image:", r);
      -     *         setCompositionRoot(image);
      -     *     }
      -     * }
      -     * 
      - */ - @Override - public void attach(); - - /** - * Gets the locale of the component. - * - *

      - * 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 Locale.getDefault(). - *

      - * - *

      - * 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. - *

      - * - * @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. - *

      - * This method must not alter the component hierarchy in any way. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - *
      -     * Button button = new Button("Click Me!");
      -     * button.addListener(new Button.ClickListener() {
      -     *     public void buttonClick(ClickEvent event) {
      -     *         getWindow().showNotification("Thank You!");
      -     *     }
      -     * });
      -     * layout.addComponent(button);
      -     * 
      - * - *

      - * 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. - *

      - * - * @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 Component.Events. - * - *

      - * 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. - *

      - * - *

      - * 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}. - *

      - * - *
      -     * 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("Say it all here");
      -     *         name.addListener(this);
      -     *         name.setImmediate(true);
      -     *         layout.addComponent(name);
      -     * 
      -     *         // Handle button clicks as generic events instead
      -     *         // of Button.ClickEvent events
      -     *         ok = new Button("OK");
      -     *         ok.addListener(this);
      -     *         layout.addComponent(ok);
      -     * 
      -     *         // For displaying information about an event
      -     *         status = new Label("");
      -     *         layout.addComponent(status);
      -     * 
      -     *         setCompositionRoot(layout);
      -     *     }
      -     * 
      -     *     public void componentEvent(Event event) {
      -     *         // Act according to the source of the event
      -     *         if (event.getSource() == ok
      -     *                 && event.getClass() == Button.ClickEvent.class)
      -     *             getWindow().showNotification("Click!");
      -     * 
      -     *         // Display source component and event class names
      -     *         status.setValue("Event from " + event.getSource().getClass().getName()
      -     *                 + ": " + event.getClass().getName());
      -     *     }
      -     * }
      -     * 
      -     * Listening listening = new Listening();
      -     * layout.addComponent(listening);
      -     * 
      - * - * @see Component#addListener(Listener) - */ - public interface Listener extends EventListener, Serializable { - - /** - * Notifies the listener of a component event. - * - *

      - * 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. - *

      - * - *
      -         * public void componentEvent(Event event) {
      -         *     // Act according to the source of the event
      -         *     if (event.getSource() == ok && event.getClass() == Button.ClickEvent.class)
      -         *         getWindow().showNotification("Click!");
      -         * 
      -         *     // Display source component and event class names
      -         *     status.setValue("Event from " + event.getSource().getClass().getName()
      -         *             + ": " + event.getClass().getName());
      -         * }
      -         * 
      - * - * @param event - * the event that has occured. - */ - public void componentEvent(Component.Event event); - } - - /** - * Registers a new (generic) component event listener for the component. - * - *
      -     * 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("Say it all here");
      -     *         name.addListener(this);
      -     *         name.setImmediate(true);
      -     *         layout.addComponent(name);
      -     * 
      -     *         // Handle button clicks as generic events instead
      -     *         // of Button.ClickEvent events
      -     *         ok = new Button("OK");
      -     *         ok.addListener(this);
      -     *         layout.addComponent(ok);
      -     * 
      -     *         // For displaying information about an event
      -     *         status = new Label("");
      -     *         layout.addComponent(status);
      -     * 
      -     *         setCompositionRoot(layout);
      -     *     }
      -     * 
      -     *     public void componentEvent(Event event) {
      -     *         // Act according to the source of the event
      -     *         if (event.getSource() == ok)
      -     *             getWindow().showNotification("Click!");
      -     * 
      -     *         status.setValue("Event from " + event.getSource().getClass().getName()
      -     *                 + ": " + event.getClass().getName());
      -     *     }
      -     * }
      -     * 
      -     * Listening listening = new Listening();
      -     * layout.addComponent(listening);
      -     * 
      - * - * @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. - * - *

      - * 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. - *

      - */ - @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 Component.Errorss. - */ - 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}. - * - *

      - * 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. - *

      - * - * @see FieldEvents - */ - public interface Focusable extends Component { - - /** - * Sets the focus to this component. - * - *
      -         * Form loginBox = new Form();
      -         * loginBox.setCaption("Login");
      -         * layout.addComponent(loginBox);
      -         * 
      -         * // Create the first field which will be focused
      -         * TextField username = new TextField("User name");
      -         * loginBox.addField("username", username);
      -         * 
      -         * // Set focus to the user name
      -         * username.focus();
      -         * 
      -         * TextField password = new TextField("Password");
      -         * loginBox.addField("password", password);
      -         * 
      -         * Button login = new Button("Login");
      -         * loginBox.getFooter().addComponent(login);
      -         * 
      - * - *

      - * 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. - *

      - * - * @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 tabulator index of the {@code Focusable} component. - * - * @return tab index set for the {@code Focusable} component - * @see #setTabIndex(int) - */ - public int getTabIndex(); - - /** - * Sets the tabulator index 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. - * - *
      -         * Form loginBox = new Form();
      -         * loginBox.setCaption("Login");
      -         * layout.addComponent(loginBox);
      -         * 
      -         * // Create the first field which will be focused
      -         * TextField username = new TextField("User name");
      -         * loginBox.addField("username", username);
      -         * 
      -         * // Set focus to the user name
      -         * username.focus();
      -         * 
      -         * TextField password = new TextField("Password");
      -         * loginBox.addField("password", password);
      -         * 
      -         * Button login = new Button("Login");
      -         * loginBox.getFooter().addComponent(login);
      -         * 
      -         * // An additional component which natural focus order would
      -         * // be after the button.
      -         * CheckBox remember = new CheckBox("Remember me");
      -         * loginBox.getFooter().addComponent(remember);
      -         * 
      -         * username.setTabIndex(1);
      -         * password.setTabIndex(2);
      -         * remember.setTabIndex(3); // Different than natural place
      -         * login.setTabIndex(4);
      -         * 
      - * - *

      - * 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. - *

      - * - *

      - * 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. - *

      - * - *

      - * 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - * - * @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 source. - * - * @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. - *

      - * 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. - *

      - *

      - * 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}. - *

      - * - * @author Vaadin Ltd - * @version @VERSION@ - * @since 7.0.0 - * - */ -public class ConnectorTracker implements Serializable { - - private final HashMap connectorIdToConnector = new HashMap(); - private Set dirtyConnectors = new HashSet(); - - 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. - *

      - * The lookup method {@link #getConnector(String)} only returns registered - * connectors. - *

      - * - * @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. - * - *

      - * The lookup method {@link #getConnector(String)} only returns registered - * connectors. - *

      - * - * @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 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. - *

      - * The state and pending RPC calls for dirty connectors are sent to the - * client in the following request. - *

      - * - * @return A collection of all dirty connectors for this root. This list may - * contain invisible connectors. - */ - public Collection 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. - *

      - * In comparison to {@link HorizontalLayout} and {@link VerticalLayout} - *

        - *
      • rather similar server side api - *
      • no spacing, alignment or expand ratios - *
      • much simpler DOM that can be styled by skilled web developer - *
      • no abstraction of browser differences (developer must ensure that the - * result works properly on each browser) - *
      • different kind of handling for relative sizes (that are set from server - * side) (*) - *
      • noticeably faster rendering time in some situations as we rely more on - * the browser's rendering engine. - *
      - *

      - * 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. - *

      - * By extending CssLayout one can also inject some css rules straight to child - * components using {@link #getCss(Component)}. - * - *

      - * (*) 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. - *

      - * 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 components = new LinkedList(); - - 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 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 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. - * - *

      - * Note that styles are injected over previous styles before actual child - * rendering. Previous styles are not cleared, but overridden. - * - *

      - * 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 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. - *

      - * 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. - *

      - * - * @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. - * - *

      - * 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. - *

      - */ - public CustomComponent() { - // expand horizontally by default - setWidth(100, UNITS_PERCENTAGE); - } - - /** - * Constructs a new custom component. - * - *

      - * 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. - *

      - * - * @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. - *

      - * The composition root must be set to non-null value before the component - * can be used. The composition root can only be set once. - *

      - * - * @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, - 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 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 - * field value type - * - * @since 7.0 - */ -public abstract class CustomField extends AbstractField implements - ComponentContainer { - - /** - * The root component implementing the custom component. - */ - private Component root = null; - - /** - * Constructs a new custom field. - * - *

      - * 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. - *

      - */ - 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, - 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 getComponentIterator() { - return new ComponentIterator(); - } - - @Override - public Iterator 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; - -/** - *

      - * 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. - *

      - * - *

      - * 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. - *

      - * - *

      - * The default theme handles the styles that are not defined by drawing the - * subcomponents just as in OrderedLayout. - *

      - * - * @author Vaadin Ltd. - * @author Duy B. Vo (devduy@gmail.com) - * @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 slots = new HashMap(); - - /** - * 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("