View Javadoc

1   // Copyright 2006 Daniel Gredler
2   //
3   // Licensed under the Apache License, Version 2.0 (the "License");
4   // you may not use this file except in compliance with the License.
5   // You may obtain a copy of the License at
6   //
7   //     http://www.apache.org/licenses/LICENSE-2.0
8   //
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  
15  package net.sf.beanform.binding;
16  
17  import java.util.Map;
18  import java.util.Map.Entry;
19  
20  import org.apache.hivemind.Location;
21  import org.apache.tapestry.IBinding;
22  import org.apache.tapestry.IComponent;
23  
24  /***
25   * A special binding type that allows us to simulate adding and removing
26   * bindings to components. This binding behaves like a custom binding unless
27   * there is no custom binding, in which case it behaves like the standard
28   * (default) binding for a given binding name.
29   *
30   * @author Daniel Gredler
31   */
32  public class DualBinding implements IBinding {
33  
34      private IBinding custom;
35      private IBinding standard;
36  
37      public DualBinding( IBinding custom, IBinding standard ) {
38          this.custom = custom;
39          this.standard = standard;
40      }
41  
42      public void setCustom( IBinding custom ) {
43          this.custom = custom;
44      }
45  
46      public Object getObject() {
47          if( this.custom != null ) return this.custom.getObject();
48          else if( this.standard != null ) return this.standard.getObject();
49          else return null;
50      }
51  
52      public Object getObject( Class type ) {
53          if( this.custom != null ) return this.custom.getObject( type );
54          else if( this.standard != null ) return this.standard.getObject( type );
55          else return null;
56      }
57  
58      public boolean isInvariant() {
59          return false;
60      }
61  
62      public void setObject( Object value ) {
63          if( this.custom != null ) this.custom.setObject( value );
64          else if( this.standard != null ) this.standard.setObject( value );
65      }
66  
67      public String getDescription() {
68          if( this.custom != null ) return this.custom.getDescription();
69          else if( this.standard != null ) return this.standard.getDescription();
70          else return null;
71      }
72  
73      public Location getLocation() {
74          if( this.custom != null ) return this.custom.getLocation();
75          else if( this.standard != null ) return this.standard.getLocation();
76          else return null;
77      }
78  
79      /***
80       * Adds temporary custom bindings to a component by overriding the existing bindings
81       * with {@link DualBinding} instances whose behavior can later be reverted.
82       */
83      public static void addCustomBindings( IComponent component, Map<String, IBinding> bindings, boolean clearFirst ) {
84          if( clearFirst ) {
85              DualBinding.removeCustomBindings( component );
86          }
87          for( Entry<String, IBinding> entry : bindings.entrySet() ) {
88              String bindingName = entry.getKey();
89              IBinding custom = entry.getValue();
90              IBinding existing = component.getBinding( bindingName );
91              DualBinding dual;
92              if( existing instanceof DualBinding ) {
93                  dual = (DualBinding) existing;
94                  dual.setCustom( custom );
95              }
96              else {
97                  dual = new DualBinding( custom, existing );
98              }
99              component.setBinding( bindingName, dual );
100         }
101     }
102 
103     /***
104      * Reverts the behavior of the specified component's temporarily customized bindings to
105      * whatever it was prior to customization.
106      */
107     @SuppressWarnings( "unchecked" )
108     public static void removeCustomBindings( IComponent component ) {
109         Map<String, IBinding> bindings = component.getBindings();
110         for( IBinding binding : bindings.values() ) {
111             if( binding instanceof DualBinding ) {
112                 DualBinding dual = (DualBinding) binding;
113                 dual.setCustom( null );
114             }
115         }
116     }
117 
118 }