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.shared.resource;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.PushbackInputStream;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.logging.Level;
27  import java.util.logging.Logger;
28  
29  import javax.el.ELContext;
30  import javax.el.ELException;
31  import javax.el.ValueExpression;
32  import javax.faces.application.Resource;
33  import javax.faces.context.FacesContext;
34  import javax.faces.event.ExceptionQueuedEvent;
35  import javax.faces.event.ExceptionQueuedEventContext;
36  
37  import org.apache.myfaces.shared.util.io.DynamicPushbackInputStream;
38  
39  public class ValueExpressionFilterInputStream extends InputStream
40  {
41      private PushbackInputStream delegate;
42      private String libraryName;
43      private String resourceName;
44      private String contractName;
45      
46      public ValueExpressionFilterInputStream(InputStream in, String libraryName, String resourceName)
47      {
48          super();
49          delegate = new DynamicPushbackInputStream(in,300);
50          this.libraryName = libraryName;
51          this.resourceName = resourceName;
52          this.contractName = null;
53      }
54      
55      public ValueExpressionFilterInputStream(InputStream in, Resource resource)
56      {
57          super();
58          delegate = new DynamicPushbackInputStream(in,300);
59          this.libraryName = resource.getLibraryName();
60          this.resourceName = resource.getResourceName();
61          this.contractName = (resource instanceof ContractResource) ? 
62                  ((ContractResource)resource).getContractName() : null;
63      }
64  
65      @Override
66      public int read() throws IOException
67      {
68          int c1 = delegate.read();
69          
70          if (c1 == -1)
71          {
72              return -1;
73          }
74          
75          if ( ((char)c1) == '#')
76          {
77              int c2 = delegate.read();
78              if (c2 == -1)
79              {
80                  return -1;
81              }
82              if (((char)c2) == '{')
83              {
84                  //It is a value expression. We need
85                  //to look for a occurrence of } to 
86                  //extract the expression and evaluate it,
87                  //the result should be unread.
88                  List<Integer> expressionList = new ArrayList<Integer>();
89                  int c3 = delegate.read();
90                  while ( c3 != -1 && ((char)c3) != '}' )
91                  {
92                      expressionList.add(c3);
93                      c3 = delegate.read();
94                  }
95                  
96                  if (c3 == -1)
97                  {
98                      //get back the data, because we can't
99                      //extract any value expression
100                     for (int i = 0; i < expressionList.size(); i++)
101                     {
102                         delegate.unread(expressionList.get(i));
103                     }
104                     delegate.unread(c2);
105                     return c1;
106                 }
107                 else
108                 {
109                     //EL expression found. Evaluate it and pushback
110                     //the result into the stream
111                     FacesContext context = FacesContext.getCurrentInstance();
112                     ELContext elContext = context.getELContext();
113                     try
114                     {
115                         if (libraryName != null)
116                         {
117                             ResourceELUtils.saveResourceLibraryForResolver(context, libraryName);
118                         }
119                         if (contractName != null)
120                         {
121                             ResourceELUtils.saveResourceContractForResolver(context, contractName);
122                         }
123                         ValueExpression ve = context.getApplication().
124                             getExpressionFactory().createValueExpression(
125                                     elContext,
126                                     "#{"+convertToExpression(expressionList)+"}",
127                                     String.class);
128                         String value = (String) ve.getValue(elContext);
129                         
130                         for (int i = value.length()-1; i >= 0 ; i--)
131                         {
132                             delegate.unread((int) value.charAt(i));
133                         }
134                     }
135                     catch(ELException e)
136                     {
137                         ExceptionQueuedEventContext equecontext = new ExceptionQueuedEventContext (
138                                 context, e, null);
139                         context.getApplication().publishEvent (context, ExceptionQueuedEvent.class, equecontext);
140                         
141                         Logger log = Logger.getLogger(ResourceImpl.class.getName());
142                         if (log.isLoggable(Level.SEVERE))
143                         {
144                             log.severe("Cannot evaluate EL expression " + convertToExpression(expressionList)
145                                     + " in resource " + (libraryName == null?"":libraryName) + ":" + 
146                                     (resourceName == null?"":resourceName));
147                         }
148                         
149                         delegate.unread(c3);
150                         for (int i = expressionList.size()-1; i >= 0; i--)
151                         {
152                             delegate.unread(expressionList.get(i));
153                         }
154                         delegate.unread(c2);
155                         return c1;
156                     }
157                     finally
158                     {
159                         if (libraryName != null)
160                         {
161                             ResourceELUtils.removeResourceLibraryForResolver(context);
162                         }
163                         if (contractName != null)
164                         {
165                             ResourceELUtils.removeResourceContractForResolver(context);
166                         }
167                     }
168                     
169                     //read again
170                     return delegate.read();
171                 }
172             }
173             else
174             {
175                 delegate.unread(c2);
176                 return c1;
177             }
178         }
179         else
180         {
181             //just continue
182             return c1;
183         }
184     }
185     
186     private String convertToExpression(List<Integer> expressionList)
187     {
188         char[] exprArray = new char[expressionList.size()];
189         
190         for (int i = 0; i < expressionList.size(); i++)
191         {
192             exprArray[i] = (char) expressionList.get(i).intValue();
193         }
194         return String.valueOf(exprArray);
195     }
196 
197     @Override
198     public void close() throws IOException
199     {
200         delegate.close();
201     }
202 }