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