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 *    https://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 */
020package org.apache.directory.api.ldap.codec.actions.ldapResult;
021
022
023import org.apache.directory.api.asn1.DecoderException;
024import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
025import org.apache.directory.api.asn1.ber.tlv.TLV;
026import org.apache.directory.api.i18n.I18n;
027import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
028import org.apache.directory.api.ldap.model.exception.LdapURLEncodingException;
029import org.apache.directory.api.ldap.model.message.LdapResult;
030import org.apache.directory.api.ldap.model.message.Message;
031import org.apache.directory.api.ldap.model.message.Referral;
032import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
033import org.apache.directory.api.ldap.model.message.ResultResponse;
034import org.apache.directory.api.ldap.model.url.LdapUrl;
035import org.apache.directory.api.util.Strings;
036import org.slf4j.Logger;
037import org.slf4j.LoggerFactory;
038
039
040/**
041 * The action used to add a referral to a LdapTresult
042 * <pre>
043 * Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI (RFC 4511)
044 * URI ::= LDAPString
045 * </pre>
046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
047 */
048public class AddReferral extends GrammarAction<LdapMessageContainer<Message>>
049{
050    /** The logger */
051    private static final Logger LOG = LoggerFactory.getLogger( AddReferral.class );
052
053
054    /**
055     * Instantiates a new referral action.
056     */
057    public AddReferral()
058    {
059        super( "Add a referral" );
060    }
061
062
063    /**
064     * {@inheritDoc}
065     */
066    @Override
067    public void action( LdapMessageContainer<Message> container ) throws DecoderException
068    {
069        TLV tlv = container.getCurrentTLV();
070
071        Message response = container.getMessage();
072        LdapResult ldapResult = ( ( ResultResponse ) response ).getLdapResult();
073        Referral referral = ldapResult.getReferral();
074
075        if ( tlv.getLength() == 0 )
076        {
077            referral.addLdapUrl( "" );
078        }
079        else
080        {
081            if ( ldapResult.getResultCode() == ResultCodeEnum.REFERRAL )
082            {
083                try
084                {
085                    String url = Strings.utf8ToString( tlv.getValue().getData() );
086                    referral.addLdapUrl( new LdapUrl( url ).toString() );
087                }
088                catch ( LdapURLEncodingException luee )
089                {
090                    String badUrl = Strings.utf8ToString( tlv.getValue().getData() );
091                    LOG.error( I18n.err( I18n.ERR_05103_INVALID_URL, badUrl, luee.getMessage() ) );
092                    throw new DecoderException( I18n.err( I18n.ERR_05104_INVALID_URL, luee.getMessage() ), luee );
093                }
094            }
095            else
096            {
097                if ( LOG.isWarnEnabled() )
098                {
099                    LOG.warn( I18n.msg( I18n.MSG_05103_REFERRAL_ERROR_MESSAGE_NOT_ALLOWED ) );
100                }
101                
102                referral.addLdapUrl( LdapUrl.EMPTY_URL.toString() );
103            }
104        }
105
106        if ( LOG.isDebugEnabled() )
107        {
108            StringBuilder sb = new StringBuilder();
109            boolean isFirst = true;
110
111            for ( String url : ldapResult.getReferral().getLdapUrls() )
112            {
113                if ( isFirst )
114                {
115                    isFirst = false;
116                }
117                else
118                {
119                    sb.append( ", " );
120                }
121
122                sb.append( url );
123            }
124
125            if ( LOG.isDebugEnabled() )
126            {
127                LOG.debug( I18n.msg( I18n.MSG_05104_REFERRAL_ERROR_MESSAGE_SET_TO, sb.toString() ) );
128             }
129        }
130
131        // We can have an END transition
132        container.setGrammarEndAllowed( true );
133    }
134}