View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.view.facelets.el;
20  
21  import java.io.Externalizable;
22  import java.io.IOException;
23  import java.io.ObjectInput;
24  import java.io.ObjectOutput;
25  
26  import javax.el.ELContext;
27  import javax.el.ValueExpression;
28  import javax.faces.FacesWrapper;
29  import javax.faces.context.FacesContext;
30  import javax.faces.view.Location;
31  
32  /**
33   * A ValueExpression that contains the original ValueExpression and
34   * the Location of the facelet file from which the ValueExpression was
35   * created. This is needed when the current composite component (cc) 
36   * has to be resolved by the ValueExpression, because #{cc} refers to the
37   * composite component which is implemented in the file the ValueExpression
38   * comes from and not the one currently on top of the composite component stack.
39   * 
40   * This ValueExpression implementation passes through all methods to the delegate
41   * ValueExpression, but saves the related composite component in a FacesContext attribute 
42   * before the invocation of the method on the delegate and removes it afterwards. 
43   * 
44   * @author Jakob Korherr (latest modification by $Author$)
45   * @version $Revision$ $Date$
46   */
47  public class LocationValueExpression extends ValueExpression
48      implements FacesWrapper<ValueExpression>, Externalizable
49  {
50      
51      private static final long serialVersionUID = -5636849184764526288L;
52      
53      // location and delegate need to be available in LocationValueExpressionUEL
54      Location location;
55      ValueExpression delegate;
56      int ccLevel;
57      
58      public LocationValueExpression()
59      {
60          super();
61      }
62      
63      public LocationValueExpression(Location location, ValueExpression delegate)
64      {
65          this.location = location;
66          this.delegate = delegate;
67          this.ccLevel = 0;
68      }
69  
70      public LocationValueExpression(Location location, ValueExpression delegate, int ccLevel)
71      {
72          this.location = location;
73          this.delegate = delegate;
74          this.ccLevel = ccLevel;
75      }
76      
77      public Location getLocation()
78      {
79          return location;
80      }
81      
82      public int getCCLevel()
83      {
84          return ccLevel;
85      }
86      
87      public LocationValueExpression apply(int newCCLevel)
88      {
89          if(this.ccLevel == newCCLevel)
90          {
91              return this;
92          }
93          else
94          {
95              return new LocationValueExpression(this.location, this.delegate, newCCLevel);
96          }
97      }
98      
99      public LocationValueExpression apply(int newCCLevel, Location newLocation)
100     {
101         if(this.ccLevel == newCCLevel && this.location.getPath().equals(newLocation.getPath()))
102         {
103             return this;
104         }
105         else
106         {
107             return new LocationValueExpression(newLocation, this.delegate, newCCLevel);
108         }
109     }
110     
111     @Override
112     public Class<?> getExpectedType()
113     {
114         return delegate.getExpectedType();
115     }
116 
117     @Override
118     public Class<?> getType(ELContext context)
119     {
120         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
121         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
122         try
123         {
124             return delegate.getType(context);
125         }
126         finally
127         {
128             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
129         }
130     }
131 
132     @Override
133     public Object getValue(ELContext context)
134     {
135         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
136         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
137         try
138         {
139             return delegate.getValue(context);
140         }
141         finally
142         {
143             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
144         }
145     }
146 
147     @Override
148     public boolean isReadOnly(ELContext context)
149     {
150         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
151         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
152         try
153         {
154             return delegate.isReadOnly(context);
155         }
156         finally
157         {
158             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
159         }
160     }
161 
162     @Override
163     public void setValue(ELContext context, Object value)
164     {
165         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
166         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
167         try
168         {
169             delegate.setValue(context, value);
170         }
171         finally
172         {
173             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
174         }
175     }
176 
177     @Override
178     public boolean equals(Object obj)
179     {
180         return delegate.equals(obj);
181     }
182 
183     @Override
184     public String getExpressionString()
185     {
186         return delegate.getExpressionString();
187     }
188 
189     @Override
190     public int hashCode()
191     {
192         return delegate.hashCode();
193     }
194 
195     @Override
196     public boolean isLiteralText()
197     {
198         return delegate.isLiteralText();
199     }
200 
201     public ValueExpression getWrapped()
202     {
203         return delegate;
204     }
205     
206     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
207     {
208         this.delegate = (ValueExpression) in.readObject();
209         this.location = (Location) in.readObject();
210         this.ccLevel = in.readInt();
211     }
212 
213     public void writeExternal(ObjectOutput out) throws IOException
214     {
215         out.writeObject(this.delegate);
216         out.writeObject(this.location);
217         out.writeInt(this.ccLevel);
218     }
219 }