All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dk.eobjects.metamodel.schema.Table Maven / Gradle / Ivy

Go to download

The eobjects.dk MetaModel is a common domain model, query-engine and optimizer for different kinds of datastores.

The newest version!
/*
 * Copyright 2008 eobjects.dk
 *
 * Licensed 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 dk.eobjects.metamodel.schema;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * Represents the metadata about a table. Tables reside within a schema and
 * contains columns and relationships to other tables.
 * 
 * @see Schema
 * @see Column
 * @see Relationship
 */
public class Table implements Serializable, Comparable {

	private static final long serialVersionUID = -5094888465714027354L;
	private String _name;
	private TableType _type;
	private String _remarks;
	private Schema _schema;
	private List _columns = new ArrayList();
	private List _relationships = new ArrayList();
	private String _quoteString = null;

	public Table() {
	}

	public Table(String name) {
		this();
		setName(name);
	}

	public Table(String name, TableType type) {
		this(name);
		setType(type);
	}

	public Table(String name, TableType type, Schema schema) {
		this(name, type);
		setSchema(schema);
	}

	public Table(String name, TableType type, Schema schema, Column... columns) {
		this(name, type, schema);
		setColumns(columns);
	}

	/**
	 * @return the name of the table
	 */
	public String getName() {
		return _name;
	}

	public Table setName(String name) {
		_name = name;
		return this;
	}

	/**
	 * Internal getter for the columns of the table. Overwrite this method to
	 * implement column lookup, column lazy-loading or similar.
	 */
	protected List getColumnsInternal() {
		return _columns;
	}

	/**
	 * Internal getter for the relationships of the table. Overwrite this method
	 * to implement relationship lookup, relationship lazy-loading or similar.
	 */
	protected List getRelationshipsInternal() {
		return _relationships;
	}

	/**
	 * @return the number of columns in this table
	 */
	public int getColumnCount() {
		return getColumnsInternal().size();
	}

	/**
	 * @return the columns of the table
	 */
	public Column[] getColumns() {
		List columns = getColumnsInternal();
		return columns.toArray(new Column[columns.size()]);
	}

	public Table setColumns(Column... columns) {
		List existingColumns = getColumnsInternal();
		existingColumns.clear();
		for (Column column : columns) {
			existingColumns.add(column);
		}
		return this;
	}

	public Table setColumns(Collection columns) {
		List existingColumns = getColumnsInternal();
		existingColumns.clear();
		for (Column column : columns) {
			existingColumns.add(column);
		}
		return this;
	}

	public Table addColumn(Column column) {
		getColumnsInternal().add(column);
		return this;
	}

	public Table removeColumn(Column column) {
		getColumnsInternal().remove(column);
		return this;
	}

	/**
	 * Convenience method for retrieving a column by it's name
	 * 
	 * @param columnName
	 *            the name of the column to retrieve
	 * @return the column with the given name. Returns null if no such column is
	 *         found.
	 */
	public Column getColumnByName(String columnName) {
		if (columnName != null) {
			List foundColumn = new ArrayList();
			// Search for column matches, case insensitive.
			for (Column column : getColumnsInternal()) {
				if (columnName.equalsIgnoreCase(column.getName())) {
					foundColumn.add(column);
				}
			}
			int numColumns = foundColumn.size();
			if (numColumns == 0) {
				return null;
			} else if (numColumns == 1) {
				return foundColumn.get(0);
			} else {
				// If more matches are found, search case sensitive
				for (Column column : foundColumn) {
					if (columnName.equals(column.getName())) {
						return column;
					}
				}
			}
		}
		return null;
	}

	/**
	 * @return the schema that the table belong to
	 */
	public Schema getSchema() {
		return _schema;
	}

	public Table setSchema(Schema schema) {
		_schema = schema;
		return this;
	}

	/**
	 * @return the type of table
	 */
	public TableType getType() {
		return _type;
	}

	public Table setType(TableType type) {
		_type = type;
		return this;
	}

	/**
	 * @return all relations for this table. To add relations use
	 *         TableRelation.createRelation();
	 */
	public Relationship[] getRelationships() {
		List relationships = getRelationshipsInternal();
		return relationships.toArray(new Relationship[relationships.size()]);
	}

	/**
	 * @param otherTable
	 * @return this tables relationsips to another table
	 */
	public Relationship[] getRelationships(Table otherTable) {
		List result = new ArrayList();
		List relationships = getRelationshipsInternal();
		for (Relationship relation : relationships) {
			if (relation.getForeignTable() == otherTable
					&& relation.getPrimaryTable() == this) {
				result.add(relation);
			} else if (relation.getForeignTable() == this
					&& relation.getPrimaryTable() == otherTable) {
				result.add(relation);
			}
		}
		return result.toArray(new Relationship[result.size()]);
	}

	/**
	 * Protected method for adding a relationship to this table. Should not be
	 * used. Use Relationship.createRelationship(Column[], Column[]) instead.
	 */
	protected Table addRelationship(Relationship relation) {
		getRelationshipsInternal().add(relation);
		return this;
	}

	/**
	 * Protected method for removing a relationship from this table. Should not
	 * be used. Use Relationship.remove() instead.
	 */
	protected Table removeRelationship(Relationship relation) {
		getRelationshipsInternal().remove(relation);
		return this;
	}

	public int getRelationshipCount() {
		return getRelationshipsInternal().size();
	}

	public String getRemarks() {
		return _remarks;
	}

	public void setRemarks(String remarks) {
		_remarks = remarks;
	}

	public String getQuote() {
		return _quoteString;
	}

	public Table setQuote(String quoteString) {
		_quoteString = quoteString;
		return this;
	}

	public String getQuotedName() {
		if (_quoteString != null) {
			return _quoteString + getName() + _quoteString;
		}
		return getName();
	}

	public Column[] getNumberColumns() {
		List result = new ArrayList();
		Column[] columns = getColumns();
		for (int i = 0; i < columns.length; i++) {
			if (columns[i].getType() != null && columns[i].getType().isNumber()) {
				result.add(columns[i]);
			}
		}
		return result.toArray(new Column[result.size()]);
	}

	public Column[] getLiteralColumns() {
		List result = new ArrayList();
		Column[] columns = getColumns();
		for (int i = 0; i < columns.length; i++) {
			if (columns[i].getType() != null
					&& columns[i].getType().isLiteral()) {
				result.add(columns[i]);
			}
		}
		return result.toArray(new Column[result.size()]);
	}

	public Column[] getTimeBasedColumns() {
		List result = new ArrayList();
		Column[] columns = getColumns();
		for (int i = 0; i < columns.length; i++) {
			if (columns[i].getType() != null
					&& columns[i].getType().isTimeBased()) {
				result.add(columns[i]);
			}
		}
		return result.toArray(new Column[result.size()]);
	}

	public Column[] getBooleanColumns() {
		List result = new ArrayList();
		Column[] columns = getColumns();
		for (int i = 0; i < columns.length; i++) {
			if (columns[i].getType() != null
					&& columns[i].getType().isBoolean()) {
				result.add(columns[i]);
			}
		}
		return result.toArray(new Column[result.size()]);
	}

	public Column[] getIndexedColumns() {
		List result = new ArrayList();
		Column[] columns = getColumns();
		for (int i = 0; i < columns.length; i++) {
			if (columns[i].isIndexed()) {
				result.add(columns[i]);
			}
		}
		return result.toArray(new Column[result.size()]);
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
				.append("name", _name).append("type", _type).append("remarks",
						_remarks).toString();
	}

	@Override
	public int hashCode() {
		HashCodeBuilder hcb = new HashCodeBuilder();
		hcb.append(_name).append(getColumnsInternal()).append(_type).append(
				getRelationshipsInternal()).append(_remarks);
		return hcb.toHashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (obj instanceof Table) {
			Table that = (Table) obj;
			return new EqualsBuilder().append(this.getName(), that.getName())
					.append(this.getType(), that.getType()).append(
							this.getRemarks(), that.getRemarks()).append(
							this.getColumns(), that.getColumns()).append(
							this.getRelationships(), that.getRelationships())
					.isEquals();
		}
		return false;
	}

	public int compareTo(Table that) {
		CompareToBuilder ctb = new CompareToBuilder();
		ctb.append(this.getName(), that.getName());
		ctb.append(this.getSchema(), that.getSchema());
		return ctb.toComparison();
	}

	public Relationship[] getForeignKeyRelationships() {
		List result = new ArrayList();
		Relationship[] relationships = getRelationships();
		for (Relationship relationship : relationships) {
			if (equals(relationship.getForeignTable())) {
				result.add(relationship);
			}
		}
		return result.toArray(new Relationship[result.size()]);
	}

	public Relationship[] getPrimaryKeyRelationships() {
		List result = new ArrayList();
		Relationship[] relationships = getRelationships();
		for (Relationship relationship : relationships) {
			if (equals(relationship.getPrimaryTable())) {
				result.add(relationship);
			}
		}
		return result.toArray(new Relationship[result.size()]);
	}

	public Column[] getForeignKeys() {
		Set columns = new HashSet();
		Relationship[] relationships = getForeignKeyRelationships();
		for (Relationship relationship : relationships) {
			Column[] foreignColumns = relationship.getForeignColumns();
			for (Column column : foreignColumns) {
				columns.add(column);
			}
		}
		return columns.toArray(new Column[columns.size()]);
	}

	public Column[] getPrimaryKeys() {
		Set columns = new HashSet();
		Relationship[] relationships = getPrimaryKeyRelationships();
		for (Relationship relationship : relationships) {
			Column[] foreignColumns = relationship.getPrimaryColumns();
			for (Column column : foreignColumns) {
				columns.add(column);
			}
		}
		return columns.toArray(new Column[columns.size()]);
	}
}