001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: /*
021: *
022: * Copyright 2005 Sun Microsystems, Inc.
023: *
024: * Licensed under the Apache License, Version 2.0 (the "License");
025: * you may not use this file except in compliance with the License.
026: * You may obtain a copy of the License at
027: *
028: * http://www.apache.org/licenses/LICENSE-2.0
029: *
030: * Unless required by applicable law or agreed to in writing, software
031: * distributed under the License is distributed on an "AS IS" BASIS,
032: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
033: * See the License for the specific language governing permissions and
034: * limitations under the License.
035: *
036: */
037: package org.netbeans.modules.jdbcwizard.builder.dbmodel.impl;
038:
039: import org.netbeans.modules.jdbcwizard.builder.dbmodel.DBTable;
040: import org.netbeans.modules.jdbcwizard.builder.dbmodel.DBColumn;
041: import org.netbeans.modules.jdbcwizard.builder.dbmodel.PrimaryKey;
042: import org.netbeans.modules.jdbcwizard.builder.dbmodel.ForeignKey;
043:
044: import java.util.ArrayList;
045: import java.util.Collections;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.ResourceBundle;
049:
050: import org.openide.util.NbBundle;
051:
052: /**
053: * Implements PrimaryKey interface.
054: *
055: * @author Jonathan Giron
056: */
057: public class PrimaryKeyImpl implements PrimaryKey, Cloneable {
058:
059: public static final PrimaryKeyImpl NULL = new PrimaryKeyImpl();
060:
061: public static final String ELEMENT_TAG = "primaryKey"; // NOI18N
062:
063: public static final String NAME_ATTR = "name"; // NOI18N
064:
065: public static final String COLUMNS_ATTR = "columns"; // NOI18N
066:
067: /* Name of this key; may be null */
068: private String name;
069:
070: /* DBTable to which this PK belongs */
071: private DBTable parent;
072:
073: /* List of column names in key sequence order. */
074: private List columnNames;
075:
076: private PrimaryKeyImpl() {
077: this .name = null;
078: this .columnNames = new ArrayList();
079: }
080:
081: /**
082: * Creates a new instance of PrimaryKey with the given key name and referencing the column names
083: * in the given List.
084: *
085: * @param keyName name, if any, of this PrimaryKey
086: * @param keyColumnNames List of Column objects, or column names in key sequence order,
087: * depending on state of isStringList
088: * @param isStringList true if keyColumnName contains column names in key sequence order, false
089: * if it contains Column objects which need to be sorted in key sequence order.
090: */
091: public PrimaryKeyImpl(final String keyName,
092: final List keyColumnNames, final boolean isStringList) {
093: this ();
094: this .name = keyName;
095:
096: if (isStringList) {
097: this .columnNames.addAll(keyColumnNames);
098: } else {
099: Collections.sort(keyColumnNames);
100: final Iterator iter = keyColumnNames.iterator();
101: while (iter.hasNext()) {
102: final PrimaryKeyImpl.Column col = (PrimaryKeyImpl.Column) iter
103: .next();
104: this .columnNames.add(col.getName());
105: }
106: }
107: }
108:
109: /**
110: * Creates a new instance of PrimaryKeyImpl, cloning the contents of the given PrimaryKey
111: * implementation instance.
112: *
113: * @param src PrimaryKey to be cloned
114: */
115: public PrimaryKeyImpl(final PrimaryKey src) {
116: this ();
117:
118: if (src == null) {
119: final ResourceBundle cMessages = NbBundle
120: .getBundle(PrimaryKeyImpl.class);
121: throw new IllegalArgumentException(cMessages
122: .getString("ERROR_NULL_PK")
123: + "ERROR_NULL_PK");// NO
124: // i18n
125: }
126:
127: this .copyFrom(src);
128: }
129:
130: /**
131: * @see com.stc.model.database.PrimaryKey#getName
132: */
133: public String getName() {
134: return this .name;
135: }
136:
137: /**
138: * @see com.stc.model.database.PrimaryKey#getColumnNames
139: */
140: public List getColumnNames() {
141: return Collections.unmodifiableList(this .columnNames);
142: }
143:
144: /**
145: * @see com.stc.model.database.PrimaryKey#getParent
146: */
147: public DBTable getParent() {
148: return this .parent;
149: }
150:
151: /**
152: * Sets reference to DBTable that owns this primary key.
153: *
154: * @param newParent new parent of this primary key.
155: */
156: void setParent(final DBTable newParent) {
157: this .parent = newParent;
158: }
159:
160: /**
161: * @see com.stc.model.database.PrimaryKey#contains(String)
162: */
163: public boolean contains(final String columnName) {
164: return this .columnNames.contains(columnName);
165: }
166:
167: /**
168: * @see com.stc.model.database.PrimaryKey#contains(DBColumn)
169: */
170: public boolean contains(final DBColumn col) {
171: return this .contains(col.getName());
172: }
173:
174: /**
175: * Create a clone of this PrimaryKeyImpl.
176: *
177: * @return cloned copy of DBColumn.
178: */
179: public Object clone() {
180: try {
181: final PrimaryKeyImpl impl = (PrimaryKeyImpl) super .clone();
182: impl.columnNames = new ArrayList(this .columnNames);
183: return impl;
184: } catch (final CloneNotSupportedException e) {
185: throw new InternalError(e.toString());
186: }
187: }
188:
189: /**
190: * Overrides default implementation to return value based on memberwise comparison.
191: *
192: * @param refObj Object against which we compare this instance
193: * @return true if refObj is functionally identical to this instance; false otherwise
194: */
195: public boolean equals(final Object refObj) {
196: if (this == refObj) {
197: return true;
198: }
199:
200: if (!(refObj instanceof PrimaryKeyImpl)) {
201: return false;
202: }
203:
204: final PrimaryKeyImpl ref = (PrimaryKeyImpl) refObj;
205:
206: boolean result = this .name != null ? this .name.equals(ref.name)
207: : ref.name == null;
208:
209: result &= this .columnNames != null ? this .columnNames
210: .equals(ref.columnNames) : ref.columnNames != null;
211:
212: return result;
213: }
214:
215: /**
216: * Overrides default implementation to compute hashCode value for those members used in equals()
217: * for comparison.
218: *
219: * @return hash code for this object
220: * @see java.lang.Object#hashCode
221: */
222: public int hashCode() {
223: int myHash = this .name != null ? this .name.hashCode() : 0;
224: myHash += this .columnNames != null ? this .columnNames
225: .hashCode() : 0;
226:
227: return myHash;
228: }
229:
230: /**
231: * @see com.stc.model.database.PrimaryKey#getSequence(DBColumn)
232: */
233: public int getSequence(final DBColumn col) {
234: if (col == null || col.getName() == null) {
235: return -1;
236: }
237:
238: return this .getSequence(col.getName().trim());
239: }
240:
241: /**
242: * @see com.stc.model.database.PrimaryKey#getSequence(String)
243: */
244: public int getSequence(final String columnName) {
245: return this .columnNames.indexOf(columnName);
246: }
247:
248: /**
249: * Replaces the current List of column names with the contents of the given String array.
250: *
251: * @param newColNames array of names to supplant current list of column names
252: */
253: public void setColumnNames(final String[] newColNames) {
254: if (newColNames == null) {
255: final ResourceBundle cMessages = NbBundle
256: .getBundle(PrimaryKeyImpl.class);
257: throw new IllegalArgumentException(cMessages
258: .getString("ERROR_COL_NAMES")
259: + "ERROR_COL_NAMES");// NO
260: // i18n
261: }
262:
263: this .columnNames.clear();
264: for (int i = 0; i < newColNames.length; i++) {
265: this .columnNames.add(newColNames[i]);
266: }
267: }
268:
269: /**
270: * @see com.stc.model.database.PrimaryKey#getColumnCount
271: */
272: public int getColumnCount() {
273: return this .columnNames.size();
274: }
275:
276: /**
277: * @see com.stc.model.database.PrimaryKey#getDBColumn
278: */
279: public String getDBColumnName(final int iColumn) {
280: return (String) this .columnNames.get(iColumn);
281: }
282:
283: /**
284: * @see com.stc.model.database.PrimaryKey#isReferencedBy
285: */
286: public boolean isReferencedBy(final ForeignKey fk) {
287: return fk != null ? fk.references(this ) : false;
288: }
289:
290: private void copyFrom(final PrimaryKey src) {
291: this .name = src.getName();
292: this .parent = src.getParent();
293:
294: this .columnNames.clear();
295: this .columnNames.addAll(src.getColumnNames());
296: }
297:
298: public static class Column implements Comparable {
299: private String name;
300:
301: private int sequence;
302:
303: public Column(final String colName, final int colSequence) {
304: final ResourceBundle cMessages = NbBundle
305: .getBundle(PrimaryKeyImpl.class);
306:
307: if (colName == null || colName.trim().length() == 0) {
308: throw new IllegalArgumentException(cMessages
309: .getString("ERROR_COL_NAME")
310: + "ERROR_COL_NAME");// NO
311: // i18n
312:
313: }
314:
315: if (colSequence <= 0) {
316: throw new IllegalArgumentException(cMessages
317: .getString("ERROR_COL_SEQ")
318: + "ERROR_COL_SEQ");// NO
319: // i18n
320: }
321:
322: this .name = colName;
323: this .sequence = colSequence;
324: }
325:
326: public Column(final DBColumn col, final int colSequence) {
327: this (col.getName(), colSequence);
328: }
329:
330: public String getName() {
331: return this .name;
332: }
333:
334: public int getSequence() {
335: return this .sequence;
336: }
337:
338: /**
339: * Compares this object with the specified object for order. Returns a negative integer,
340: * zero, or a positive integer as this object is less than, equal to, or greater than the
341: * specified object.
342: * <p>
343: * Note: this class has a natural ordering that is inconsistent with equals.
344: *
345: * @param o the Object to be compared.
346: * @return a negative integer, zero, or a positive integer as this object is less than,
347: * equal to, or greater than the specified object.
348: */
349: public int compareTo(final Object o) {
350: return this .sequence - ((Column) o).sequence;
351: }
352: }
353: }
|