| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.jdbc.schema; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.openjpa.jdbc.identifier.DBIdentifier; |
| import org.apache.openjpa.lib.util.Localizer; |
| import org.apache.openjpa.util.InvalidStateException; |
| |
| /** |
| * Constraint over local table columns, as opposed to a foreign key which |
| * spans tables. Column APIs can represent a full constraint or a partial |
| * constraint, aligning with {@link java.sql.DatabaseMetaData}. |
| * |
| * @author Abe White |
| */ |
| public abstract class LocalConstraint extends Constraint { |
| private static final long serialVersionUID = 1L; |
| |
| private static final Localizer _loc = Localizer.forPackage |
| (LocalConstraint.class); |
| |
| private List<Column> _colList = null; |
| private Column[] _cols = null; |
| |
| /** |
| * Default constructor. |
| */ |
| public LocalConstraint() { |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param name the name of the constraint, if any |
| * @param table the table of the constraint |
| * @deprecated |
| */ |
| @Deprecated |
| public LocalConstraint(String name, Table table) { |
| super(name, table); |
| } |
| |
| public LocalConstraint(DBIdentifier name, Table table) { |
| super(name, table); |
| } |
| /** |
| * Called when the constraint is removed from its table. |
| */ |
| @Override |
| void remove() { |
| // remove all columns |
| for (Column c : _cols) { |
| c.removeConstraint(this); |
| } |
| setColumns(null); |
| super.remove(); |
| } |
| |
| /** |
| * Return all the columns the constraint spans. |
| */ |
| public Column[] getColumns() { |
| if (_cols == null) |
| _cols = (_colList == null) ? Schemas.EMPTY_COLUMNS |
| : (Column[]) _colList.toArray(new Column[_colList.size()]); |
| return _cols; |
| } |
| |
| /** |
| * Set the columns the constraint spans. |
| */ |
| public void setColumns(Column[] cols) { |
| Column[] cur = getColumns(); |
| for (Column column : cur) { |
| removeColumn(column); |
| } |
| |
| if (cols != null) |
| for (Column col : cols) { |
| addColumn(col); |
| } |
| } |
| |
| /** |
| * Add a column to the constraint. |
| */ |
| public void addColumn(Column col) { |
| if (col == null) |
| throw new InvalidStateException(_loc.get("table-mismatch", |
| col == null ? null : col.getTable(), |
| col == null ? null : getTable())); |
| |
| if (_colList == null) |
| _colList = new ArrayList<>(3); |
| else if (_colList.contains(col)) |
| return; |
| |
| _colList.add(col); |
| _cols = null; |
| col.addConstraint(this); |
| } |
| |
| /** |
| * Remove a column from the constraint. |
| * |
| * @return true if the column was removed, false if not part of the |
| * primary key |
| */ |
| public boolean removeColumn(Column col) { |
| if (col == null || _colList == null) |
| return false; |
| if (_colList.remove(col)) { |
| _cols = null; |
| col.removeConstraint(this); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Return true if the pk includes the given column. |
| */ |
| public boolean containsColumn(Column col) { |
| if (col == null || _colList == null) |
| return false; |
| return _colList.contains(col); |
| } |
| |
| /** |
| * Ref all columns in this constraint. |
| */ |
| public void refColumns() { |
| Column[] cols = getColumns(); |
| for (Column col : cols) { |
| col.ref(); |
| } |
| } |
| |
| /** |
| * Deref all columns in this constraint. |
| */ |
| public void derefColumns() { |
| Column[] cols = getColumns(); |
| for (Column col : cols) { |
| col.deref(); |
| } |
| } |
| |
| /** |
| * Return true if the given columns match the columns of this constraint. |
| */ |
| public boolean columnsMatch(Column[] ocols) { |
| Column[] cols = getColumns(); |
| if (cols.length != ocols.length) |
| return false; |
| for (Column ocol : ocols) |
| if (!hasColumn(cols, ocol)) |
| return false; |
| return true; |
| } |
| |
| /** |
| * Return whether the given column exists in the array. |
| */ |
| private static boolean hasColumn(Column[] cols, Column col) { |
| for (Column column : cols) |
| if (column.getQualifiedPath().equals(col.getQualifiedPath())) |
| return true; |
| return false; |
| } |
| |
| /** |
| * Return true if the columns of this constraint matches that of |
| * the given one. The constraints are not compared on name. |
| */ |
| protected boolean equalsLocalConstraint(LocalConstraint lc) { |
| if (lc == this) |
| return true; |
| if (lc == null) |
| return false; |
| return columnsMatch(lc.getColumns()); |
| } |
| } |