Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

AbstractExtension.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright 2000-2018 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.server;
  17. /**
  18. * An extension is an entity that is attached to a Component or another
  19. * Extension and independently communicates between client and server.
  20. * <p>
  21. * Extensions can use shared state and RPC in the same way as components.
  22. * <p>
  23. * AbstractExtension adds a mechanism for adding the extension to any Connector
  24. * (extend). To let the Extension determine what kind target it can be added to,
  25. * the extend method is declared as protected.
  26. *
  27. * @author Vaadin Ltd
  28. * @since 7.0.0
  29. */
  30. public abstract class AbstractExtension extends AbstractClientConnector
  31. implements Extension {
  32. private boolean previouslyAttached = false;
  33. private ClientConnector parent;
  34. /**
  35. * Creates a new extension instance without extending any connector.
  36. */
  37. public AbstractExtension() {
  38. // Empty default constructor
  39. }
  40. /**
  41. * Creates a new extension instance that extends the provided connector.
  42. *
  43. * @since 7.4
  44. *
  45. * @param target
  46. * the connector to extend
  47. */
  48. public AbstractExtension(AbstractClientConnector target) {
  49. this();
  50. extend(target);
  51. }
  52. /**
  53. * Gets a type that the parent must be an instance of. Override this if the
  54. * extension only support certain targets, e.g. if only TextFields can be
  55. * extended.
  56. *
  57. * @return a type that the parent must be an instance of
  58. */
  59. protected Class<? extends ClientConnector> getSupportedParentType() {
  60. return ClientConnector.class;
  61. }
  62. /**
  63. * Add this extension to the target connector. This method is protected to
  64. * allow subclasses to require a more specific type of target.
  65. *
  66. * @param target
  67. * the connector to attach this extension to
  68. */
  69. protected void extend(AbstractClientConnector target) {
  70. target.addExtension(this);
  71. }
  72. @Override
  73. public void remove() {
  74. getParent().removeExtension(this);
  75. }
  76. @Override
  77. public void setParent(ClientConnector parent) {
  78. if (previouslyAttached && parent != null) {
  79. throw new IllegalStateException(
  80. "An extension can not be set to extend a new target after getting detached from the previous.");
  81. }
  82. Class<? extends ClientConnector> supportedParentType = getSupportedParentType();
  83. if (parent == null || supportedParentType.isInstance(parent)) {
  84. internalSetParent(parent);
  85. previouslyAttached = true;
  86. } else {
  87. throw new IllegalArgumentException(getClass().getName()
  88. + " can only be attached to targets of type "
  89. + supportedParentType.getName() + " but attach to "
  90. + parent.getClass().getName() + " was attempted.");
  91. }
  92. }
  93. /**
  94. * Actually sets the parent and calls required listeners.
  95. *
  96. * @since 7.1
  97. * @param parent
  98. * The parent to set
  99. */
  100. private void internalSetParent(ClientConnector parent) {
  101. ClientConnector oldParent = getParent();
  102. // Send a detach event if the component is currently attached
  103. if (isAttached()) {
  104. detach();
  105. }
  106. // Connect to new parent
  107. this.parent = parent;
  108. // Send attach event if the component is now attached
  109. if (isAttached()) {
  110. attach();
  111. }
  112. if (oldParent != null) {
  113. oldParent.markAsDirty();
  114. }
  115. }
  116. @Override
  117. public ClientConnector getParent() {
  118. return parent;
  119. }
  120. }