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 */
020package org.apache.directory.api.ldap.model.message;
021
022
023import java.util.ArrayList;
024import java.util.Collection;
025import java.util.Collections;
026import java.util.Iterator;
027import java.util.List;
028
029
030/**
031 * A Referral implementation. For the time being this implementation uses a
032 * String representation for LDAPURLs. In the future an LdapUrl interface with
033 * default implementations will be used once a parser for an LdapUrl is created.
034 * 
035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
036 */
037public class ReferralImpl implements Referral
038{
039    static final long serialVersionUID = 2638820668325359096L;
040
041    /** Sequence of LDAPUrls composing this Referral */
042    private final List<String> urls = new ArrayList<>();
043
044    /** The encoded LdapURL */
045    private final List<byte[]> urlsBytes = new ArrayList<>();
046
047    /** The length of the referral */
048    private int referralLength;
049
050
051    // ------------------------------------------------------------------------
052    // LdapResult Interface Method Implementations
053    // ------------------------------------------------------------------------
054    /**
055     * {@inheritDoc}
056     */
057    @Override
058    public int getReferralLength()
059    {
060        return referralLength;
061    }
062
063
064    /**
065     * {@inheritDoc}
066     */
067    @Override
068    public void setReferralLength( int referralLength )
069    {
070        this.referralLength = referralLength;
071    }
072
073
074    /**
075     * Gets an unmodifiable set of alternative referral urls.
076     * 
077     * @return the alternative url objects.
078     */
079    @Override
080    public Collection<String> getLdapUrls()
081    {
082        return Collections.unmodifiableCollection( urls );
083    }
084
085
086    /**
087     * {@inheritDoc}
088     */
089    @Override
090    public Collection<byte[]> getLdapUrlsBytes()
091    {
092        return urlsBytes;
093    }
094
095
096    /**
097     * Adds an LDAPv3 URL to this Referral.
098     * 
099     * @param url the LDAPv3 URL to add
100     */
101    @Override
102    public void addLdapUrl( String url )
103    {
104        urls.add( url );
105    }
106
107
108    /**
109     * {@inheritDoc}
110     */
111    @Override
112    public void addLdapUrlBytes( byte[] urlBytes )
113    {
114        urlsBytes.add( urlBytes );
115    }
116
117
118    /**
119     * Removes an LDAPv3 URL to this Referral.
120     * 
121     * @param url
122     *            the LDAPv3 URL to remove
123     */
124    @Override
125    public void removeLdapUrl( String url )
126    {
127        urls.remove( url );
128    }
129
130
131    /**
132     * @see Object#hashCode()
133     * @return the instance's hash code 
134     */
135    @Override
136    public int hashCode()
137    {
138        int hash = 37;
139        hash = hash * 17 + urls.size();
140
141        // Order doesn't matter, so just add the url hashCode
142        for ( String url : urls )
143        {
144            hash = hash + url.hashCode();
145        }
146
147        return hash;
148    }
149
150
151    /**
152     * Compares this Referral implementation to see if it is the same as
153     * another. The classes do not have to be the same implementation to return
154     * true. Both this and the compared Referral must have the same entries
155     * exactly. The order of Referral URLs does not matter.
156     * 
157     * @param obj
158     *            the object to compare this ReferralImpl to
159     * @return true if both implementations contain exactly the same URLs
160     */
161    @Override
162    public boolean equals( Object obj )
163    {
164        // just in case for speed return true if obj is this object
165        if ( obj == this )
166        {
167            return true;
168        }
169
170        if ( obj instanceof Referral )
171        {
172            Collection<String> refs = ( ( Referral ) obj ).getLdapUrls();
173
174            // if their sizes do not match they are not equal
175            if ( refs.size() != urls.size() )
176            {
177                return false;
178            }
179
180            Iterator<String> list = urls.iterator();
181
182            while ( list.hasNext() )
183            {
184                // if one of our urls is not contained in the obj return false
185                if ( !refs.contains( list.next() ) )
186                {
187                    return false;
188                }
189            }
190
191            // made it through the checks so we have a match
192            return true;
193        }
194
195        return false;
196    }
197
198
199    /**
200     * Get a String representation of a Referral
201     * 
202     * @return A Referral String
203     */
204    @Override
205    public String toString()
206    {
207        StringBuilder sb = new StringBuilder();
208
209        if ( !urls.isEmpty() )
210        {
211            sb.append( "            Referrals :\n" );
212
213            Object[] urlsArray = urls.toArray();
214
215            for ( int i = 0; i < urlsArray.length; i++ )
216            {
217
218                String referral = ( String ) urlsArray[i];
219
220                sb.append( "                Referral[" ).append( i ).append( "] :" ).append( referral ).append( '\n' );
221            }
222        }
223
224        return sb.toString();
225    }
226}