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