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.ldap.message;
021    
022    
023    import java.io.OutputStream;
024    import java.nio.ByteBuffer;
025    
026    import org.apache.directory.shared.asn1.codec.EncoderException;
027    import org.apache.directory.shared.asn1.codec.stateful.EncoderCallback;
028    import org.apache.directory.shared.asn1.codec.stateful.EncoderMonitor;
029    import org.apache.directory.shared.ldap.codec.TwixTransformer;
030    import org.apache.directory.shared.ldap.message.spi.Provider;
031    import org.apache.directory.shared.ldap.message.spi.ProviderEncoder;
032    import org.apache.directory.shared.ldap.message.spi.ProviderException;
033    
034    
035    /**
036     * Encodes a Message instance into a binary message envelope using Basic
037     * Encoding rules flushing the PDU out to an OutputStream.
038     * 
039     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
040     * @version $Rev: 764131 $
041     */
042    public final class MessageEncoder implements ProviderEncoder
043    {
044        /** the provider */
045        private final Provider provider;
046    
047        /** the provider's encoder */
048        private final ProviderEncoder encoder;
049    
050    
051        /**
052         * Creates a MessageEncoder using default properties for enabling a BER
053         * library provider.
054         * 
055         * @throws MessageException if the encoder cannot be created.
056         */
057        public MessageEncoder() throws MessageException
058        {
059            this.provider = Provider.getProvider( Provider.getEnvironment() );
060            this.encoder = provider.getEncoder();
061        }
062    
063    
064        // ------------------------------------------------------------------------
065        // ProviderEncoder
066        // ------------------------------------------------------------------------
067    
068        /**
069         * @see ProviderEncoder#encodeBlocking(Object, java.io.OutputStream, Object)
070         */
071        public void encodeBlocking( Object lock, OutputStream out, Object obj ) throws ProviderException
072        {
073            // transform to build provider specific intermediate envelope
074            Object providerEnvelope = TwixTransformer.transform( ( InternalMessage ) obj );
075    
076            // now encode provider's intermediate stub into a PDU onto stream
077            this.encoder.encodeBlocking( lock, out, providerEnvelope );
078        }
079    
080    
081        /**
082         * @see ProviderEncoder#encodeBlocking(Object)
083         */
084        public ByteBuffer encodeBlocking( Object obj ) throws ProviderException
085        {
086            // transform to build provider specific intermediate envelope
087            Object providerEnvelope = TwixTransformer.transform( ( InternalMessage ) obj );
088    
089            // now encode provider's intermediate stub into PDU in a byte buffer
090            return this.encoder.encodeBlocking( providerEnvelope );
091        }
092    
093    
094        // ------------------------------------------------------------------------
095        // ProviderObject Methods
096        // ------------------------------------------------------------------------
097    
098        /**
099         * @see org.apache.directory.shared.ldap.message.spi.ProviderObject#getProvider()
100         */
101        public Provider getProvider()
102        {
103            return this.provider;
104        }
105    
106    
107        // ------------------------------------------------------------------------
108        // StatefulEncoder Methods
109        // ------------------------------------------------------------------------
110    
111        /**
112         * Encodes a Message object piece by piece often emitting chunks of the
113         * final PDU to the callback if present.
114         * 
115         * @param obj the message object to encode into a PDU
116         * @throws EncoderException if there are problems while encoding
117         */
118        public void encode( Object obj ) throws EncoderException
119        {
120            // transform to build provider specific intermediate envelope
121            Object providerEnvelope = TwixTransformer.transform( ( InternalMessage ) obj );
122    
123            // now give intermediate envelope to provider's encoder
124            this.encoder.encode( providerEnvelope );
125        }
126    
127    
128        /**
129         * Sets the callback of the underlying implementation. There is no need for
130         * any special callbacks because when encoding we do not need to transform
131         * before a value return as we did in the decoder.
132         * 
133         * @param cb the callback to set on the underlying provider specific encoder
134         */
135        public void setCallback( EncoderCallback cb )
136        {
137            this.encoder.setCallback( cb );
138        }
139    
140    
141        /**
142         * Sets the monitor of the underlying implementation.
143         * 
144         * @param monitor the monitor to set on the underlying implementation
145         */
146        public void setEncoderMonitor( EncoderMonitor monitor )
147        {
148            this.encoder.setEncoderMonitor( monitor );
149        }
150    }