001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.asn1.codec.stateful;
021
022
023 import java.util.LinkedList;
024
025
026 /**
027 * A convenience callback which collects decoded or encoded objects to audit a
028 * codecs's activity. The callback also comes in handy when data is to be pushed
029 * through a codec and grabed immediately afterwords to serialize codec
030 * operation.
031 *
032 * @author <a href="mailto:dev@directory.apache.org"> Apache Directory Project</a>
033 * @version $Rev: 572195 $
034 */
035 public class CallbackHistory implements DecoderCallback, EncoderCallback
036 {
037 /** history of decoded objects in cronological order */
038 private final LinkedList<Object> history;
039
040 /** the length of callback history stored */
041 private final int length;
042
043
044 /**
045 * Creates an auditing callback that manages a history of indefinite length.
046 */
047 public CallbackHistory()
048 {
049 this( -1 );
050 }
051
052
053 /**
054 * Creates an auditing callback that manages a history of fixed or
055 * indefinite length. If the length is fixed the history effectively becomes
056 * a FIFO structure.
057 *
058 * @param length
059 * the maximum length of callback history to store before
060 * dropping decoded items, a length of zero or 1 corresponds to
061 * indefinite history
062 */
063 public CallbackHistory(int length)
064 {
065 this.length = length;
066 history = new LinkedList<Object>();
067 }
068
069
070 /*
071 * (non-Javadoc)
072 *
073 * @see org.apache.asn1.codec.stateful.DecoderCallback#decodeOccurred(
074 * org.apache.asn1.codec.stateful.StatefulDecoder, java.lang.Object)
075 */
076 public void decodeOccurred( StatefulDecoder decoder, Object decoded )
077 {
078 if ( length > 0 )
079 {
080 while ( history.size() >= length )
081 {
082 history.removeLast();
083 }
084 }
085
086 history.addFirst( decoded );
087 }
088
089
090 /**
091 * Callback to deliver a fully encoded object.
092 *
093 * @param encoder
094 * the stateful encoder driving the callback
095 * @param encoded
096 * the object that was encoded
097 */
098 public void encodeOccurred( StatefulEncoder encoder, Object encoded )
099 {
100 if ( length > 0 )
101 {
102 while ( history.size() >= length )
103 {
104 history.removeLast();
105 }
106 }
107
108 history.addFirst( encoded );
109 }
110
111
112 /**
113 * Gets the most recent decoded object if one exists.
114 *
115 * @return the most recent decoded object
116 * @throws java.util.NoSuchElementException
117 * if the history is empty
118 */
119 public Object getMostRecent()
120 {
121 return history.getFirst();
122 }
123
124
125 /**
126 * Gets the oldest decoded object if one exists.
127 *
128 * @return the oldest decoded object
129 * @throws java.util.NoSuchElementException
130 * if the history is empty
131 */
132 public Object getOldest()
133 {
134 return history.getLast();
135 }
136
137
138 /**
139 * Tests to see if the history is empty.
140 *
141 * @return true if the history is empty, false otherwise
142 */
143 public boolean isEmpty()
144 {
145 return history.isEmpty();
146 }
147
148
149 /**
150 * Clears the history of decoded items.
151 */
152 public void clear()
153 {
154 history.clear();
155 }
156
157
158 /**
159 * Gets the number of decoded items in the callback history.
160 *
161 * @return the number of decoded items in the callback history
162 */
163 public int size()
164 {
165 return history.size();
166 }
167 }