001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.dao.db;
016    
017    import aQute.bnd.annotation.ProviderType;
018    
019    import com.liferay.portal.kernel.util.HashUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.Validator;
024    
025    import java.util.Arrays;
026    
027    /**
028     * @author James Lefeu
029     * @author Peter Shin
030     * @author Shuyang Zhou
031     */
032    @ProviderType
033    public class IndexMetadata extends Index implements Comparable<IndexMetadata> {
034    
035            public IndexMetadata(
036                    String indexName, String tableName, boolean unique,
037                    String... columnNames) {
038    
039                    super(indexName, tableName, unique);
040    
041                    if (columnNames == null) {
042                            throw new NullPointerException("Column names are missing");
043                    }
044    
045                    _columnNames = columnNames;
046    
047                    StringBundler sb = new StringBundler(8 + columnNames.length * 2);
048    
049                    if (unique) {
050                            sb.append("create unique ");
051                    }
052                    else {
053                            sb.append("create ");
054                    }
055    
056                    sb.append("index ");
057                    sb.append(indexName);
058                    sb.append(" on ");
059                    sb.append(tableName);
060    
061                    sb.append(StringPool.SPACE);
062                    sb.append(StringPool.OPEN_PARENTHESIS);
063    
064                    for (String columnName : columnNames) {
065                            sb.append(columnName);
066                            sb.append(StringPool.COMMA_AND_SPACE);
067                    }
068    
069                    sb.setIndex(sb.index() - 1);
070    
071                    sb.append(StringPool.CLOSE_PARENTHESIS);
072                    sb.append(StringPool.SEMICOLON);
073    
074                    _createSQL = sb.toString();
075    
076                    sb.setIndex(0);
077    
078                    sb.append("drop index ");
079                    sb.append(indexName);
080                    sb.append(" on ");
081                    sb.append(tableName);
082                    sb.append(StringPool.SEMICOLON);
083    
084                    _dropSQL = sb.toString();
085            }
086    
087            @Override
088            public int compareTo(IndexMetadata indexMetadata) {
089                    String columnNames = StringUtil.merge(_columnNames);
090    
091                    String indexMetadataColumnNames = StringUtil.merge(
092                            indexMetadata._columnNames);
093    
094                    return columnNames.compareTo(indexMetadataColumnNames);
095            }
096    
097            @Override
098            public boolean equals(Object obj) {
099                    if (this == obj) {
100                            return true;
101                    }
102    
103                    if (!(obj instanceof IndexMetadata)) {
104                            return false;
105                    }
106    
107                    IndexMetadata indexMetadata = (IndexMetadata)obj;
108    
109                    if (Validator.equals(getTableName(), indexMetadata.getTableName()) &&
110                            Arrays.equals(getColumnNames(), indexMetadata.getColumnNames())) {
111    
112                            return true;
113                    }
114    
115                    return false;
116            }
117    
118            public String[] getColumnNames() {
119                    return _columnNames;
120            }
121    
122            public String getCreateSQL() {
123                    return _createSQL;
124            }
125    
126            public String getDropSQL() {
127                    return _dropSQL;
128            }
129    
130            @Override
131            public int hashCode() {
132                    int hashCode = HashUtil.hash(0, getTableName());
133    
134                    for (String columnName : _columnNames) {
135                            hashCode = HashUtil.hash(hashCode, columnName);
136                    }
137    
138                    return hashCode;
139            }
140    
141            public Boolean redundantTo(IndexMetadata indexMetadata) {
142                    String[] indexMetadataColumnNames = indexMetadata._columnNames;
143    
144                    if (_columnNames.length <= indexMetadataColumnNames.length) {
145                            for (int i = 0; i < _columnNames.length; i++) {
146                                    if (!_columnNames[i].equals(indexMetadataColumnNames[i])) {
147                                            return null;
148                                    }
149                            }
150    
151                            if (isUnique()) {
152                                    return Boolean.FALSE;
153                            }
154                            else {
155                                    return Boolean.TRUE;
156                            }
157                    }
158    
159                    Boolean redundant = indexMetadata.redundantTo(this);
160    
161                    if (redundant == null) {
162                            return null;
163                    }
164    
165                    return !redundant;
166            }
167    
168            @Override
169            public String toString() {
170                    return _createSQL;
171            }
172    
173            private final String[] _columnNames;
174            private final String _createSQL;
175            private final String _dropSQL;
176    
177    }