View Javadoc

1   package org.apache.maven.jelly;
2   
3   /* ====================================================================
4    *   Licensed to the Apache Software Foundation (ASF) under one or more
5    *   contributor license agreements.  See the NOTICE file distributed with
6    *   this work for additional information regarding copyright ownership.
7    *   The ASF licenses this file to You under the Apache License, Version 2.0
8    *   (the "License"); you may not use this file except in compliance with
9    *   the License.  You may obtain a copy of the License at
10   *
11   *       http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *   Unless required by applicable law or agreed to in writing, software
14   *   distributed under the License is distributed on an "AS IS" BASIS,
15   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *   See the License for the specific language governing permissions and
17   *   limitations under the License.
18   * ====================================================================
19   */
20  
21  import org.apache.commons.jelly.JellyContext;
22  import org.apache.commons.jelly.JellyException;
23  import org.apache.commons.jelly.expression.Expression;
24  import org.apache.commons.jelly.expression.ExpressionFactory;
25  import org.apache.commons.jelly.expression.ExpressionSupport;
26  import org.apache.commons.jelly.expression.jexl.JexlExpression;
27  
28  /**
29   * Represents a factory of <a href="http://commons.apache.org/jexl/">
30   * Jexl</a> expression which fully supports the Expression Language in JSTL and
31   * JSP. In addition this ExpressionFactory can also support Ant style variable
32   * names, where '.' is used inside variable names.
33   *
34   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
35   * @version $Revision: 517014 $
36   */
37  
38  public class MavenExpressionFactory
39      implements ExpressionFactory
40  {
41      // ----------------------------------------------------------------------
42      //     Instance members
43      // ----------------------------------------------------------------------
44  
45      /**
46       * whether we should allow Ant-style expresssions, using dots as part of
47       * variable name
48       */
49      private boolean supportAntVariables = true;
50  
51      /** @see ExpressionFactory
52       */
53      public Expression createExpression( final String text )
54          throws JellyException
55      {
56          Expression expression = null;
57          try
58          {
59              expression = new JexlExpression( org.apache.commons.jexl.ExpressionFactory.createExpression( text ) );
60          }
61          catch ( Exception anException )
62          {
63              throw new JellyException( "error evaluating expression", anException );
64          }
65  
66          final Expression jexlExpression = expression;
67  
68          if ( isSupportAntVariables() && isValidAntVariableName( text ) )
69          {
70              ExpressionSupport expr = new ExpressionSupport()
71              {
72                  public Object evaluate( JellyContext context )
73                  {
74                      Object answer = jexlExpression.evaluate( context );
75  
76                      if ( answer == null )
77                      {
78                          answer = context.getVariable( text );
79  
80                          if ( answer instanceof String )
81                          {
82                              return JellyUtils.decomposeExpression( (String) answer, context );
83                          }
84                      }
85  
86                      return answer;
87                  }
88  
89                  public String getExpressionText()
90                  {
91                      return text;
92                  }
93  
94                  public String toString()
95                  {
96                      return super.toString() + "[expression:" + text + "]";
97                  }
98              };
99  
100             return expr;
101         }
102 
103         return jexlExpression;
104     }
105 
106     // Properties
107     //-------------------------------------------------------------------------
108 
109     /**
110      * @return whether we should allow Ant-style expresssions, using dots as
111      *      part of variable name
112      */
113     public boolean isSupportAntVariables()
114     {
115         return supportAntVariables;
116     }
117 
118     /**
119      * Sets whether we should allow Ant-style expresssions, using dots as part
120      * of variable name
121      *
122      * @param supportAntVariables <code>true</code> to indicate that ant variable
123      *        should be supported, otherwise <code>false</code>.
124      */
125     public void setSupportAntVariables( boolean supportAntVariables )
126     {
127         this.supportAntVariables = supportAntVariables;
128     }
129 
130     // Implementation methods
131     //-------------------------------------------------------------------------
132 
133     /** Determine if a variable name is a valid ant variable name.
134      *
135      * @param text The text to test.
136      *
137      * @return true if the given string is a valid Ant variable name, typically
138      *      thats alphanumeric text with '.' etc.
139      */
140     protected boolean isValidAntVariableName( String text )
141     {
142         char[] chars = text.toCharArray();
143         for ( int i = 0, size = chars.length; i < size; i++ )
144         {
145             char ch = chars[i];
146             // could maybe be a bit more restrictive...
147             if ( Character.isWhitespace( ch ) || ( ch == '[' ) )
148             {
149                 return false;
150             }
151         }
152         return true;
153     }
154 
155 }