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.MethodExpression;
28  import javax.el.MethodInfo;
29  import javax.el.ValueExpression;
30  import javax.faces.FacesWrapper;
31  import javax.faces.context.FacesContext;
32  import javax.faces.view.Location;
33  
34  /**
35   * A MethodExpression that contains the original MethodExpression and
36   * the Location of the facelet file from which the MethodExpression was
37   * created. This is needed when the current composite component (cc) 
38   * has to be resolved by the MethodExpression, because #{cc} refers to the
39   * composite component which is implemented in the file the MethodExpression
40   * comes from and not the one currently on top of the composite component stack.
41   * 
42   * This MethodExpression implementation passes through all methods to the delegate
43   * MethodExpression, but saves the related composite component in a FacesContext attribute 
44   * before the invocation of the method on the delegate and removes it afterwards.
45   * 
46   * @author Jakob Korherr (latest modification by $Author: lu4242 $)
47   * @version $Revision: 1351627 $ $Date: 2012-06-19 04:50:21 -0500 (Tue, 19 Jun 2012) $
48   */
49  public class LocationMethodExpression extends MethodExpression 
50      implements FacesWrapper<MethodExpression>, Externalizable, LocationAware
51  {
52  
53      private static final long serialVersionUID = 1634644578979226893L;
54      
55      private Location location;
56      private MethodExpression delegate;
57      int ccLevel;
58      
59      public LocationMethodExpression()
60      {
61          super();
62      }
63      
64      public LocationMethodExpression(Location location, MethodExpression delegate)
65      {
66          this.location = location;
67          this.delegate = delegate;
68          this.ccLevel = 0;
69      }
70  
71      public LocationMethodExpression(Location location, MethodExpression 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 LocationMethodExpression apply(int newCCLevel)
84      {
85          if(this.ccLevel == newCCLevel)
86          {
87              return this;
88          }
89          else
90          {
91              return new LocationMethodExpression(this.location, this.delegate, newCCLevel);
92          }
93      }
94      
95      @Override
96      public MethodInfo getMethodInfo(ELContext context)
97      {
98          FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
99          CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
100         try
101         {
102             return delegate.getMethodInfo(context);
103         }
104         finally
105         {
106             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
107         }
108     }
109 
110     @Override
111     public Object invoke(ELContext context, Object[] params)
112     {
113         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
114         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
115         try
116         {
117             return delegate.invoke(context, params);
118         }
119         finally
120         {
121             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
122         }
123     }
124 
125     @Override
126     public boolean equals(Object obj)
127     {
128         return delegate.equals(obj);
129     }
130 
131     @Override
132     public String getExpressionString()
133     {
134         return delegate.getExpressionString();
135     }
136 
137     @Override
138     public int hashCode()
139     {
140         return delegate.hashCode();
141     }
142 
143     @Override
144     public boolean isLiteralText()
145     {
146         return delegate.isLiteralText();
147     }
148 
149     public MethodExpression getWrapped()
150     {
151         return delegate;
152     }
153     
154     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
155     {
156         this.delegate = (MethodExpression) in.readObject();
157         this.location = (Location) in.readObject();
158         this.ccLevel = in.readInt();
159     }
160 
161     public void writeExternal(ObjectOutput out) throws IOException
162     {
163         out.writeObject(this.delegate);
164         out.writeObject(this.location);
165         out.writeInt(this.ccLevel);
166     }
167 
168 }