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