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: package org.apache.openjpa.jdbc.schema;
020:
021: import java.util.ArrayList;
022: import java.util.List;
023:
024: import org.apache.commons.lang.ObjectUtils;
025: import org.apache.openjpa.lib.util.Localizer;
026: import org.apache.openjpa.util.InvalidStateException;
027:
028: /**
029: * Constraint over local table columns, as opposed to a foreign key which
030: * spans tables. Column APIs can represent a full constraint or a partial
031: * constraint, aligning with {@link java.sql.DatabaseMetaData}.
032: *
033: * @author Abe White
034: */
035: public abstract class LocalConstraint extends Constraint {
036:
037: private static final Localizer _loc = Localizer
038: .forPackage(LocalConstraint.class);
039:
040: private List _colList = null;
041: private Column[] _cols = null;
042:
043: /**
044: * Default constructor.
045: */
046: public LocalConstraint() {
047: }
048:
049: /**
050: * Constructor.
051: *
052: * @param name the name of the constraint, if any
053: * @param table the table of the constraint
054: */
055: public LocalConstraint(String name, Table table) {
056: super (name, table);
057: }
058:
059: /**
060: * Called when the constraint is removed from its table.
061: */
062: void remove() {
063: // remove all columns
064: setColumns(null);
065: super .remove();
066: }
067:
068: /**
069: * Return all the columns the constraint spans.
070: */
071: public Column[] getColumns() {
072: if (_cols == null)
073: _cols = (_colList == null) ? Schemas.EMPTY_COLUMNS
074: : (Column[]) _colList.toArray(new Column[_colList
075: .size()]);
076: return _cols;
077: }
078:
079: /**
080: * Set the columns the constraint spans.
081: */
082: public void setColumns(Column[] cols) {
083: Column[] cur = getColumns();
084: for (int i = 0; i < cur.length; i++)
085: removeColumn(cur[i]);
086:
087: if (cols != null)
088: for (int i = 0; i < cols.length; i++)
089: addColumn(cols[i]);
090: }
091:
092: /**
093: * Add a column to the constraint.
094: */
095: public void addColumn(Column col) {
096: if (col == null)
097: throw new InvalidStateException(_loc.get("table-mismatch",
098: col == null ? null : col.getTable(),
099: col == null ? null : getTable()));
100:
101: if (_colList == null)
102: _colList = new ArrayList(3);
103: else if (_colList.contains(col))
104: return;
105:
106: _colList.add(col);
107: _cols = null;
108: }
109:
110: /**
111: * Remove a column from the constraint.
112: *
113: * @return true if the column was removed, false if not part of the
114: * primary key
115: */
116: public boolean removeColumn(Column col) {
117: if (col == null || _colList == null)
118: return false;
119: if (_colList.remove(col)) {
120: _cols = null;
121: return true;
122: }
123: return false;
124: }
125:
126: /**
127: * Return true if the pk includes the given column.
128: */
129: public boolean containsColumn(Column col) {
130: if (col == null || _colList == null)
131: return false;
132: return _colList.contains(col);
133: }
134:
135: /**
136: * Ref all columns in this constraint.
137: */
138: public void refColumns() {
139: Column[] cols = getColumns();
140: for (int i = 0; i < cols.length; i++)
141: cols[i].ref();
142: }
143:
144: /**
145: * Deref all columns in this constraint.
146: */
147: public void derefColumns() {
148: Column[] cols = getColumns();
149: for (int i = 0; i < cols.length; i++)
150: cols[i].deref();
151: }
152:
153: /**
154: * Return true if the given columns match the columns of this constraint.
155: */
156: public boolean columnsMatch(Column[] ocols) {
157: Column[] cols = getColumns();
158: if (cols.length != ocols.length)
159: return false;
160: for (int i = 0; i < ocols.length; i++)
161: if (!hasColumn(cols, ocols[i]))
162: return false;
163: return true;
164: }
165:
166: /**
167: * Return whether the given column exists in the array.
168: */
169: private static boolean hasColumn(Column[] cols, Column col) {
170: for (int i = 0; i < cols.length; i++)
171: if (cols[i].getFullName().equalsIgnoreCase(
172: col.getFullName()))
173: return true;
174: return false;
175: }
176:
177: /**
178: * Return true if the columns of this constraint matches that of
179: * the given one. The constraints are not compared on name.
180: */
181: protected boolean equalsLocalConstraint(LocalConstraint lc) {
182: if (lc == this )
183: return true;
184: if (lc == null)
185: return false;
186: return columnsMatch(lc.getColumns());
187: }
188: }
|