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 }