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