/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.transformation.ui.wizards.file;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.StringConstants;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.metamodels.relational.aspects.validation.RelationalStringNameValidator;
import org.teiid.designer.query.IQueryFactory;
import org.teiid.designer.query.IQueryService;
import org.teiid.designer.query.proc.ITeiidColumnInfo;
import org.teiid.designer.query.sql.symbol.IElementSymbol;
import org.teiid.designer.transformation.ui.wizards.xmlfile.XmlAttribute;
import org.teiid.designer.transformation.ui.wizards.xmlfile.XmlElement;
/**
* A <code>TeiidColumnInfo</code> defines extension properties for metaclasses within a metamodel.
*
* @since 8.0
*/
public class TeiidColumnInfo implements ITeiidColumnInfo {
private static final IPath EMPTY_PATH = new Path(StringConstants.EMPTY_STRING);
/**
* The unique column name (never <code>null</code> or empty).
*/
private IElementSymbol nameSymbol;
/**
* The unique column datatype (never <code>null</code> or empty).
*/
private String datatype;
/**
* The column width value
*/
private int width = DEFAULT_WIDTH;
/**
* The unique column datatype (never <code>null</code> or empty).
*/
private boolean forOrdinality;
/**
* The unique column datatype (never <code>null</code> or empty).
*/
private String defaultValue = StringConstants.EMPTY_STRING;
/**
* The full xml path
*/
private IPath fullXmlPath = EMPTY_PATH;
/**
* The root xml path
*/
private IPath rootXmlPath = EMPTY_PATH;
/**
* The xml element
*/
private XmlElement xmlElement;
/**
* The xml attribute
*/
private XmlAttribute xmlAttribute;
private boolean noTrim;
/**
* Current <code>IStatus</code> representing the state of the input values for this instance of
* <code>TeiidColumnInfo</code>
*/
private IStatus status;
RelationalStringNameValidator validator = new RelationalStringNameValidator(true);
/**
*
* @param name the column name (never <code>null</code> or empty).
*/
public TeiidColumnInfo(String name) {
this(name, DEFAULT_DATATYPE);
}
/**
*
* @param name the column name (never <code>null</code> or empty).
* @param datatype the column datatype (never <code>null</code> or empty).
*/
public TeiidColumnInfo(String name, String datatype) {
super();
CoreArgCheck.isNotEmpty(name, "name is null"); //$NON-NLS-1$
CoreArgCheck.isNotEmpty(datatype, "datatype is null"); //$NON-NLS-1$
initNameSymbol(name);
this.datatype = datatype;
validate();
}
/**
*
* @param name the column name (never <code>null</code> or empty).
* @param datatype the column datatype (never <code>null</code> or empty).
*/
public TeiidColumnInfo(String name, String datatype, int width) {
this(name, datatype);
CoreArgCheck.isPositive(width, "width is zero or less"); //$NON-NLS-1$
this.width = width;
}
/**
*
* @param name the column name (never <code>null</code> or empty).
* @param datatype the column datatype (never <code>null</code> or empty).
*/
public TeiidColumnInfo(String name, boolean ordinality, String datatype, String defaultValue, String fullXmlPath ) {
this(name, datatype);
this.forOrdinality = ordinality;
if( defaultValue == null ) {
this.defaultValue = StringConstants.EMPTY_STRING;
} else {
this.defaultValue = defaultValue;
}
if( fullXmlPath == null ) {
this.fullXmlPath = EMPTY_PATH;
} else {
this.fullXmlPath = new Path(fullXmlPath);
}
validate();
}
/**
* Initialise the {@link ElementSymbol} to hold the
* name. This validates the symbol's character composition.
*
* The '.' character is the only puntuation symbol that will cause
* problems for an element symbol so these are replaced these with '_'.
*/
private void initNameSymbol(final String name) {
IQueryService queryService = ModelerCore.getTeiidQueryService();
IQueryFactory factory = queryService.createQueryFactory();
nameSymbol = factory.createElementSymbol(name.replaceAll("\\.", "_")); //$NON-NLS-1$//$NON-NLS-2$
}
/**
* Get the fully validated column name. This should be used in SQL string
* generation.
*
* @return name the column name
*/
@Override
public String getSymbolName() {
return this.nameSymbol.toString();
}
/**
* Get the column name for display in the UI. This removes any quotes for
* aesthetic reasons. Use {@link #getSymbolName()} for retrieving the
* fully validated column name.
*
* @return the column name sans quotes.
*/
@Override
public String getName() {
String name = this.nameSymbol.toString();
return name.replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
*
* @param name the column name (never <code>null</code> or empty).
*/
public void setName(String name) {
CoreArgCheck.isNotNull(name, "name is null"); //$NON-NLS-1$
initNameSymbol(name);
validate();
}
/**
*
* @return datatype the column datatype
*/
@Override
public String getDatatype() {
return this.datatype;
}
/**
*
* @param datatype the column datatype (never <code>null</code> or empty).
*/
public void setDatatype(String datatype) {
CoreArgCheck.isNotNull(datatype, "datatype is null"); //$NON-NLS-1$
this.datatype = datatype;
validate();
}
/**
*
* @return name the column name
*/
@Override
public int getWidth() {
return this.width;
}
/**
*
* @param name the column name (never <code>null</code> or empty).
*/
public void setWidth(int width) {
CoreArgCheck.isPositive(width, "width is less than 1"); //$NON-NLS-1$
this.width = width;
validate();
}
/**
*
* @return defaultValue the column defaultValue
*/
@Override
public String getDefaultValue() {
return this.defaultValue;
}
/**
*
* @param defaultValue the column defaultValue
*/
public void setDefaultValue(String defaultValue) {
if( defaultValue == null ) {
this.defaultValue = StringConstants.EMPTY_STRING;
} else {
this.defaultValue = defaultValue;
}
validate();
}
/**
*
* @param xmlPath the column xmlPath
*/
public void setRelativePath(String relativePath) {
if( relativePath == null ) {
this.fullXmlPath = this.rootXmlPath;
} else {
this.fullXmlPath = this.rootXmlPath.append(relativePath);
}
}
/**
*
* @return xmlPath the column xmlPath
*/
@Override
public String getRelativePath() {
if( this.xmlElement != null ) {
// Get difference between the xmlElement full path minus the root (if applicable)
String fullPath = getFullXmlPath();
String rootPath = this.rootXmlPath.toString();
if( fullPath.startsWith(rootPath) ) {
return fullPath.substring(rootPath.length(), fullPath.length());
}
}
if( !this.fullXmlPath.isEmpty() ) {
if( !this.rootXmlPath.isEmpty() && this.fullXmlPath.toString().indexOf(rootXmlPath.toString()) > -1) {
return '/' + this.fullXmlPath.removeFirstSegments(this.rootXmlPath.segmentCount()).toString();
} else {
return this.fullXmlPath.toString();
}
}
return StringConstants.EMPTY_STRING;
}
public void setXmlElement(XmlElement element) {
this.xmlElement = element;
}
public void setXmlAttribute(XmlAttribute attribute) {
this.xmlAttribute = attribute;
this.xmlElement = attribute.getElement();
}
/**
*
* @return xmlPath the column xmlPath
*/
public String getFullXmlPath() {
if( isXmlAttribute() ) {
String theFullPath = null;
if( this.xmlElement != null ) {
theFullPath = this.xmlElement.getFullPath() + "/@" + this.xmlAttribute.getName(); //$NON-NLS-1$
} else {
theFullPath = this.fullXmlPath.toString();
}
return theFullPath;
} else {
if( this.xmlElement != null ) {
return this.xmlElement.getFullPath();
}
return this.fullXmlPath.toString();
}
}
/**
*
* @param xmlPath the column xmlPath
*/
public void setFullXmlPath(String fullPath) {
if( fullPath == null ) {
this.fullXmlPath = EMPTY_PATH;
} else {
this.fullXmlPath = new Path(fullPath);
}
}
public void setRootPath(String thePath) {
if( thePath != null && thePath.length() > 0 ) {
// Need to remove the OLD root path from FULL path
IPath oldRelativePath = new Path(getRelativePath());
String tmpRoot = thePath;
if( thePath.endsWith("/")) { //$NON-NLS-1$
tmpRoot = tmpRoot.substring(0, thePath.length()-1);
}
String newFullPath = tmpRoot + oldRelativePath;
setFullXmlPath(newFullPath); //tmpRoot + oldRelativePath.toString());
this.rootXmlPath = new Path(thePath);
} else {
this.rootXmlPath = EMPTY_PATH;
}
}
/**
*
* @return xmlElement the xmlElement
*/
public XmlElement getXmlElement() {
return this.xmlElement;
}
/**
*
* @return xmlElement the xmlAttribute
*/
public XmlAttribute getXmlAttribute() {
return this.xmlAttribute;
}
public boolean isXmlAttribute() {
return this.xmlAttribute != null;
}
/**
*
* @return forOrdinality the column forOrdinality
*/
@Override
public boolean getOrdinality() {
return this.forOrdinality;
}
/**
*
* @param forOrdinality the column forOrdinality
*/
public void setOrdinality(boolean value) {
this.forOrdinality = value;
validate();
}
/**
*
* @return no trim value
*/
@Override
public boolean isNoTrim() {
return noTrim;
}
/**
*
* @param noTrim
*/
public void setNoTrim(boolean noTrim) {
this.noTrim = noTrim;
}
/**
*
* @return status the <code>IStatus</code> representing the validity of the data in this info object
*/
@Override
public IStatus getStatus() {
return this.status;
}
/**
*
* @param status the <code>IStatus</code> representing the validity of the data in this info object
*/
public void setStatus(IStatus status) {
this.status = status;
}
private void validate() {
/*
* No validation is currently required since the name is automatically
* 'fixed' by the teiid element symbol. If validation is required on
* other fields then a failure should be captured by setting the status,
* eg.
*
* setStatus(new Status(IStatus.ERROR, UiConstants.PLUGIN_ID,
* UiConstants
* .Util.getString("TeiidColumnInfo.status.invalidColumnName",
* getName()))); //$NON-NLS-1$
*/
setStatus(Status.OK_STATUS);
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder text = new StringBuilder();
text.append("Teiid Metadata Column Info: "); //$NON-NLS-1$
text.append("name =").append(getName()); //$NON-NLS-1$
text.append("symbol name = ").append(getSymbolName()); //$NON-NLS-1$
text.append(", datatype =").append(getDatatype()); //$NON-NLS-1$
return text.toString();
}
}