Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: ognl/ASTChain.java


1   //--------------------------------------------------------------------------
2   //  Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
3   //  All rights reserved.
4   //
5   //  Redistribution and use in source and binary forms, with or without
6   //  modification, are permitted provided that the following conditions are
7   //  met:
8   //
9   //  Redistributions of source code must retain the above copyright notice,
10  //  this list of conditions and the following disclaimer.
11  //  Redistributions in binary form must reproduce the above copyright
12  //  notice, this list of conditions and the following disclaimer in the
13  //  documentation and/or other materials provided with the distribution.
14  //  Neither the name of the Drew Davidson nor the names of its contributors
15  //  may be used to endorse or promote products derived from this software
16  //  without specific prior written permission.
17  //
18  //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  //  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  //  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  //  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25  //  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  //  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  //  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28  //  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29  //  DAMAGE.
30  //--------------------------------------------------------------------------
31  package ognl;
32  
33  import java.lang.reflect.Array;
34  
35  /**
36   * @author Luke Blanshard (blanshlu@netscape.net)
37   * @author Drew Davidson (drew@ognl.org)
38   */
39  class ASTChain extends SimpleNode
40  {
41      public ASTChain(int id) {
42          super(id);
43      }
44  
45      public ASTChain(OgnlParser p, int id) {
46          super(p, id);
47      }
48  
49      public void jjtClose() {
50          flattenTree();
51      }
52  
53      protected Object getValueBody( OgnlContext context, Object source ) throws OgnlException
54      {
55          Object      result = source;
56  
57          for ( int i = 0, ilast = children.length - 1; i <= ilast; ++i ) {
58              boolean         handled = false;
59  
60              if (i < ilast) {
61                  if (children[i] instanceof ASTProperty) {
62                      ASTProperty     propertyNode = (ASTProperty)children[i];
63                      int             indexType = propertyNode.getIndexedPropertyType(context, result);
64  
65                      if ((indexType != OgnlRuntime.INDEXED_PROPERTY_NONE) && (children[i + 1] instanceof ASTProperty)) {
66                          ASTProperty     indexNode = (ASTProperty)children[i + 1];
67  
68                          if (indexNode.isIndexedAccess()) {
69                              Object      index = indexNode.getProperty(context, result);
70  
71                              if (index instanceof DynamicSubscript) {
72                                  if (indexType == OgnlRuntime.INDEXED_PROPERTY_INT) {
73                                      Object      array = propertyNode.getValue(context, result);
74                                      int         len = Array.getLength(array);
75  
76                                      switch (((DynamicSubscript)index).getFlag()) {
77                                          case DynamicSubscript.ALL:
78                                              result = Array.newInstance( array.getClass().getComponentType(), len );
79                                              System.arraycopy( array, 0, result, 0, len );
80                                              handled = true;
81                                              i++;
82                                              break;
83                                          case DynamicSubscript.FIRST:
84                                              index = new Integer((len > 0) ? 0 : -1);
85                                              break;
86                                          case DynamicSubscript.MID:
87                                              index = new Integer((len > 0) ? (len / 2) : -1);
88                                              break;
89                                          case DynamicSubscript.LAST:
90                                              index = new Integer((len > 0) ? (len - 1) : -1);
91                                              break;
92                                      }
93                                  } else {
94                                      if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT) {
95                                          throw new OgnlException("DynamicSubscript '" + indexNode + "' not allowed for object indexed property '" + propertyNode + "'");
96                                      }
97                                  }
98                              }
99                              if (!handled) {
100                                 result = OgnlRuntime.getIndexedProperty(context, result, propertyNode.getProperty(context, result).toString(), index);
101                                 handled = true;
102                                 i++;
103                             }
104                         }
105                     }
106                 }
107             }
108             if (!handled) {
109                 result = children[i].getValue( context, result );
110             }
111         }
112         return result;
113     }
114 
115     protected void setValueBody( OgnlContext context, Object target, Object value ) throws OgnlException
116     {
117         boolean         handled = false;
118 
119         for ( int i = 0, ilast = children.length - 2; i <= ilast; ++i ) {
120             if (i == ilast) {
121                 if (children[i] instanceof ASTProperty) {
122                     ASTProperty     propertyNode = (ASTProperty)children[i];
123                     int             indexType = propertyNode.getIndexedPropertyType(context, target);
124 
125                     if ((indexType != OgnlRuntime.INDEXED_PROPERTY_NONE) && (children[i + 1] instanceof ASTProperty)) {
126                         ASTProperty     indexNode = (ASTProperty)children[i + 1];
127 
128                         if (indexNode.isIndexedAccess()) {
129                             Object      index = indexNode.getProperty(context, target);
130 
131                             if (index instanceof DynamicSubscript) {
132                                 if (indexType == OgnlRuntime.INDEXED_PROPERTY_INT) {
133                                     Object      array = propertyNode.getValue(context, target);
134                                     int         len = Array.getLength(array);
135 
136                                     switch (((DynamicSubscript)index).getFlag()) {
137                                         case DynamicSubscript.ALL:
138                                             System.arraycopy(target, 0, value, 0, len);
139                                             handled = true;
140                                             i++;
141                                             break;
142                                         case DynamicSubscript.FIRST:
143                                             index = new Integer((len > 0) ? 0 : -1);
144                                             break;
145                                         case DynamicSubscript.MID:
146                                             index = new Integer((len > 0) ? (len / 2) : -1);
147                                             break;
148                                         case DynamicSubscript.LAST:
149                                             index = new Integer((len > 0) ? (len - 1) : -1);
150                                             break;
151                                     }
152                                 } else {
153                                     if (indexType == OgnlRuntime.INDEXED_PROPERTY_OBJECT) {
154                                         throw new OgnlException("DynamicSubscript '" + indexNode + "' not allowed for object indexed property '" + propertyNode + "'");
155                                     }
156                                 }
157                             }
158                             if (!handled) {
159                                 OgnlRuntime.setIndexedProperty(context, target, propertyNode.getProperty(context, target).toString(), index, value);
160                                 handled = true;
161                                 i++;
162                             }
163                         }
164                     }
165                 }
166             }
167             if (!handled) {
168                 target = children[i].getValue( context, target );
169             }
170         }
171         if (!handled) {
172             children[children.length - 1].setValue( context, target, value );
173         }
174     }
175 
176     public boolean isSimpleNavigationChain( OgnlContext context ) throws OgnlException
177     {
178         boolean     result = false;
179 
180         if ((children != null) && (children.length > 0)) {
181             result = true;
182             for (int i = 0; result && (i < children.length); i++) {
183                 if (children[i] instanceof SimpleNode) {
184                     result = ((SimpleNode)children[i]).isSimpleProperty(context);
185                 } else {
186                     result = false;
187                 }
188             }
189         }
190         return result;
191     }
192 
193     public String toString()
194     {
195         String      result = "";
196 
197         if ((children != null) && (children.length > 0)) {
198             for (int i = 0; i < children.length; i++) {
199                 if (i > 0) {
200                     if (!(children[i] instanceof ASTProperty) || !((ASTProperty)children[i]).isIndexedAccess()) {
201                         result = result + ".";
202                     }
203                 }
204                 result += children[i].toString();
205             }
206         }
207         return result;
208     }
209 }