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: lu4242 $)
46   * @version $Revision: 1351625 $ $Date: 2012-06-19 04:48:54 -0500 (Tue, 19 Jun 2012) $
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      @Override
95      public MethodInfo getMethodInfo(ELContext context)
96      {
97          FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
98          CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
99          try
100         {
101             return delegate.getMethodInfo(context);
102         }
103         finally
104         {
105             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
106         }
107     }
108 
109     @Override
110     public Object invoke(ELContext context, Object[] params)
111     {
112         FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
113         CompositeComponentELUtils.saveCompositeComponentForResolver(facesContext, location, ccLevel);
114         try
115         {
116             return delegate.invoke(context, params);
117         }
118         finally
119         {
120             CompositeComponentELUtils.removeCompositeComponentForResolver(facesContext);
121         }
122     }
123 
124     @Override
125     public boolean equals(Object obj)
126     {
127         return delegate.equals(obj);
128     }
129 
130     @Override
131     public String getExpressionString()
132     {
133         return delegate.getExpressionString();
134     }
135 
136     @Override
137     public int hashCode()
138     {
139         return delegate.hashCode();
140     }
141 
142     @Override
143     public boolean isLiteralText()
144     {
145         return delegate.isLiteralText();
146     }
147 
148     public MethodExpression getWrapped()
149     {
150         return delegate;
151     }
152     
153     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
154     {
155         this.delegate = (MethodExpression) in.readObject();
156         this.location = (Location) in.readObject();
157         this.ccLevel = in.readInt();
158     }
159 
160     public void writeExternal(ObjectOutput out) throws IOException
161     {
162         out.writeObject(this.delegate);
163         out.writeObject(this.location);
164         out.writeInt(this.ccLevel);
165     }
166 
167 }