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.el.ValueReference;
29  import javax.faces.FacesWrapper;
30  import javax.faces.context.FacesContext;
31  import javax.faces.view.Location;
32  
33  /**
34   * A ValueExpression that contains the original ValueExpression and
35   * the Location of the facelet file from which the ValueExpression was
36   * created. This is needed when the current composite component (cc) 
37   * has to be resolved by the ValueExpression, because #{cc} refers to the
38   * composite component which is implemented in the file the ValueExpression
39   * comes from and not the one currently on top of the composite component stack.
40   * 
41   * This ValueExpression implementation passes through all methods to the delegate
42   * ValueExpression, but saves the related composite component in a FacesContext attribute 
43   * before the invocation of the method on the delegate and removes it afterwards. 
44   * 
45   * @author Jakob Korherr (latest modification by $Author$)
46   * @version $Revision$ $Date$
47   */
48  public class LocationValueExpression extends ValueExpression
49      implements FacesWrapper<ValueExpression>, Externalizable
50  {
51      
52      private static final long serialVersionUID = -5636849184764526288L;
53      
54      // location and delegate need to be available in LocationValueExpressionUEL
55      Location location;
56      ValueExpression delegate;
57      int ccLevel;
58      
59      public LocationValueExpression()
60      {
61          super();
62      }
63      
64      public LocationValueExpression(Location location, ValueExpression delegate)
65      {
66          this.location = location;
67          this.delegate = delegate;
68          this.ccLevel = 0;
69      }
70  
71      public LocationValueExpression(Location location, ValueExpression delegate, int ccLevel)
72      {
73          this.location = location;
74          this.delegate = delegate;
75          this.ccLevel = ccLevel;
76      }
77      
78      public Location getLocation()
79      {
80          return location;
81      }
82      
83      public int getCCLevel()
84      {
85          return ccLevel;
86      }
87      
88      public LocationValueExpression apply(int newCCLevel)
89      {
90          if(this.ccLevel == newCCLevel)
91          {
92              return this;
93          }
94          else
95          {
96              return new LocationValueExpression(this.location, this.delegate, newCCLevel);
97          }
98      }
99      
100     public LocationValueExpression apply(int newCCLevel, Location newLocation)
101     {
102         if(this.ccLevel == newCCLevel && this.location.getPath().equals(newLocation.getPath()))
103         {
104             return this;
105         }
106         else
107         {
108             return new LocationValueExpression(newLocation, this.delegate, newCCLevel);
109         }
110     }
111         
112     @Override
113     public Class<?> getExpectedType()
114     {
115         return delegate.getExpectedType();
116     }
117 
118     @Override
119     public Class<?> getType(ELContext context)
120     {
121         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
122         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
123         try
124         {
125             return delegate.getType(context);
126         }
127         finally
128         {
129             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
130         }
131     }
132 
133     @Override
134     public Object getValue(ELContext context)
135     {
136         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
137         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
138         try
139         {
140             return delegate.getValue(context);
141         }
142         finally
143         {
144             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
145         }
146     }
147 
148     @Override
149     public boolean isReadOnly(ELContext context)
150     {
151         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
152         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
153         try
154         {
155             return delegate.isReadOnly(context);
156         }
157         finally
158         {
159             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
160         }
161     }
162 
163     @Override
164     public void setValue(ELContext context, Object value)
165     {
166         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
167         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
168         try
169         {
170             delegate.setValue(context, value);
171         }
172         finally
173         {
174             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
175         }
176     }
177 
178     @Override
179     public boolean equals(Object obj)
180     {
181         return delegate.equals(obj);
182     }
183 
184     @Override
185     public String getExpressionString()
186     {
187         return delegate.getExpressionString();
188     }
189 
190     @Override
191     public int hashCode()
192     {
193         return delegate.hashCode();
194     }
195 
196     @Override
197     public boolean isLiteralText()
198     {
199         return delegate.isLiteralText();
200     }
201 
202     @Override
203     public ValueExpression getWrapped()
204     {
205         return delegate;
206     }
207     
208     @Override
209     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
210     {
211         this.delegate = (ValueExpression) in.readObject();
212         this.location = (Location) in.readObject();
213         this.ccLevel = in.readInt();
214     }
215 
216     @Override
217     public void writeExternal(ObjectOutput out) throws IOException
218     {
219         out.writeObject(this.delegate);
220         out.writeObject(this.location);
221         out.writeInt(this.ccLevel);
222     }
223         
224     @Override
225     public ValueReference getValueReference(ELContext context)
226     {
227         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
228         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
229         try
230         {
231             return delegate.getValueReference(context);
232         }
233         finally
234         {
235             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
236         }
237     }
238 }