View Javadoc

1   package org.apache.commons.ognl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collection;
23  import java.util.Map;
24  import java.util.Set;
25  
26  /**
27   * Implementation of PropertyAccessor that sets and gets properties by storing and looking up values in Maps.
28   *
29   * $Id: MapPropertyAccessor.java 1198666 2011-11-07 09:17:15Z mcucchiara $
30   * @author Luke Blanshard (blanshlu@netscape.net)
31   * @author Drew Davidson (drew@ognl.org)
32   */
33  public class MapPropertyAccessor
34      implements PropertyAccessor
35  {
36  
37      public Object getProperty( Map<String, Object> context, Object target, Object name )
38          throws OgnlException
39      {
40          Object result;
41          @SuppressWarnings( "unchecked" ) // checked by the invoker
42              Map<Object, Object> map = (Map<Object, Object>) target;
43          Node currentNode = ( (OgnlContext) context ).getCurrentNode().jjtGetParent();
44          boolean indexedAccess = false;
45  
46          if ( currentNode == null )
47          {
48              throw new OgnlException( "node is null for '" + name + "'" );
49          }
50          if ( !( currentNode instanceof ASTProperty ) )
51          {
52              currentNode = currentNode.jjtGetParent();
53          }
54          if ( currentNode instanceof ASTProperty )
55          {
56              indexedAccess = ( (ASTProperty) currentNode ).isIndexedAccess();
57          }
58  
59          if ( ( name instanceof String ) && !indexedAccess )
60          {
61              if ( "size".equals( name ) )
62              {
63                  result = map.size();
64              }
65              else if ( "keys".equals( name ) || "keySet".equals( name ) )
66              {
67                  result = map.keySet();
68              }
69              else if ( "values".equals( name ) )
70              {
71                  result = map.values();
72              }
73              else if ( "isEmpty".equals( name ) )
74              {
75                  result = map.isEmpty() ? Boolean.TRUE : Boolean.FALSE;
76              }
77              else
78              {
79                  result = map.get( name );
80              }
81          }
82          else
83          {
84              result = map.get( name );
85          }
86  
87          return result;
88      }
89  
90      public void setProperty( Map<String, Object> context, Object target, Object name, Object value )
91          throws OgnlException
92      {
93          @SuppressWarnings( "unchecked" ) // checked by the invoker
94          Map<Object, Object> map = (Map<Object, Object>) target;
95          map.put( name, value );
96      }
97  
98      public String getSourceAccessor( OgnlContext context, Object target, Object index )
99      {
100         Node currentNode = context.getCurrentNode().jjtGetParent();
101         boolean indexedAccess = false;
102 
103         if ( currentNode == null )
104         {
105             throw new RuntimeException( "node is null for '" + index + "'" );
106         }
107 
108         if ( !( currentNode instanceof ASTProperty ) )
109         {
110             currentNode = currentNode.jjtGetParent();
111         }
112 
113         if ( currentNode instanceof ASTProperty )
114         {
115             indexedAccess = ( (ASTProperty) currentNode ).isIndexedAccess();
116         }
117 
118         String indexStr = index.toString();
119 
120         context.setCurrentAccessor( Map.class );
121         context.setCurrentType( Object.class );
122 
123         if ( String.class.isInstance( index ) && !indexedAccess )
124         {
125             String key = indexStr.replaceAll( "\"", "" );
126 
127             if ( "size".equals( key ) )
128             {
129                 context.setCurrentType( int.class );
130                 return ".size()";
131             }
132             else if ( "keys".equals( key ) || "keySet".equals( key ) )
133             {
134                 context.setCurrentType( Set.class );
135                 return ".keySet()";
136             }
137             else if ( "values".equals( key ) )
138             {
139                 context.setCurrentType( Collection.class );
140                 return ".values()";
141             }
142             else if ( "isEmpty".equals( key ) )
143             {
144                 context.setCurrentType( boolean.class );
145                 return ".isEmpty()";
146             }
147         }
148 
149         return ".get(" + indexStr + ")";
150     }
151 
152     public String getSourceSetter( OgnlContext context, Object target, Object index )
153     {
154         context.setCurrentAccessor( Map.class );
155         context.setCurrentType( Object.class );
156 
157         String indexStr = index.toString();
158 
159         if ( String.class.isInstance( index ) )
160         {
161             String key = indexStr.replaceAll( "\"", "" );
162 
163             if ( "size".equals( key ) || "keys".equals( key ) || "keySet".equals( key ) || "values".equals( key )
164                 || "isEmpty".equals( key ) )
165             {
166                 return "";
167             }
168         }
169 
170         return ".put(" + indexStr + ", $3)";
171     }
172 }