blob: 77c30a00a5496a48d61654ee850e12d0e4b226f0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.platformsmodel;
import java.util.Iterator;
import java.util.List;
import org.eclipse.persistence.tools.workbench.utility.ClassTools;
import org.eclipse.persistence.tools.workbench.utility.XMLTools;
import org.eclipse.persistence.tools.workbench.utility.node.AbstractNodeModel;
import org.w3c.dom.Node;
/**
* A database type holds all the settings for a platform-specific database type.
* For example, the Oracle database type VARCHAR2
* - maps to the JDBC type VARCHAR
* - allows and requires a size specification
* - has a initial size of 20 when generating tables
* - does not allow a sub-size specification
* - allows a null value
*/
public final class DatabaseType
extends AbstractNodeModel
{
/**
* a name uniquely identifying the type within a
* database platform
*/
private String name;
public static final String NAME_PROPERTY = "name";
/**
* the JDBC type most closely resembling the
* platform-specific database type
*/
private JDBCType jdbcType;
public static final String JDBC_TYPE_PROPERTY = "jdbcType";
/**
* whether the type can be declared with a size
*/
private boolean allowsSize;
public static final String ALLOWS_SIZE_PROPERTY = "allowsSize";
/**
* whether the type *requires* a size...
*/
private boolean requiresSize;
public static final String REQUIRES_SIZE_PROPERTY = "requiresSize";
/**
* ...and, if it does, what the initial size should be
*/
private int initialSize;
public static final String INITIAL_SIZE_PROPERTY = "initialSize";
/**
* whether the type can be declared with a "sub-size";
* this is typically a numeric scale
*/
private boolean allowsSubSize;
public static final String ALLOWS_SUB_SIZE_PROPERTY = "allowsSubSize";
/**
* whether the type allows NULL values
*/
private boolean allowsNull;
public static final String ALLOWS_NULL_PROPERTY = "allowsNull";
// ********** constructors **********
/**
* this constructor is called when the type is read from an XML file
*/
DatabaseType(DatabasePlatform platform, Node node) throws CorruptXMLException {
super(platform);
this.read(node);
}
/**
* this constructor is called when the user (or a test case)
* creates a new type (which shouldn't happen very often,
* since all the typical platforms have already been built...)
*/
DatabaseType(DatabasePlatform platform, String name) {
super(platform);
this.name = name;
this.jdbcType = this.jdbcTypeRepository().getDefaultJDBCType();
}
// ********** initialization **********
/**
* @see org.eclipse.persistence.tools.workbench.utility.AbstractNodeModel#initialize()
*/
protected void initialize() {
super.initialize();
this.allowsSize = true;
this.requiresSize = false;
this.initialSize = 0;
this.allowsSubSize = false;
this.allowsNull = true;
}
// ********** accessors **********
public DatabasePlatform getPlatform() {
return (DatabasePlatform) this.getParent();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.getPlatform().checkDatabaseTypeName(name);
Object old = this.name;
this.name = name;
this.firePropertyChanged(NAME_PROPERTY, old, name);
}
public JDBCType getJDBCType() {
return this.jdbcType;
}
public void setJDBCType(JDBCType jdbcType) {
if (jdbcType == null) {
throw new NullPointerException();
}
Object old = this.jdbcType;
this.jdbcType = jdbcType;
this.firePropertyChanged(JDBC_TYPE_PROPERTY, old, jdbcType);
}
public boolean allowsSize() {
return this.allowsSize;
}
public void setAllowsSize(boolean allowsSize) {
boolean old = this.allowsSize;
this.allowsSize = allowsSize;
this.firePropertyChanged(ALLOWS_SIZE_PROPERTY, old, allowsSize);
// if size is not allowed, sub-size is not either and size cannot be required
if ( ! allowsSize) {
this.setAllowsSubSize(false);
this.setRequiresSize(false);
}
}
public boolean requiresSize() {
return this.requiresSize;
}
public void setRequiresSize(boolean requiresSize) {
boolean old = this.requiresSize;
this.requiresSize = requiresSize;
this.firePropertyChanged(REQUIRES_SIZE_PROPERTY, old, requiresSize);
// if size is required, size must be allowed...
if (requiresSize) {
this.setAllowsSize(true);
} else {
this.setInitialSize(0);
}
}
public int getInitialSize() {
return this.initialSize;
}
public void setInitialSize(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("initial size must be greater than or equal to zero" + initialSize);
}
int old = this.initialSize;
this.initialSize = initialSize;
this.firePropertyChanged(INITIAL_SIZE_PROPERTY, old, initialSize);
// if there is a initial size, it must be required
if (initialSize != 0) {
this.setRequiresSize(true);
}
}
public boolean allowsSubSize() {
return this.allowsSubSize;
}
public void setAllowsSubSize(boolean allowsSubSize) {
boolean old = this.allowsSubSize;
this.allowsSubSize = allowsSubSize;
this.firePropertyChanged(ALLOWS_SUB_SIZE_PROPERTY, old, allowsSubSize);
// if sub-size is allowed, size must be also
if (allowsSubSize) {
this.setAllowsSize(true);
}
}
public boolean allowsNull() {
return this.allowsNull;
}
public void setAllowsNull(boolean allowsNull) {
boolean old = this.allowsNull;
this.allowsNull = allowsNull;
this.firePropertyChanged(ALLOWS_NULL_PROPERTY, old, allowsNull);
}
// ********** queries **********
/**
* return a Java type declaration that can used for this database type;
* this is used for generating classes from tables
*/
public JavaTypeDeclaration javaTypeDeclaration() {
return this.jdbcTypeRepository().javaTypeDeclarationFor(this.getJDBCType());
}
private DatabasePlatformRepository platformRepository() {
return this.getPlatform().getRepository();
}
private JDBCTypeRepository jdbcTypeRepository() {
return this.platformRepository().getJDBCTypeRepository();
}
private JDBCType jdbcTypeNamed(String jdbcTypeName) {
return this.jdbcTypeRepository().jdbcTypeNamed(jdbcTypeName);
}
/**
* Return all the JDBC types that the database type
* could be mapped to. Simplifies UI code....
*/
public Iterator jdbcTypes() {
return this.jdbcTypeRepository().jdbcTypes();
}
/**
* Return the size of all the JDBC types that the database type
* could be mapped to. Simplifies UI code....
*/
public int jdbcTypesSize() {
return this.jdbcTypeRepository().jdbcTypesSize();
}
// ********** behavior **********
protected void addProblemsTo(List currentProblems) {
if (this.requiresSize() && (this.getInitialSize() == 0)) {
currentProblems.add(this.buildProblem("003", this.getPlatform().getName(), this.getName()));
}
super.addProblemsTo(currentProblems);
}
/**
* @see org.eclipse.persistence.tools.workbench.utility.AbstractNodeModel#nodeRemoved(org.eclipse.persistence.tools.workbench.utility.Node)
*/
public void nodeRemoved(org.eclipse.persistence.tools.workbench.utility.node.Node node) {
super.nodeRemoved(node);
if (this.jdbcType == node) {
this.setJDBCType(this.jdbcTypeRepository().getDefaultJDBCType());
}
}
/**
* copy all the settings from the original type
* to this, newly-created, type
*/
void cloneFrom(DatabaseType originalType) {
// the name has been set by the time we get here
this.setComment(originalType.getComment());
this.setJDBCType(originalType.getJDBCType()); // the JDBC type should NOT be cloned
this.setAllowsSize(originalType.allowsSize());
this.setRequiresSize(originalType.requiresSize());
this.setInitialSize(originalType.getInitialSize());
this.setAllowsSubSize(originalType.allowsSubSize());
this.setAllowsNull(originalType.allowsNull());
}
// ********** i/o **********
private void read(Node node) throws CorruptXMLException {
if (node == null) {
throw this.buildCorruptXMLException("missing node");
}
this.name = XMLTools.childTextContent(node, "name", null);
if ((this.name == null) || (this.name.length() == 0)) {
throw this.buildCorruptXMLException("name is required");
}
ClassTools.setFieldValue(this, "comment", XMLTools.childTextContent(node, "comment", ""));
String jdbcTypeName = XMLTools.childTextContent(node, "jdbc-type", null);
try {
this.jdbcType = this.jdbcTypeNamed(jdbcTypeName);
} catch (IllegalArgumentException ex) {
throw this.buildCorruptXMLException(ex);
}
this.allowsSize = XMLTools.childBooleanContent(node, "allows-size", false);
this.requiresSize = XMLTools.childBooleanContent(node, "requires-size", false);
if (( ! this.allowsSize) && this.requiresSize) {
throw this.buildCorruptXMLException("size cannot be required when it is not allowed");
}
this.initialSize = XMLTools.childIntContent(node, "initial-size", 0);
if (( ! this.requiresSize) && (this.initialSize != 0)) {
throw this.buildCorruptXMLException("initial size cannot be specified when size is not required");
}
this.allowsSubSize = XMLTools.childBooleanContent(node, "allows-sub-size", false);
if (( ! this.allowsSize) && this.allowsSubSize) {
throw this.buildCorruptXMLException("sub-size cannot be allowed when size is not allowed");
}
this.allowsNull = XMLTools.childBooleanContent(node, "allows-null", false);
}
/**
* tack on some more information on the message
*/
private CorruptXMLException buildCorruptXMLException(String message) {
return new CorruptXMLException(message + " (" + this.corruptXMLLocation() + ")");
}
/**
* tack on some more information on the message
*/
private CorruptXMLException buildCorruptXMLException(Throwable t) {
return new CorruptXMLException(this.corruptXMLLocation(), t);
}
private String corruptXMLLocation() {
return this.getPlatform().getName() + ":" + this.name;
}
void write(Node node) {
XMLTools.addSimpleTextNode(node, "name", this.name);
XMLTools.addSimpleTextNode(node, "comment", (String) ClassTools.getFieldValue(this, "comment"), "");
XMLTools.addSimpleTextNode(node, "jdbc-type", this.jdbcType.getName());
XMLTools.addSimpleTextNode(node, "allows-size", this.allowsSize, false);
XMLTools.addSimpleTextNode(node, "requires-size", this.requiresSize, false);
XMLTools.addSimpleTextNode(node, "initial-size", this.initialSize, 0);
XMLTools.addSimpleTextNode(node, "allows-sub-size", this.allowsSubSize, false);
XMLTools.addSimpleTextNode(node, "allows-null", this.allowsNull, false);
}
// ********** printing and displaying **********
/**
* @see org.eclipse.persistence.tools.workbench.utility.Node#displayString()
*/
public String displayString() {
return this.name;
}
/**
* @see org.eclipse.persistence.tools.workbench.utility.AbstractModel#toString(StringBuffer)
*/
public void toString(StringBuffer sb) {
sb.append(this.name);
}
}