/* * 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.jdbc.metadata.impl; import java.sql.DatabaseMetaData; import java.sql.SQLException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.jdbc.JdbcException; import org.teiid.designer.jdbc.JdbcPlugin; import org.teiid.designer.jdbc.data.MetadataRequest; import org.teiid.designer.jdbc.data.MethodRequest; import org.teiid.designer.jdbc.data.Request; import org.teiid.designer.jdbc.metadata.JdbcCatalog; import org.teiid.designer.jdbc.metadata.JdbcDatabase; import org.teiid.designer.jdbc.metadata.JdbcNode; import org.teiid.designer.jdbc.metadata.JdbcProcedure; import org.teiid.designer.jdbc.metadata.JdbcProcedureType; import org.teiid.designer.jdbc.metadata.JdbcSchema; /** * JdbcProcedureImpl * * @since 8.0 */ public class JdbcProcedureImpl extends JdbcNodeImpl implements JdbcProcedure { private String remarks; private short procType; private String[] properties; private boolean isOracle = false; /** * Construct an instance of JdbcProcedureImpl. */ public JdbcProcedureImpl( final JdbcProcedureType parent, final String name ) { super(PROCEDURE, name, parent); CoreArgCheck.isNotNull(parent); } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.impl.JdbcNodeImpl#computeChildren() */ @Override protected JdbcNode[] computeChildren() { return null; } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.impl.JdbcNodeImpl#getTypeName() */ @Override public String getTypeName() { // Return the table type for this table return getParent().getName(); } /** * This method is overridden to specify that JdbcTable instances never have children. * * @see org.teiid.designer.jdbc.metadata.JdbcNode#allowsChildren() */ @Override public boolean allowsChildren() { return false; } /** * Return the default selection mode when the selection mode can't be determined any other way. For example, this method is * called when the parent selection mode is {@link JdbcNode#PARTIALLY_SELECTED}. This method returns {@link JdbcNode#SELECTED} * by default, since procedures should be included for import whenever there is a question. * * @return the default selection mode */ @Override protected int getDefaultSelectionMode() { return SELECTED; } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getFullyQualifiedName() */ @Override public String getFullyQualifiedName() { final StringBuffer sb = new StringBuffer(); String prefix = null; if( isOracle && properties != null && properties.length > 0 && properties[0] != null) { prefix = getUnqualifiedPackageName(properties[0]); } else { prefix = this.getParent().getFullyQualifiedName(); } if (prefix.length() != 0) { sb.append(prefix); sb.append(getQualifedNameDelimiter()); } final String unqualName = getUnqualifiedName(); sb.append(unqualName); return sb.toString(); // empty string } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getQualifedNameDelimiter() */ @Override protected String getQualifedNameDelimiter() { // Informix DB doesn't use a single NIS delimiter. The Catalog delimiter is ":" while the table delimiter is a "." // We're checking specifically for INFORMIX and overriding for table only try { String productName = this.getJdbcDatabase().getDatabaseInfo().getProductName(); if( productName.toUpperCase().indexOf(INFORMIX) > -1) { return DEFAULT_QUALIFIED_NAME_DELIMITER; } } catch (JdbcException e) { JdbcPlugin.Util.log(e); // not expected, but log just in case } return super.getQualifedNameDelimiter(); } /** * @see org.teiid.designer.jdbc.metadata.JdbcNode#getUnqualifiedName(java.lang.String) */ public String getUnqualifiedPackageName( final String packageName ) { // Get the identifier quote string ... String quoteString = null; try { quoteString = this.getJdbcDatabase().getCapabilities().getIdentifierQuoteString(); } catch (JdbcException e) { JdbcPlugin.Util.log(e); // not expected, but log just in case } catch (SQLException e) { // ignore; } if (quoteString == null || quoteString.trim().length() == 0) { return packageName; } // // See if the name even needs the quote string ... // boolean extraCharsUsed = true; // assume they are ... // try { // final String extraChars = this.getJdbcDatabase().getCapabilities().getExtraNameCharacters(); // if (extraChars != null && extraChars.length() != 0) { // extraCharsUsed = containsCharacters(originalName, extraChars); // } // } catch (JdbcException e) { // JdbcPlugin.Util.log(e); // not expected, but log just in case // } catch (SQLException e) { // // ignore; // } // if (!extraCharsUsed && isValidName(originalName)) { // // Case 3263: Regardless of result returned above, we should always consider // // name with spaces as needing to be quoted. // if (originalName.indexOf(" ") == -1) { //$NON-NLS-1$ // return originalName; // } // } final StringBuffer sb = new StringBuffer(); sb.append(quoteString); sb.append(packageName); sb.append(quoteString); return sb.toString(); } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getPathInSource() */ @Override public IPath getPathInSource() { return getPathInSource(true, true); } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getPathInSource(boolean, boolean) */ @Override public IPath getPathInSource( final boolean includeCatalog, final boolean includeSchema ) { // Go up until we get to the schema, catalog or database that contains this object ... JdbcNode parent = getParent(); while (true) { // Stop only if the node type is to be included in the path if ((parent instanceof JdbcSchema && includeSchema) || (parent instanceof JdbcCatalog && includeCatalog) || (parent instanceof JdbcDatabase)) { break; } parent = parent.getParent(); } // If parent instanceof JdbcDatabase, then the path is just the path with this name ... if (parent instanceof JdbcDatabase) { return new Path(getName()); } // Otherwise, just append the name of this node to that of the parent. return parent.getPathInSource().append(getName()); } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getParentDatabaseObject(boolean, boolean) */ @Override public JdbcNode getParentDatabaseObject( final boolean includeCatalog, final boolean includeSchema ) { JdbcNode parent = getParent(); while (parent != null) { // Stop only if the node type is to be included in the path if ((parent instanceof JdbcSchema && includeSchema) || (parent instanceof JdbcCatalog && includeCatalog) || (parent instanceof JdbcDatabase)) { break; } parent = parent.getParent(); } // If parent instanceof JdbcDatabase, then the path is just the path with this name ... if (parent != null && parent.isDatabaseObject()) { return parent; } return null; } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcNode#getJdbcDatabase() */ @Override public JdbcDatabase getJdbcDatabase() { return getParent().getJdbcDatabase(); } /** * @return */ @Override public String getRemarks() { return remarks; } /** * @param string */ public void setRemarks( String string ) { remarks = string; } /** * @param string array */ public void setProperties( String[] strings) { this.properties = strings; } @Override public String[] getProperties() { return properties; } public void setIsOracle(boolean value) { isOracle = value; } @Override public boolean isOracle() { return isOracle; } /* (non-Javadoc) * @See org.teiid.designer.jdbc.metadata.JdbcProcedure#getProcedureType() */ @Override public short getProcedureType() { return procType; } public void setProcedureType( final short type ) { CoreArgCheck.isTrue(type == RESULT_UNKNOWN || type == RETURNS_RESULT || type == NO_RESULT, JdbcPlugin.Util.getString("JdbcProcedureImpl.Invalid_procedure_type")); //$NON-NLS-1$ this.procType = type; } @Override protected Request[] createRequests() { DatabaseMetaData metadata = null; try { metadata = this.getJdbcDatabase().getDatabaseMetaData(); } catch (JdbcException e) { JdbcPlugin.Util.log(e); } final DatabaseMetaData finalMetadata = metadata; final String catalogNamePattern = JdbcNodeImpl.getCatalogPattern(this); final String schemaNamePattern = JdbcNodeImpl.getSchemaPattern(this); final String procedureNamePattern = this.getName(); final String procedureColumnNamePattern = WILDCARD_PATTERN; final Request[] requests = new Request[2]; // 2 requests! // 1. Create the "Columns" request requests[0] = new GetProcedureParametersRequest(finalMetadata, catalogNamePattern, schemaNamePattern, procedureNamePattern, procedureColumnNamePattern); // 2. Create the "Description" request requests[1] = new GetDescriptionRequest(this, "getRemarks"); //$NON-NLS-1$ // Disable what is not to be loaded ... if (!this.getJdbcDatabase().getIncludes().includeProcedures()) { requests[1] = new DisabledRequest((MethodRequest)requests[1]); } return requests; } }