View Javadoc

1   /*
2    *   Copyright 2004-2005 The Apache Software Foundation
3    *
4    *   Licensed under the Apache License, Version 2.0 (the "License");
5    *   you may not use this file except in compliance with the License.
6    *   You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *   Unless required by applicable law or agreed to in writing, software
11   *   distributed under the License is distributed on an "AS IS" BASIS,
12   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *   See the License for the specific language governing permissions and
14   *   limitations under the License.
15   *
16   */
17  package org.apache.asn1.ber;
18  
19  
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  
23  
24  /***
25   * A visitor used to transform a TLV tuple tree by altering tuples to use
26   * determinate length encodings rather than the indeterminate form.
27   *
28   * @author <a href="mailto:dev@directory.apache.org"> Apache Directory
29   *         Project</a> $Rev: 157644 $
30   */
31  public class DeterminateLengthVisitor implements TupleNodeVisitor
32  {
33      /*** the visitor monitor called when notible events occur */
34      private VisitorMonitor monitor = VisitorMonitor.NOOP;
35  
36  
37      /***
38       * Visits a tree of tuple nodes using a specific visitation order.
39       *
40       * @param node the node to visit
41       */
42      public void visit( TupleNode node )
43      {
44          /*
45           * Because of a recursive depth first descent driving the
46           * calculation of indeterminate child sizes we just need to
47           * add the sizes of all the child nodes to find the determinate
48           * length and set it for the tuple.
49           */
50          int length = 0;
51          Iterator children = node.getChildren();
52          while ( children.hasNext() )
53          {
54              TupleNode childTuple = ( TupleNode ) children.next();
55              Tuple tlv = childTuple.getTuple() ;
56  
57              /*
58               * The tuple node may have child tuple nodes that are indefinite
59               * terminator nodes.  When converting to the definate length form
60               * these tuples must be detached from the tree and NOT factored
61               * into length computations.
62               */
63              if ( tlv.isIndefiniteTerminator() )
64              {
65                  // setting the parent to null removes it from the
66                  // parent's child list
67                  ( ( MutableTupleNode ) childTuple ).setParent( null );
68              }
69              else
70              {
71                  length += tlv.size();
72              }
73          }
74  
75          node.getTuple().setValueLength( length );
76          monitor.visited( this, node );
77      }
78  
79  
80      /***
81       * Checks to see if a node can be visited.
82       *
83       * @param node the node to be visited
84       * @return whether or node the node should be visited
85       */
86      public boolean canVisit( TupleNode node )
87      {
88          return node.getTuple().isIndefinite();
89      }
90  
91  
92      /***
93       * Determines whether the visitation order is prefix or postfix.
94       *
95       * @return true if the visitation is in prefix order, false otherwise.
96       */
97      public boolean isPrefix()
98      {
99          return false;
100     }
101 
102 
103     /***
104      * Get the array of children to visit sequentially to determine the order of
105      * child visitations.  Some children may not be returned at all if
106      * canVisit() returns false on them.
107      *
108      * @param node     the parent branch node
109      * @param children the child node array
110      * @return the new reordered array of children
111      */
112     public ArrayList getOrder( TupleNode node, ArrayList children )
113     {
114         return children;
115     }
116 
117 
118     public void setMonitor( VisitorMonitor monitor )
119     {
120         this.monitor = monitor;
121     }
122 }