001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2015 ForgeRock AS
026 */
027package org.opends.guitools.controlpanel.datamodel;
028
029import static org.opends.server.backends.pluggable.SuffixContainer.*;
030
031import java.util.Collections;
032import java.util.Set;
033import java.util.SortedSet;
034import java.util.TreeSet;
035
036import org.opends.server.types.AttributeType;
037
038/**
039 * The class used to describe the index configuration (the normal index: the one
040 * used to improve search performance on a given attribute).
041 */
042public class IndexDescriptor extends AbstractIndexDescriptor
043{
044
045  private static final String[] DATABASE_INDEXES = new String[] {
046    DN2ID_INDEX_NAME, ID2CHILDREN_COUNT_NAME, ID2CHILDREN_INDEX_NAME, ID2SUBTREE_INDEX_NAME };
047
048  private final SortedSet<IndexTypeDescriptor> types = new TreeSet<>();
049  private final boolean isDatabaseIndex;
050  private final int entryLimit;
051  private final AttributeType attr;
052  private int hashCode;
053
054  /**
055   * Constructor of the index descriptor.
056   *
057   * @param indexName
058   *          name of the index.
059   */
060  public IndexDescriptor(String indexName)
061  {
062    this(indexName, null, null, Collections.EMPTY_SET, -1);
063  }
064
065  /**
066   * Constructor of the index descriptor.
067   *
068   * @param name
069   *          name of the index.
070   * @param attr
071   *          the attribute type associated with the index attribute.
072   * @param backend
073   *          the backend where the index is defined.
074   * @param types
075   *          the type of indexes (equality, substring, etc.).
076   * @param entryLimit
077   *          the entry limit for the index.
078   */
079  public IndexDescriptor(
080      String name, AttributeType attr, BackendDescriptor backend, Set<IndexTypeDescriptor> types, int entryLimit)
081  {
082    super(name, backend);
083    this.attr = attr;
084    this.types.addAll(types);
085    isDatabaseIndex = isDatabaseIndex(name);
086    this.entryLimit = entryLimit;
087    recalculateHashCode();
088  }
089
090  /**
091   * Returns the attribute type associated with the index attribute.
092   *
093   * @return the attribute type associated with the index attribute.
094   */
095  public AttributeType getAttributeType()
096  {
097    return attr;
098  }
099
100  @Override
101  public int compareTo(AbstractIndexDescriptor o)
102  {
103    return getName().toLowerCase().compareTo(o.getName().toLowerCase());
104  }
105
106  @Override
107  public int hashCode()
108  {
109    return hashCode;
110  }
111
112  /**
113   * Returns the type of indexes (equality, substring, etc.).
114   *
115   * @return the type of indexes (equality, substring, etc.).
116   */
117  public SortedSet<IndexTypeDescriptor> getTypes()
118  {
119    return new TreeSet<>(types);
120  }
121
122  /**
123   * Tells whether this is a database index or not. Database indexes are not
124   * modifiable and for internal use only.
125   *
126   * @return <CODE>true</CODE> if this is a database index and
127   *         <CODE>false</CODE> otherwise.
128   */
129  public boolean isDatabaseIndex()
130  {
131    return isDatabaseIndex;
132  }
133
134  /**
135   * Tells whether the provide index name corresponds to a database index or
136   * not. Database indexes are not modifiable and for internal use only.
137   *
138   * @return <CODE>true</CODE> if the provide index name corresponds to a
139   *         database index and <CODE>false</CODE> otherwise.
140   */
141  private boolean isDatabaseIndex(final String indexName)
142  {
143    for (final String dbIndex : DATABASE_INDEXES)
144    {
145      if (indexName.equalsIgnoreCase(dbIndex))
146      {
147        return true;
148      }
149    }
150    return false;
151  }
152
153  @Override
154  public boolean equals(Object o)
155  {
156    if (o == this)
157    {
158      return true;
159    }
160    if (!(o instanceof IndexDescriptor))
161    {
162      return false;
163    }
164    final IndexDescriptor index = (IndexDescriptor)o;
165    return index.getName().equalsIgnoreCase(getName())
166        && index.isDatabaseIndex() == isDatabaseIndex()
167        && index.getTypes().equals(getTypes())
168        && index.getEntryLimit() == getEntryLimit()
169        && backendIdEqual(index);
170  }
171
172  private boolean backendIdEqual(IndexDescriptor index)
173  {
174    BackendDescriptor backend1 = getBackend();
175    BackendDescriptor backend2 = index.getBackend();
176    return backend1 != null && backend2 != null && backend1.getBackendID().equals(backend2.getBackendID());
177  }
178
179  /**
180   * Returns the entry limit of the index.
181   *
182   * @return the entry limit of the index.
183   */
184  public int getEntryLimit()
185  {
186    return entryLimit;
187  }
188
189  @Override
190  protected void recalculateHashCode()
191  {
192    final StringBuilder sb = new StringBuilder();
193    for (final IndexTypeDescriptor t : types)
194    {
195      sb.append(t).append(",");
196    }
197    if (getBackend() != null)
198    {
199      sb.append(getBackend().getBackendID());
200    }
201    hashCode = (getName()+sb+entryLimit).hashCode();
202  }
203}