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