/*
* 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.modelgenerator.wsdl.ui.wizards.soap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.teiid.core.designer.util.StringConstants;
import org.teiid.designer.core.validation.rules.StringNameValidator;
import org.teiid.designer.modelgenerator.wsdl.model.ModelGenerationException;
import org.teiid.designer.modelgenerator.wsdl.model.Operation;
import org.teiid.designer.modelgenerator.wsdl.model.impl.ModelImpl;
import org.teiid.designer.query.proc.wsdl.IWsdlColumnInfo;
import org.teiid.designer.query.proc.wsdl.IWsdlProcedureInfo;
import org.teiid.designer.query.sql.ISQLConstants;
/**
* @since 8.0
*/
public abstract class ProcedureInfo implements IWsdlProcedureInfo, ISQLConstants {
private StringNameValidator nameValidator;
public SchemaTreeModel treeModel = null;
/**
* @since 8.1
*/
public HashMap<String, String> reverseNSMap;
// CREATE VIRTUAL PROCEDURE
// BEGIN
// SELECT XMLELEMENT(NAME getPrice, XMLNAMESPACES(DEFAULT 'http://quickstart.samples/xsd'), XMLELEMENT(NAME symbol, StockQuoteServiceXML.getPrice.create_getPrice.symbol)) AS xml_out;
// END
private Collection<ColumnInfo> bodyColumnInfoList;
private Collection<ColumnInfo> headerColumnInfoList;
private Map<String, String> namespaceMap;
private Operation operation;
private ProcedureGenerator generator;
/**
* The unique procedureName defining a procedure containing the generated SELECT SQL statement
*/
private String procedureName;
/**
* An initial xquery root path expression
*
* XMLTABLE([<NSP>,] xquery-expression [<PASSING>] [COLUMNS <COLUMN>, ... )] AS name
*
* Usually of the form '$d/MedlineCitationSet/MedlineCitation'. In this case, the expression defines the initial path
* inside the XML structure that the COLUMN PATH's are relative to
*/
private String rootPath = StringConstants.EMPTY_STRING;
private ProcedureType type;
private boolean changed;
private boolean initializing;
public ProcedureInfo(Operation operation, ProcedureType type, ProcedureGenerator generator) {
super();
this.initializing = true;
this.operation = operation;
this.bodyColumnInfoList = new ArrayList<ColumnInfo>();
this.headerColumnInfoList = new ArrayList<ColumnInfo>();
this.namespaceMap = new HashMap<String, String>();
try {
this.reverseNSMap = (HashMap<String, String>) ((ModelImpl)generator.getImportManager().getWSDLModel()).getReverseNamespaces();
} catch (ModelGenerationException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
}
this.type = type;
this.generator = generator;
this.nameValidator = new StringNameValidator(true);
this.initializing = false;
}
@Override
public abstract String getDefaultProcedureName();
protected ProcedureGenerator getGenerator() {
return this.generator;
}
@Override
public ProcedureGenerator getWrapperProcedure() {
return generator;
}
public SchemaTreeModel getTreeModel() {
return treeModel;
}
public void setTreeModel(SchemaTreeModel treeModel) {
this.treeModel = treeModel;
}
public void addNamespace(String key, String value) {
for (String nsKey:this.namespaceMap.keySet()){
String ns = this.namespaceMap.get(nsKey);
if (value.endsWith(ns)){
return;
}
}
this.namespaceMap.put(key, value);
setChanged(true);
}
public void addNamespaces(Map<String, String> namespaces) {
this.namespaceMap.putAll(namespaces);
setChanged(true);
}
@Override
public Map<String, String> getNamespaceMap() {
return this.namespaceMap;
}
@Override
public ProcedureType getType() {
return this.type;
}
@Override
public ColumnInfo[] getBodyColumnInfoList() {
return this.bodyColumnInfoList.toArray(new ColumnInfo[this.bodyColumnInfoList.size()]);
}
public ColumnInfo addBodyColumn(String name, boolean ordinality, String datatype, String defaultValue, String path, String namespace) {
ColumnInfo newInfo = new ColumnInfo(name, ordinality, datatype, defaultValue, path, namespace);
this.bodyColumnInfoList.add(newInfo);
setChanged(true);
return newInfo;
}
public void removeBodyColumn(ColumnInfo theInfo) {
this.bodyColumnInfoList.remove(theInfo);
setChanged(true);
}
public void moveBodyColumnUp(ColumnInfo columnInfo) {
int startIndex = getBodyColumnIndex(columnInfo);
//
if( startIndex > 0 ) {
// Make Copy of List & get columnInfo of startIndex-1
ColumnInfo priorInfo = getBodyColumnInfoList()[startIndex-1];
ColumnInfo[] infos = getBodyColumnInfoList();
infos[startIndex-1] = columnInfo;
infos[startIndex] = priorInfo;
Collection<ColumnInfo> colInfos = new ArrayList<ColumnInfo>(infos.length);
for( ColumnInfo info : infos) {
colInfos.add(info);
}
this.bodyColumnInfoList = colInfos;
setChanged(true);
}
}
public void moveBodyColumnDown(ColumnInfo columnInfo) {
int startIndex = getBodyColumnIndex(columnInfo);
if( startIndex < (getBodyColumnInfoList().length-1) ) {
// Make Copy of List & get columnInfo of startIndex-1
ColumnInfo afterInfo = getBodyColumnInfoList()[startIndex+1];
ColumnInfo[] infos = getBodyColumnInfoList();
infos[startIndex+1] = columnInfo;
infos[startIndex] = afterInfo;
Collection<ColumnInfo> colInfos = new ArrayList<ColumnInfo>(infos.length);
for( ColumnInfo info : infos) {
colInfos.add(info);
}
this.bodyColumnInfoList = colInfos;
setChanged(true);
}
}
public boolean canMoveBodyColumnUp(ColumnInfo columnInfo) {
return getBodyColumnIndex(columnInfo) > 0;
}
public boolean canMoveBodyColumnDown(ColumnInfo columnInfo) {
return getBodyColumnIndex(columnInfo) < getBodyColumnInfoList().length-1;
}
private int getBodyColumnIndex(ColumnInfo columnInfo) {
int i=0;
for( ColumnInfo colInfo : getBodyColumnInfoList() ) {
if( colInfo == columnInfo) {
return i;
}
i++;
}
// Shouldn't ever get here!
return -1;
}
@Override
public ColumnInfo[] getHeaderColumnInfoList() {
return this.headerColumnInfoList.toArray(new ColumnInfo[this.headerColumnInfoList.size()]);
}
public ColumnInfo addHeaderColumn(String name, boolean ordinality, String datatype, String defaultValue, String path, String namespace) {
ColumnInfo newInfo = new ColumnInfo(name, ordinality, datatype, defaultValue, path, namespace);
this.headerColumnInfoList.add(newInfo);
setChanged(true);
return newInfo;
}
public void removeHeaderColumn(ColumnInfo theInfo) {
this.headerColumnInfoList.remove(theInfo);
setChanged(true);
}
public void moveHeaderColumnUp(ColumnInfo columnInfo) {
int startIndex = getHeaderColumnIndex(columnInfo);
//
if( startIndex > 0 ) {
// Make Copy of List & get columnInfo of startIndex-1
ColumnInfo priorInfo = getHeaderColumnInfoList()[startIndex-1];
ColumnInfo[] infos = getHeaderColumnInfoList();
infos[startIndex-1] = columnInfo;
infos[startIndex] = priorInfo;
Collection<ColumnInfo> colInfos = new ArrayList<ColumnInfo>(infos.length);
for( ColumnInfo info : infos) {
colInfos.add(info);
}
this.headerColumnInfoList = colInfos;
setChanged(true);
}
}
public void moveHeaderColumnDown(ColumnInfo columnInfo) {
int startIndex = getHeaderColumnIndex(columnInfo);
if( startIndex < (getHeaderColumnInfoList().length-1) ) {
// Make Copy of List & get columnInfo of startIndex-1
ColumnInfo afterInfo = getHeaderColumnInfoList()[startIndex+1];
ColumnInfo[] infos = getHeaderColumnInfoList();
infos[startIndex+1] = columnInfo;
infos[startIndex] = afterInfo;
Collection<ColumnInfo> colInfos = new ArrayList<ColumnInfo>(infos.length);
for( ColumnInfo info : infos) {
colInfos.add(info);
}
this.headerColumnInfoList = colInfos;
setChanged(true);
}
}
public boolean canMoveHeaderColumnUp(ColumnInfo columnInfo) {
return getHeaderColumnIndex(columnInfo) > 0;
}
public boolean canMoveHeaderColumnDown(ColumnInfo columnInfo) {
return getHeaderColumnIndex(columnInfo) < getHeaderColumnInfoList().length-1;
}
private int getHeaderColumnIndex(ColumnInfo columnInfo) {
int i=0;
for( ColumnInfo colInfo : getHeaderColumnInfoList() ) {
if( colInfo == columnInfo) {
return i;
}
i++;
}
// Shouldn't ever get here!
return -1;
}
public void columnChanged(ColumnInfo columnInfo) {
setChanged(true);
}
public void setOrdinality(ColumnInfo columnInfo, boolean value) {
// Need to synchronize the setting of this value for a column info.
// Basically only ONE Column can be set to TRUE .... AND ... the datatype MUST be an INTEGER
if( value == false ) {
// Only need to set the columnInfo value
columnInfo.setOrdinality(false);
} else {
for( ColumnInfo info : this.bodyColumnInfoList) {
if( !(info == columnInfo) ) {
if( info.getOrdinality() ) {
info.setOrdinality(false);
}
}
}
if( ! columnInfo.getDatatype().equalsIgnoreCase(IWsdlColumnInfo.BIGINTEGER_DATATYPE) ) {
columnInfo.setDatatype(IWsdlColumnInfo.BIGINTEGER_DATATYPE);
}
columnInfo.setOrdinality(true);
}
setChanged(true);
}
@Override
public String getProcedureName() {
return this.procedureName;
}
/**
*
* @return rootPath the root path xquery expression
*/
@Override
public String getRootPath() {
return this.getGenerator().getImportManager().isMessageServiceMode() ? ResponseInfo.SOAPENVELOPE_ROOTPATH: this.rootPath;
}
/**
*
* @param rootPath
*/
public void setRootPath(String path) {
this.rootPath = path;
// Need to walk through the ColumnInfo objects and have them re-set their paths
for( ColumnInfo colInfo : getBodyColumnInfoList() ) {
colInfo.setRootPath(this.rootPath);
}
// Need to walk through the ColumnInfo objects and have them re-set their paths
for( ColumnInfo colInfo : getHeaderColumnInfoList() ) {
colInfo.setRootPath(this.rootPath);
}
setChanged(true);
}
public void setProcedureName(String procedureName) {
this.procedureName = procedureName;
setChanged(true);
}
@Override
public Operation getOperation() {
return this.operation;
}
public IStatus validate() {
return Status.OK_STATUS;
}
@Override
public String getUniqueBodyColumnName(String proposedName) {
for( ColumnInfo info : getBodyColumnInfoList()) {
this.nameValidator.addExistingName(info.getName());
}
String changedName = this.nameValidator.createUniqueName(proposedName);
String finalName = changedName == null ? proposedName : changedName;
this.nameValidator.clearExistingNames();
return finalName;
}
@Override
public String getUniqueHeaderColumnName(String proposedName) {
for( ColumnInfo info : getHeaderColumnInfoList()) {
this.nameValidator.addExistingName(info.getName());
}
String changedName = this.nameValidator.createUniqueName(proposedName);
String finalName = changedName == null ? proposedName : changedName;
this.nameValidator.clearExistingNames();
return finalName;
}
public void setChanged(boolean value) {
this.changed = value;
if( this.changed && !this.initializing) {
this.generator.setChanged(changed);
}
}
public boolean isChanged() {
return this.changed;
}
abstract String getSqlStringTemplate();
abstract String getSqlString(Properties properties);
/**
* @since 8.2
*/
@Override
public HashMap<String, String> getReverseNSMap() {
return reverseNSMap;
}
}