public LocalClient(String vdbName, int vdbVersion, Properties props) { this.vdbName = vdbName; this.vdbVersion = vdbVersion; this.batchSize = PropertiesUtils.getIntProperty( props, BATCH_SIZE, BufferManagerImpl.DEFAULT_PROCESSOR_BATCH_SIZE); this.cacheTime = PropertiesUtils.getLongProperty(props, SKIPTOKEN_TIME, 300000L); this.invalidCharacterReplacement = props.getProperty(INVALID_CHARACTER_REPLACEMENT); StringBuilder sb = new StringBuilder(); sb.append("jdbc:teiid:") .append(this.vdbName) .append(".") .append(this.vdbVersion) .append(";"); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ this.initProperties = props; if (this.initProperties.getProperty(TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION) == null) { this.initProperties.put( TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION, "true"); // $NON-NLS-1$ } if (this.initProperties.getProperty(EmbeddedProfile.TRANSPORT_NAME) == null) { this.initProperties.setProperty(EmbeddedProfile.TRANSPORT_NAME, "odata"); } if (this.initProperties.getProperty(EmbeddedProfile.WAIT_FOR_LOAD) == null) { this.initProperties.put(EmbeddedProfile.WAIT_FOR_LOAD, "0"); // $NON-NLS-1$ } this.connectionString = sb.toString(); }
@Override public ConnectionImpl connect(String url, Properties info) throws SQLException { ConnectionType conn = JDBCURL.acceptsUrl(url); if (conn == null) { return null; } if (info == null) { // create a properties obj if it is null info = new Properties(); } else { // don't modify the original info = PropertiesUtils.clone(info); } parseURL(url, info); ConnectionImpl myConnection = null; /* * Add the teiid server version to the properties */ info.setProperty(ITeiidServerVersion.TEIID_VERSION_PROPERTY, getTeiidVersion().toString()); try { myConnection = socketProfile.connect(url, info); } catch (SQLException e) { logger.log(Level.SEVERE, "Could not create connection", e); // $NON-NLS-1$ throw e; } // logging String logMsg = Messages.getString(Messages.JDBC.Connection_success); logger.fine(logMsg); return myConnection; }
@Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { if (info == null) { info = new Properties(); } else { info = PropertiesUtils.clone(info); } // construct list of driverPropertyInfo objects List<DriverPropertyInfo> driverProps = new LinkedList<DriverPropertyInfo>(); parseURL(url, info); for (String property : JDBCURL.KNOWN_PROPERTIES.keySet()) { DriverPropertyInfo dpi = new DriverPropertyInfo(property, info.getProperty(property)); if (property.equals(TeiidURL.JDBC.VDB_NAME)) { dpi.required = true; } driverProps.add(dpi); } // create an array of DriverPropertyInfo objects DriverPropertyInfo[] propInfo = new DriverPropertyInfo[driverProps.size()]; // copy the elements from the list to the array return driverProps.toArray(propInfo); }
public LocalServerConnection(Properties connectionProperties, boolean useCallingThread) throws CommunicationException, ConnectionException { this.connectionProperties = connectionProperties; this.csr = getClientServiceRegistry(); String vdbVersion = connectionProperties.getProperty(TeiidURL.JDBC.VDB_VERSION); String vdbName = connectionProperties.getProperty(TeiidURL.JDBC.VDB_NAME); int firstIndex = vdbName.indexOf('.'); int lastIndex = vdbName.lastIndexOf('.'); if (firstIndex != -1 && firstIndex == lastIndex) { vdbVersion = vdbName.substring(firstIndex + 1); vdbName = vdbName.substring(0, firstIndex); } if (vdbVersion != null) { int waitForLoad = PropertiesUtils.getIntProperty(connectionProperties, EmbeddedProfile.WAIT_FOR_LOAD, -1); if (waitForLoad != 0) { this.csr.waitForFinished(vdbName, Integer.valueOf(vdbVersion), waitForLoad); } } workContext.setSecurityHelper(csr.getSecurityHelper()); workContext.setUseCallingThread(useCallingThread); workContext.setSecurityContext(csr.getSecurityHelper().getSecurityContext()); authenticate(); passthrough = Boolean.valueOf( connectionProperties.getProperty( TeiidURL.CONNECTION.PASSTHROUGH_AUTHENTICATION, "false")); // $NON-NLS-1$ }
/** * Implement to provide metadata to the metadata for use by the engine. This is the primary method * of creating metadata for dynamic VDBs. * * @param metadataFactory * @param conn may be null if the source is not required * @throws TranslatorException to indicate a recoverable error, otherwise a RuntimeException * @see #isSourceRequiredForMetadata() */ public void getMetadata(MetadataFactory metadataFactory, C conn) throws TranslatorException { MetadataProcessor mp = getMetadataProcessor(); if (mp != null) { PropertiesUtils.setBeanProperties( mp, metadataFactory.getModelProperties(), "importer"); // $NON-NLS-1$ mp.process(metadataFactory, conn); } }
public void initialize(Properties info) { PropertiesUtils.setBeanProperties(this, info, "org.teiid.sockets"); // $NON-NLS-1$ this.pingTimer = new Timer("SocketPing", true); // $NON-NLS-1$ this.pingTimer.schedule( new TimerTask() { @Override public void run() { Set<Map.Entry<HostInfo, Set<SessionToken>>> sessionEntries = null; synchronized (sessions) { sessionEntries = new HashSet<Map.Entry<HostInfo, Set<SessionToken>>>(sessions.entrySet()); } for (Map.Entry<HostInfo, Set<SessionToken>> entry : sessionEntries) { SocketServerInstance instance = null; HashSet<SessionToken> entries = null; synchronized (sessions) { entries = new HashSet<SessionToken>(entry.getValue()); } try { instance = getServerInstance(entry.getKey()); ILogon logon = instance.getService(ILogon.class); if ("07.01.01".compareTo(instance.getServerVersion()) > 0 || //$NON-NLS-1$ "7.1.1".compareTo(instance.getServerVersion()) > 0) { // $NON-NLS-1$ for (SessionToken session : entries) { try { logon.assertIdentity(session); logon.ping(); log.log(Level.FINER, "issueing ping for session:", session); // $NON-NLS-1$ } catch (InvalidSessionException e) { } } } else { ArrayList<String> sessionStrings = new ArrayList<String>(entry.getValue().size()); for (SessionToken session : entries) { sessionStrings.add(session.getSessionID()); } logon.ping(sessionStrings); log.log( Level.FINER, "issueing ping for sessions:", sessionStrings); // $NON-NLS-1$ } } catch (Exception e) { log.log(Level.WARNING, "Error performing keep-alive ping", e); // $NON-NLS-1$ } finally { if (instance != null) { instance.shutdown(); } } } } }, ServerConnection.PING_INTERVAL, ServerConnection.PING_INTERVAL); this.channelFactory = new OioOjbectChannelFactory(info); }
@BeforeClass public static void beforeEachClass() throws Exception { RemoteInfinispanTestHelper.createServer(); System.out.println("Hostaddress " + RemoteInfinispanTestHelper.hostAddress()); // read in the properties template file and set the server host:port and then save for use File f = new File("./src/test/resources/hotrod-client.properties"); Properties props = PropertiesUtils.load(f.getAbsolutePath()); props.setProperty( "infinispan.client.hotrod.server_list", RemoteInfinispanTestHelper.hostAddress() + ":" + RemoteInfinispanTestHelper.hostPort()); PropertiesUtils.print("./target/hotrod-client.properties", props); factory = new InfinispanManagedConnectionFactory(); factory.setHotRodClientPropertiesFile("./target/hotrod-client.properties"); factory.setCacheTypeMap(RemoteInfinispanTestHelper.CACHE_NAME + ":" + "java.lang.String"); }
/** Teiid's Connection implementation. */ public class ConnectionImpl extends WrapperImpl implements TeiidConnection { private static final int MAX_OPEN_STATEMENTS = PropertiesUtils.getIntProperty( System.getProperties(), "org.teiid.maxOpenStatements", 1000); // $NON-NLS-1$ private static Logger logger = Logger.getLogger("org.teiid.jdbc"); // $NON-NLS-1$ public static final int DEFAULT_ISOLATION = Connection.TRANSACTION_READ_COMMITTED; // constant value giving product name private static final String SERVER_NAME = "Teiid Server"; // $NON-NLS-1$ private static final String EMBEDDED_NAME = "Teiid Embedded"; // $NON-NLS-1$ // Unique request ID generator private long requestIDGenerator; // url used to create the connection private String url; // properties object containing the connection properties. protected Properties propInfo; // status of connection object private boolean closed = false; // determines if a statement executed should be immediately committed. private boolean autoCommitFlag = true; private boolean inLocalTxn; // collection of all open statements on this connection private Collection<StatementImpl> statements = Collections.newSetFromMap(new ConcurrentHashMap<StatementImpl, Boolean>()); // cached DatabaseMetadata private DatabaseMetaDataImpl dbmm; // Xid for participating in TXN private XidImpl transactionXid; // Flag to represent if the connection state needs to be readOnly, default value false. private boolean readOnly = false; private DQP dqp; protected ServerConnection serverConn; private int transactionIsolation = DEFAULT_ISOLATION; // the last query plan description private PlanNode currentPlanDescription; // the last query debug log private String debugLog; // the last query annotations private Collection<Annotation> annotations; private Properties connectionProps; private Properties payload; public ConnectionImpl(ServerConnection serverConn, Properties info, String url) { this.connectionProps = info; this.serverConn = serverConn; this.url = url; this.dqp = serverConn.getService(DQP.class); logger.fine(JDBCPlugin.Util.getString("MMConnection.Session_success")); // $NON-NLS-1$ logConnectionProperties(url, info); setExecutionProperties(info); } boolean isInLocalTxn() { return inLocalTxn; } private void setExecutionProperties(Properties info) { this.propInfo = new Properties(); String defaultFetchSize = info.getProperty(ExecutionProperties.PROP_FETCH_SIZE); if (defaultFetchSize != null) { propInfo.put(ExecutionProperties.PROP_FETCH_SIZE, defaultFetchSize); } else { propInfo.put( ExecutionProperties.PROP_FETCH_SIZE, String.valueOf(BaseDataSource.DEFAULT_FETCH_SIZE)); } String partialResultsMode = info.getProperty(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE); if (partialResultsMode != null) { propInfo.put(ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, partialResultsMode); } else { propInfo.put( ExecutionProperties.PROP_PARTIAL_RESULTS_MODE, BaseDataSource.DEFAULT_PARTIAL_RESULTS_MODE); } String resultSetCacheMode = info.getProperty(ExecutionProperties.RESULT_SET_CACHE_MODE); if (resultSetCacheMode != null) { propInfo.put(ExecutionProperties.RESULT_SET_CACHE_MODE, resultSetCacheMode); } else { propInfo.put( ExecutionProperties.RESULT_SET_CACHE_MODE, BaseDataSource.DEFAULT_RESULT_SET_CACHE_MODE); } String ansiQuotes = info.getProperty(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS); if (ansiQuotes != null) { propInfo.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS, ansiQuotes); } else { propInfo.put(ExecutionProperties.ANSI_QUOTED_IDENTIFIERS, Boolean.TRUE.toString()); } for (String key : info.stringPropertyNames()) { String actualKey = JDBCURL.EXECUTION_PROPERTIES.get(key); if (actualKey != null) { propInfo.setProperty(actualKey, info.getProperty(key)); } } } public Collection<Annotation> getAnnotations() { return annotations; } public void setAnnotations(Collection<Annotation> annotations) { this.annotations = annotations; } public String getDebugLog() { return debugLog; } public void setDebugLog(String debugLog) { this.debugLog = debugLog; } public PlanNode getCurrentPlanDescription() { return currentPlanDescription; } public void setCurrentPlanDescription(PlanNode currentPlanDescription) { this.currentPlanDescription = currentPlanDescription; } protected Properties getExecutionProperties() { return this.propInfo; } public void setExecutionProperty(String key, String value) { JDBCURL.addNormalizedProperty(key, value, getExecutionProperties()); } public String getExecutionProperty(String key) { return this.getExecutionProperties().getProperty(JDBCURL.getValidKey(key)); } DQP getDQP() { return this.dqp; } /** * Remove password & trusted token and log all other properties * * @param connUrl - URL used to connect to server * @param info - properties object supplied */ private void logConnectionProperties(String connUrl, Properties info) { StringBuffer modifiedUrl = new StringBuffer(); // If we have valid URL if (connUrl != null) { // We need wipe out the password here, before we write to the log int startIndex = connUrl.indexOf("password="******"password=***"); // $NON-NLS-1$ int endIndex = connUrl.indexOf(";", startIndex + 9); // $NON-NLS-1$ if (endIndex != -1) { modifiedUrl.append(";").append(connUrl.substring(endIndex)); // $NON-NLS-1$ } } logger.fine("Connection Url=" + modifiedUrl); // $NON-NLS-1$ } // Now clone the properties object and remove password and trusted token if (info != null) { Enumeration enumeration = info.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); Object anObj = info.get(key); // Log each property except for password and token. if (!TeiidURL.CONNECTION.PASSWORD.equalsIgnoreCase(key)) { logger.fine(key + "=" + anObj); // $NON-NLS-1$ } } } } String getUrl() { return this.url; } /** * Connection identifier of this connection * * @return identifier * @throws SQLException */ public String getConnectionId() { return this.serverConn.getLogonResult().getSessionID(); } /** * Generate the next unique requestID for matching up requests with responses. These IDs should be * unique only in the context of a ServerConnection instance. * * @return Request ID */ protected synchronized long nextRequestID() { return requestIDGenerator++; } public void clearWarnings() throws SQLException { // do nothing } public void close() throws SQLException { Throwable firstException = null; if (closed) { return; } try { // close any statements that were created on this connection try { closeStatements(); } catch (SQLException se) { firstException = se; } finally { this.serverConn.close(); if (firstException != null) throw (SQLException) firstException; } } catch (SQLException se) { throw TeiidSQLException.create( se, JDBCPlugin.Util.getString( "MMConnection.Err_connection_close", se.getMessage())); // $NON-NLS-1$ } finally { logger.fine( JDBCPlugin.Util.getString("MMConnection.Connection_close_success")); // $NON-NLS-1$ // set the status of the connection to closed closed = true; } } /** * Close all the statements open on this connection * * @throws SQLException server statement object could not be closed. */ void closeStatements() throws SQLException { // Closing the statement will cause the // MMConnection.closeStatement() method to be called, // which will modify this.statements. So, we do this iteration // in a separate safe copy of the list List<StatementImpl> statementsSafe = new ArrayList<StatementImpl>(this.statements); SQLException ex = null; for (StatementImpl statement : statementsSafe) { try { statement.close(); } catch (SQLException e) { ex = e; } } if (ex != null) { throw TeiidSQLException.create( ex, JDBCPlugin.Util.getString("MMConnection.Err_closing_stmts")); // $NON-NLS-1$ } } /** * Called by MMStatement to notify the connection that the statement has been closed. * * @param statement */ void closeStatement(Statement statement) { this.statements.remove(statement); } /** * This method makes any changes involved in a transaction permanent and releases any locks held * by the connection object. This is only used when auto-commit is set to false. * * @throws SQLException if the transaction had been rolled back or marked to roll back. */ public void commit() throws SQLException { checkConnection(); if (!autoCommitFlag) { try { directCommit(); } finally { inLocalTxn = false; } } } private void directCommit() throws SQLException { if (inLocalTxn) { try { ResultsFuture<?> future = this.dqp.commit(); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } logger.fine(JDBCPlugin.Util.getString("MMConnection.Commit_success")); // $NON-NLS-1$ } } void beginLocalTxnIfNeeded() throws SQLException { if (this.transactionXid != null || inLocalTxn || this.autoCommitFlag || isDisableLocalTxn()) { return; } try { try { this.dqp.begin(); } catch (XATransactionException e) { throw TeiidSQLException.create(e); } inLocalTxn = true; } finally { if (!inLocalTxn) { autoCommitFlag = true; } } } private boolean isDisableLocalTxn() { String prop = this.propInfo.getProperty(ExecutionProperties.DISABLE_LOCAL_TRANSACTIONS); return prop != null && Boolean.valueOf(prop); } public StatementImpl createStatement() throws SQLException { return createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } /** * Creates a Statement object that will produce ResultSet objects of the type resultSetType and * concurrency level resultSetConcurrency. * * @param intvalue indicating the ResultSet's type * @param intValue indicating the ResultSet's concurrency * @return Statement object. */ public StatementImpl createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return createStatement(resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT); } /** * @param resultSetType * @throws TeiidSQLException * @since 4.3 */ private void validateResultSetType(int resultSetType) throws TeiidSQLException { if (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE) { String msg = JDBCPlugin.Util.getString( "MMConnection.Scrollable_type_not_supported", "ResultSet.TYPE_SCROLL_SENSITIVE"); //$NON-NLS-1$ //$NON-NLS-2$ throw new TeiidSQLException(msg); } } /** * @param resultSetConcurrency * @throws TeiidSQLException * @since 4.3 */ private void validateResultSetConcurrency(int resultSetConcurrency) throws TeiidSQLException { if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { String msg = JDBCPlugin.Util.getString( "MMConnection.Concurrency_type_not_supported", "ResultSet.CONCUR_UPDATABLE"); //$NON-NLS-1$ //$NON-NLS-2$ throw new TeiidSQLException(msg); } } public boolean getAutoCommit() throws SQLException { // Check to see the connection is open checkConnection(); return autoCommitFlag; } public String getCatalog() throws SQLException { // Check to see the connection is open checkConnection(); // catalogs are not supported return this.serverConn.getLogonResult().getVdbName(); } /** * This method gets the ServerConnection object wrapped by this object. * * @return ServerConnection object */ public ServerConnection getServerConnection() throws SQLException { // Check to see the connection is open checkConnection(); return serverConn; } String getVDBName() throws SQLException { // Check to see the connection is open checkConnection(); // get the virtual database name to which we are connected. return this.serverConn.getLogonResult().getVdbName(); } public int getVDBVersion() throws SQLException { checkConnection(); return this.serverConn.getLogonResult().getVdbVersion(); } /** * Get's the name of the user who got this connection. * * @return Sring object giving the user name * @throws SQLException if the connection is closed */ String getUserName() throws SQLException { checkConnection(); return this.serverConn.getLogonResult().getUserName(); } public DatabaseMetaDataImpl getMetaData() throws SQLException { // Check to see the connection is open checkConnection(); if (dbmm == null) { dbmm = new DatabaseMetaDataImpl(this); } return dbmm; } /** * Get the database name that this connection is representing * * @return String name of the database */ public String getDatabaseName() { if (this.serverConn instanceof SocketServerConnection) { return SERVER_NAME; } return EMBEDDED_NAME; } /** * Retrieves the current holdability of ResultSet objects created using this Connection object. * * @param holdability int indicating the holdability * @return int holdability * @throws SQLException */ public int getHoldability() throws SQLException { return ResultSet.HOLD_CURSORS_OVER_COMMIT; } public int getTransactionIsolation() throws SQLException { return this.transactionIsolation; } @Override public Map<String, Class<?>> getTypeMap() throws SQLException { return Collections.emptyMap(); } /** * This method will return the first warning reported by calls on this connection, or null if none * exist. * * @return A SQLWarning object if there are any warnings. * @throws SQLException, should never occur */ public SQLWarning getWarnings() throws SQLException { // Check to see the connection is open checkConnection(); return null; // we don't have any warnings } /** * This method will return whether this connection is closed or not. * * @return booleanvalue indicating if the connection is closed * @throws SQLException, should never occur */ public boolean isClosed() throws SQLException { return closed; } public boolean isReadOnly() throws SQLException { return readOnly; } public String nativeSQL(String sql) throws SQLException { // return the string argument without any modifications. // escape syntaxes are directly supported in the server return sql; } /** * Creates a CallableStatement object that contains sql and that will produce ResultSet objects * that are non-scrollable and non-updatable. A SQL stored procedure call statement is handled by * creating a CallableStatement for it. * * @param sql String(escape syntax) for invoking a stored procedure. * @return CallableStatement object that can be used to execute the storedProcedure * @throws SQLException if there is an error creating the callable statement object */ public CallableStatementImpl prepareCall(String sql) throws SQLException { // there is a problem setting the result set type to be non-scrollable // See defect 17768 return prepareCall(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } /** * Creates a CallableStatement object that contains a sql and that will produce ResultSet objects * of the type resultSetType and with a concurrency level of resultSetConcurrency. A SQL stored * procedure call statement is handled by creating a CallableStatement for it. * * @param sql String(escape syntax) for invoking a stored procedure. * @param intvalue indicating the ResultSet's type * @param intValue indicating the ResultSet's concurrency * @return CallableStatement object that can be used to execute the storedProcedure */ public CallableStatementImpl prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return prepareCall( sql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT); } /** * @param sql * @throws TeiidSQLException * @since 4.3 */ private void validateSQL(String sql) throws TeiidSQLException { if (sql == null) { String msg = JDBCPlugin.Util.getString("MMConnection.SQL_cannot_be_null"); // $NON-NLS-1$ throw new TeiidSQLException(msg); } } public PreparedStatementImpl prepareStatement(String sql) throws SQLException { return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } public PreparedStatementImpl prepareStatement( String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return prepareStatement( sql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT); } public PreparedStatementImpl prepareStatement( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability, int autoGeneratedKeys) throws SQLException { // Check to see the connection is open checkConnection(); validateResultSetType(resultSetType); validateResultSetConcurrency(resultSetConcurrency); validateSQL(sql); // add the statement object to the map PreparedStatementImpl newStatement = new PreparedStatementImpl(this, sql, resultSetType, resultSetConcurrency); newStatement.setAutoGeneratedKeys(autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS); addStatement(newStatement); return newStatement; } public PreparedStatementImpl prepareStatement( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return prepareStatement( sql, resultSetType, resultSetConcurrency, resultSetHoldability, Statement.NO_GENERATED_KEYS); } public void rollback() throws SQLException { rollback(true); } /** * Rollback the current local transaction * * @param startTxn * @throws SQLException */ public void rollback(boolean startTxn) throws SQLException { // Check to see the connection is open checkConnection(); if (!autoCommitFlag) { try { if (this.inLocalTxn) { this.inLocalTxn = false; try { ResultsFuture<?> future = this.dqp.rollback(); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } logger.fine(JDBCPlugin.Util.getString("MMConnection.Rollback_success")); // $NON-NLS-1$ } } finally { if (startTxn) { this.inLocalTxn = false; } else { this.autoCommitFlag = true; } } } } public ResultsFuture<?> submitSetAutoCommitTrue(boolean commit) throws SQLException { // Check to see the connection is open checkConnection(); if (this.autoCommitFlag) { return ResultsFuture.NULL_FUTURE; } this.autoCommitFlag = true; if (isDisableLocalTxn()) { return ResultsFuture.NULL_FUTURE; } try { if (commit) { return dqp.commit(); } return dqp.rollback(); } catch (XATransactionException e) { throw TeiidSQLException.create(e); } } public void setAutoCommit(boolean autoCommit) throws SQLException { // Check to see the connection is open checkConnection(); if (autoCommit == this.autoCommitFlag) { return; } this.autoCommitFlag = autoCommit; if (autoCommit) { directCommit(); } else { inLocalTxn = false; } } /** * Teiid does not allow setting a catalog through a connection. This method silently ignores the * request as per the specification. * * @param The string values which sets the catalog name on the connection. * @throws SQLException This should never occur. */ public void setCatalog(String catalog) throws SQLException { // do nothing, silently ignore the request } /** * @param A boolean value specifying whether the connection is readonly. * @throws throws SQLException. */ public void setReadOnly(boolean readOnly) throws SQLException { if (this.readOnly == readOnly) { return; } // During transaction do not allow to change this flag if (!autoCommitFlag || this.transactionXid != null) { throw new TeiidSQLException( JDBCPlugin.Util.getString( "MMStatement.Invalid_During_Transaction", "setReadOnly(" + readOnly + ")")); // $NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ } this.readOnly = readOnly; } /** * This utility method checks if the jdbc connection is closed and throws an exception if it is * closed. * * @throws SQLException if the connection object is closed. */ void checkConnection() throws SQLException { // Check to see the connection is closed and proceed if it is not if (closed) { throw new TeiidSQLException( JDBCPlugin.Util.getString("MMConnection.Cant_use_closed_connection")); // $NON-NLS-1$ } } protected void commitTransaction(XidImpl arg0, boolean arg1) throws SQLException { checkConnection(); transactionXid = null; this.autoCommitFlag = true; try { ResultsFuture<?> future = this.dqp.commit(arg0, arg1); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected void endTransaction(XidImpl arg0, int arg1) throws SQLException { checkConnection(); this.autoCommitFlag = true; try { ResultsFuture<?> future = this.dqp.end(arg0, arg1); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected void forgetTransaction(XidImpl arg0) throws SQLException { checkConnection(); try { ResultsFuture<?> future = this.dqp.forget(arg0); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected int prepareTransaction(XidImpl arg0) throws SQLException { checkConnection(); transactionXid = null; try { ResultsFuture<Integer> future = this.dqp.prepare(arg0); return future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected Xid[] recoverTransaction(int arg0) throws SQLException { checkConnection(); try { ResultsFuture<Xid[]> future = this.dqp.recover(arg0); return future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected void rollbackTransaction(XidImpl arg0) throws SQLException { checkConnection(); transactionXid = null; this.autoCommitFlag = true; try { ResultsFuture<?> future = this.dqp.rollback(arg0); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } } protected void startTransaction(XidImpl arg0, int arg1, int timeout) throws SQLException { checkConnection(); try { ResultsFuture<?> future = this.dqp.start(arg0, arg1, timeout); future.get(); } catch (Exception e) { throw TeiidSQLException.create(e); } transactionXid = arg0; this.autoCommitFlag = false; } protected XidImpl getTransactionXid() { return transactionXid; } public boolean isValid(int timeout) throws SQLException { return this.getServerConnection().isOpen(timeout * 1000); } public void recycleConnection(boolean selectNewInstance) { this.payload = null; try { // close all open statements this.closeStatements(); } catch (SQLException e) { logger.log( Level.WARNING, JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e); //$NON-NLS-1$ } try { // rollback if still in a transaction if (!this.getAutoCommit()) { logger.warning(JDBCPlugin.Util.getString("MMXAConnection.rolling_back")); // $NON-NLS-1$ if (this.getTransactionXid() == null) { this.rollback(false); } else { this.rollbackTransaction(getTransactionXid()); } } } catch (SQLException e) { logger.log( Level.WARNING, JDBCPlugin.Util.getString("MMXAConnection.rolling_back_error"), e); //$NON-NLS-1$ } if (selectNewInstance) { this.serverConn.cleanUp(); } } public boolean isSameProcess(ConnectionImpl conn) throws CommunicationException { return this.serverConn.isSameInstance(conn.serverConn); } public void setClientInfo(Properties properties) throws SQLClientInfoException {} public void setClientInfo(String name, String value) throws SQLClientInfoException {} public Properties getClientInfo() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public String getClientInfo(String name) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return new ArrayImpl(elements); } public Blob createBlob() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public Clob createClob() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public NClob createNClob() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public SQLXML createSQLXML() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public StatementImpl createStatement( int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { // Check to see the connection is open checkConnection(); validateResultSetType(resultSetType); validateResultSetConcurrency(resultSetConcurrency); // TODO: implement close cursors at commit // add the statement object to the map StatementImpl newStatement = new StatementImpl(this, resultSetType, resultSetConcurrency); addStatement(newStatement); return newStatement; } private void addStatement(StatementImpl newStatement) throws SQLException { if (statements.size() > MAX_OPEN_STATEMENTS) { this.close(); throw new TeiidSQLException( JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID20036, MAX_OPEN_STATEMENTS)); } statements.add(newStatement); } public Struct createStruct(String typeName, Object[] attributes) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public CallableStatementImpl prepareCall( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { // Check to see the connection is open checkConnection(); validateResultSetType(resultSetType); validateResultSetConcurrency(resultSetConcurrency); validateSQL(sql); // TODO: implement close cursors at commit // add the statement object to the map CallableStatementImpl newStatement = new CallableStatementImpl(this, sql, resultSetType, resultSetConcurrency); addStatement(newStatement); return newStatement; } public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return prepareStatement( sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, Statement.RETURN_GENERATED_KEYS); } public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return prepareStatement( sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, Statement.RETURN_GENERATED_KEYS); } public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return prepareStatement( sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, Statement.RETURN_GENERATED_KEYS); } public void releaseSavepoint(Savepoint savepoint) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public void rollback(Savepoint savepoint) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public void setHoldability(int holdability) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public Savepoint setSavepoint() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public Savepoint setSavepoint(String name) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public void setTransactionIsolation(int level) throws SQLException { this.transactionIsolation = level; } public void setTypeMap(Map<String, Class<?>> map) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } Object setPassword(Object newPassword) { if (newPassword != null) { return this.connectionProps.put(TeiidURL.CONNECTION.PASSWORD, newPassword); } return this.connectionProps.remove(TeiidURL.CONNECTION.PASSWORD); } String getPassword() { Object result = this.connectionProps.get(TeiidURL.CONNECTION.PASSWORD); if (result == null) { return null; } return result.toString(); } @Override public void changeUser(String userName, String newPassword) throws SQLException { // TODO: recycleConnection(); Object oldName = null; Object oldPassword = null; if (userName != null) { oldName = this.connectionProps.put(TeiidURL.CONNECTION.USER_NAME, userName); } else { oldName = this.connectionProps.remove(TeiidURL.CONNECTION.USER_NAME); } oldPassword = setPassword(newPassword); boolean success = false; try { this.serverConn.authenticate(); success = true; } catch (ConnectionException e) { throw TeiidSQLException.create(e); } catch (CommunicationException e) { throw TeiidSQLException.create(e); } finally { if (!success) { if (oldName != null) { this.connectionProps.put(TeiidURL.CONNECTION.USER_NAME, oldName); } else { this.connectionProps.remove(TeiidURL.CONNECTION.USER_NAME); } setPassword(oldPassword); } } } public void abort(Executor executor) throws SQLException { if (closed) { return; } // TODO: ensure that threads are released. In theory they will be since close effectively // cancels current executions close(); } public int getNetworkTimeout() throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public String getSchema() throws SQLException { return null; } /** @see query timeouts and the synchronousTtl setting if using socket connections */ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { throw SqlUtil.createFeatureNotSupportedException(); } public void setSchema(String schema) throws SQLException {} public Properties getPayload() { return payload; } public void setPayload(Properties payload) { this.payload = payload; } public Properties getConnectionProps() { return connectionProps; } }
/** * The FunctionDescriptor describes a particular function instance enough to invoke the function. */ public class FunctionDescriptor implements Serializable, Cloneable { private static final long serialVersionUID = 5374103983118037242L; private static final boolean ALLOW_NAN_INFINITY = PropertiesUtils.getBooleanProperty( System.getProperties(), "org.teiid.allowNanInfinity", false); // $NON-NLS-1$ private Class<?>[] types; private Class<?> returnType; private boolean requiresContext; private FunctionMethod method; private String schema; // TODO: remove me - we need to create a proper schema for udf and system functions private boolean hasWrappedArgs; private boolean calledWithVarArgArrayParam; // TODO: could store this on the function and pass to invoke // This is transient as it would be useless to invoke this method in // a different VM. This function descriptor can be used to look up // the real VM descriptor for execution. private transient Method invocationMethod; FunctionDescriptor() {} FunctionDescriptor( FunctionMethod method, Class<?>[] types, Class<?> outputType, Method invocationMethod, boolean requiresContext) { this.types = types; this.returnType = outputType; this.invocationMethod = invocationMethod; this.requiresContext = requiresContext; this.method = method; } public Object newInstance() { try { return invocationMethod.getDeclaringClass().newInstance(); } catch (InstantiationException e) { throw new TeiidRuntimeException( QueryPlugin.Event.TEIID30602, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID30602, method.getName(), method.getInvocationClass())); } catch (IllegalAccessException e) { throw new TeiidRuntimeException( QueryPlugin.Event.TEIID30602, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID30602, method.getName(), method.getInvocationClass())); } } public void setHasWrappedArgs(boolean hasWrappedArgs) { this.hasWrappedArgs = hasWrappedArgs; } public String getSchema() { return schema; } public void setSchema(String schema) { this.schema = schema; } public String getName() { return this.method.getName(); } public String getFullName() { if (CoreConstants.SYSTEM_MODEL.equals(this.schema)) { return getName(); } return this.schema + AbstractMetadataRecord.NAME_DELIM_CHAR + getName(); } public PushDown getPushdown() { return this.method.getPushdown(); } public Class<?>[] getTypes() { return this.types; } public Class<?> getReturnType() { return this.returnType; } Method getInvocationMethod() { return this.invocationMethod; } public boolean requiresContext() { return this.requiresContext; } @Override public String toString() { StringBuffer str = new StringBuffer(this.method.getName()); str.append("("); // $NON-NLS-1$ for (int i = 0; i < types.length; i++) { if (types[i] != null) { str.append(types[i].getName()); } else { str.append("null"); // $NON-NLS-1$ } if (i < (types.length - 1)) { str.append(", "); // $NON-NLS-1$ } } str.append(") : "); // $NON-NLS-1$ if (returnType == null) { str.append("null"); // $NON-NLS-1$ } else { str.append(returnType.getName()); } return str.toString(); } public boolean isNullDependent() { return !this.method.isNullOnNull(); } public Determinism getDeterministic() { return this.method.getDeterminism(); } @Override public FunctionDescriptor clone() { try { return (FunctionDescriptor) super.clone(); } catch (CloneNotSupportedException e) { throw new TeiidRuntimeException(QueryPlugin.Event.TEIID30381, e); } } public FunctionMethod getMethod() { return method; } void setReturnType(Class<?> returnType) { this.returnType = returnType; } /** * Invoke the function described in the function descriptor, using the values provided. Return the * result of the function. * * @param values Values that should match 1-to-1 with the types described in the function * descriptor * @param context * @param functionTarget TODO * @param fd Function descriptor describing the name and types of the arguments * @return Result of invoking the function */ public Object invokeFunction(Object[] values, CommandContext context, Object functionTarget) throws FunctionExecutionException, BlockedException { if (!isNullDependent()) { for (int i = requiresContext ? 1 : 0; i < values.length; i++) { if (values[i] == null) { return null; } } } // If descriptor is missing invokable method, find this VM's descriptor // give name and types from fd if (invocationMethod == null) { throw new FunctionExecutionException( QueryPlugin.Event.TEIID30382, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30382, getFullName())); } // Invoke the method and return the result try { if (hasWrappedArgs) { for (int i = 0; i < values.length; i++) { Object val = values[i]; if (val != null && types[i] == DataTypeManager.DefaultDataClasses.VARBINARY) { values[i] = ((BinaryType) val).getBytesDirect(); } } } if (method.isVarArgs()) { if (calledWithVarArgArrayParam) { ArrayImpl av = (ArrayImpl) values[values.length - 1]; if (av != null) { Object[] vals = av.getValues(); values[values.length - 1] = vals; if (hasWrappedArgs && types[types.length - 1] == DataTypeManager.DefaultDataClasses.VARBINARY) { vals = Arrays.copyOf(vals, vals.length); for (int i = 0; i < vals.length; i++) { if (vals[i] != null) { vals[i] = ((BinaryType) vals[i]).getBytesDirect(); } } values[values.length - 1] = vals; } Class<?> arrayType = invocationMethod.getParameterTypes()[types.length - 1]; if (arrayType.getComponentType() != Object.class && vals.getClass() != arrayType) { Object varArgs = Array.newInstance(arrayType.getComponentType(), vals.length); for (int i = 0; i < vals.length; i++) { Array.set(varArgs, i, vals[i]); } values[values.length - 1] = varArgs; } } } else { int i = invocationMethod.getParameterTypes().length; Object[] newValues = Arrays.copyOf(values, i); Object varArgs = null; if (invocationMethod.getParameterTypes()[i - 1].getComponentType() != Object.class) { int varArgCount = values.length - i + 1; varArgs = Array.newInstance( invocationMethod.getParameterTypes()[i - 1].getComponentType(), varArgCount); for (int j = 0; j < varArgCount; j++) { Array.set(varArgs, j, values[i - 1 + j]); } } else { varArgs = Arrays.copyOfRange(values, i - 1, values.length); } newValues[i - 1] = varArgs; values = newValues; } } Object result = invocationMethod.invoke(functionTarget, values); if (context != null && getDeterministic().ordinal() <= Determinism.USER_DETERMINISTIC.ordinal()) { context.setDeterminismLevel(getDeterministic()); } return importValue(result, getReturnType()); } catch (ArithmeticException e) { throw new FunctionExecutionException( QueryPlugin.Event.TEIID30384, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30384, getFullName())); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof BlockedException) { throw (BlockedException) e.getTargetException(); } throw new FunctionExecutionException( QueryPlugin.Event.TEIID30384, e.getTargetException(), QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30384, getFullName())); } catch (IllegalAccessException e) { throw new FunctionExecutionException( QueryPlugin.Event.TEIID30385, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30385, method.toString())); } catch (TransformationException e) { throw new FunctionExecutionException(e); } } public static Object importValue(Object result, Class<?> expectedType) throws ArithmeticException, TransformationException { if (!ALLOW_NAN_INFINITY) { if (result instanceof Double) { Double floatVal = (Double) result; if (Double.isInfinite(floatVal) || Double.isNaN(floatVal)) { throw new ArithmeticException("Infinite or invalid result"); // $NON-NLS-1$ } } else if (result instanceof Float) { Float floatVal = (Float) result; if (Float.isInfinite(floatVal) || Float.isNaN(floatVal)) { throw new ArithmeticException("Infinite or invalid result"); // $NON-NLS-1$ } } } result = DataTypeManager.convertToRuntimeType( result, expectedType != DataTypeManager.DefaultDataClasses.OBJECT); if (expectedType.isArray() && result instanceof ArrayImpl) { return result; } result = DataTypeManager.transformValue(result, expectedType); if (result instanceof String) { String s = (String) result; if (s.length() > DataTypeManager.MAX_STRING_LENGTH) { return s.substring(0, DataTypeManager.MAX_STRING_LENGTH); } } return result; } public boolean isCalledWithVarArgArrayParam() { return calledWithVarArgArrayParam; } public void setCalledWithVarArgArrayParam(boolean calledWithVarArgArrayParam) { this.calledWithVarArgArrayParam = calledWithVarArgArrayParam; } public boolean isSystemFunction(String name) { return this.getName().equalsIgnoreCase(name) && CoreConstants.SYSTEM_MODEL.equals(this.getSchema()); } }
/** Represents the runtime state of a vdb that may aggregate several vdbs. */ public class CompositeVDB { private static final boolean WIDEN_COMPARISON_TO_STRING = PropertiesUtils.getBooleanProperty( System.getProperties(), "org.teiid.widenComparisonToString", true); // $NON-NLS-1$ private VDBMetaData vdb; private MetadataStore store; private LinkedHashMap<String, VDBResources.Resource> visibilityMap; private UDFMetaData udf; LinkedHashMap<VDBKey, CompositeVDB> children; private MetadataStore[] additionalStores; private ConnectorManagerRepository cmr; private FunctionTree systemFunctions; private boolean metadataloadFinished = false; private VDBMetaData mergedVDB; private VDBMetaData originalVDB; private Collection<Future<?>> tasks = Collections.synchronizedSet(new HashSet<Future<?>>()); public CompositeVDB( VDBMetaData vdb, MetadataStore metadataStore, LinkedHashMap<String, VDBResources.Resource> visibilityMap, UDFMetaData udf, FunctionTree systemFunctions, ConnectorManagerRepository cmr, VDBRepository vdbRepository, MetadataStore... additionalStores) throws VirtualDatabaseException { this.vdb = vdb; this.store = metadataStore; this.visibilityMap = visibilityMap; this.udf = udf; this.systemFunctions = systemFunctions; this.cmr = cmr; this.additionalStores = additionalStores; this.mergedVDB = vdb; this.originalVDB = vdb; buildCompositeState(vdbRepository); } private static TransformationMetadata buildTransformationMetaData( VDBMetaData vdb, LinkedHashMap<String, VDBResources.Resource> visibilityMap, MetadataStore store, UDFMetaData udf, FunctionTree systemFunctions, MetadataStore[] additionalStores) { Collection<FunctionTree> udfs = new ArrayList<FunctionTree>(); if (udf != null) { for (Map.Entry<String, UDFSource> entry : udf.getFunctions().entrySet()) { udfs.add(new FunctionTree(entry.getKey(), entry.getValue(), true)); } } CompositeMetadataStore compositeStore = new CompositeMetadataStore(store); for (MetadataStore s : additionalStores) { compositeStore.merge(s); for (Schema schema : s.getSchemas().values()) { if (!schema.getFunctions().isEmpty()) { UDFSource source = new UDFSource(schema.getFunctions().values()); if (udf != null) { source.setClassLoader(udf.getClassLoader()); } udfs.add(new FunctionTree(schema.getName(), source, true)); } if (!schema.getProcedures().isEmpty()) { FunctionTree ft = FunctionTree.getFunctionProcedures(schema); if (ft != null) { udfs.add(ft); } } } } TransformationMetadata metadata = new TransformationMetadata(vdb, compositeStore, visibilityMap, systemFunctions, udfs); metadata.setUseOutputNames(false); metadata.setWidenComparisonToString(WIDEN_COMPARISON_TO_STRING); return metadata; } public VDBMetaData getVDB() { return this.mergedVDB; } private void buildCompositeState(VDBRepository vdbRepository) throws VirtualDatabaseException { if (vdb.getVDBImports().isEmpty()) { this.vdb.addAttchment(ConnectorManagerRepository.class, this.cmr); return; } VDBMetaData newMergedVDB = this.vdb.clone(); ConnectorManagerRepository mergedRepo = this.cmr; if (!this.cmr.isShared()) { mergedRepo = new ConnectorManagerRepository(); mergedRepo.getConnectorManagers().putAll(this.cmr.getConnectorManagers()); } newMergedVDB.addAttchment(ConnectorManagerRepository.class, mergedRepo); ClassLoader[] toSearch = new ClassLoader[vdb.getVDBImports().size() + 1]; toSearch[0] = this.vdb.getAttachment(ClassLoader.class); this.children = new LinkedHashMap<VDBKey, CompositeVDB>(); newMergedVDB.setImportedModels(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)); int i = 1; for (VDBImport vdbImport : vdb.getVDBImports()) { CompositeVDB importedVDB = vdbRepository.getCompositeVDB(new VDBKey(vdbImport.getName(), vdbImport.getVersion())); if (importedVDB == null) { throw new VirtualDatabaseException( RuntimePlugin.Event.TEIID40083, RuntimePlugin.Util.gs( RuntimePlugin.Event.TEIID40083, vdb.getName(), vdb.getVersion(), vdbImport.getName(), vdbImport.getVersion())); } VDBMetaData childVDB = importedVDB.getVDB(); newMergedVDB.getVisibilityOverrides().putAll(childVDB.getVisibilityOverrides()); toSearch[i++] = childVDB.getAttachment(ClassLoader.class); this.children.put(new VDBKey(childVDB.getName(), childVDB.getVersion()), importedVDB); if (vdbImport.isImportDataPolicies()) { for (DataPolicy dp : importedVDB.getVDB().getDataPolicies()) { DataPolicyMetadata role = (DataPolicyMetadata) dp; if (newMergedVDB.addDataPolicy(role) != null) { throw new VirtualDatabaseException( RuntimePlugin.Event.TEIID40084, RuntimePlugin.Util.gs( RuntimePlugin.Event.TEIID40084, vdb.getName(), vdb.getVersion(), vdbImport.getName(), vdbImport.getVersion(), role.getName())); } if (role.isGrantAll()) { role.setSchemas(childVDB.getModelMetaDatas().keySet()); } } } // add models for (ModelMetaData m : childVDB.getModelMetaDatas().values()) { if (newMergedVDB.addModel(m) != null) { throw new VirtualDatabaseException( RuntimePlugin.Event.TEIID40085, RuntimePlugin.Util.gs( RuntimePlugin.Event.TEIID40085, vdb.getName(), vdb.getVersion(), vdbImport.getName(), vdbImport.getVersion(), m.getName())); } newMergedVDB.getImportedModels().add(m.getName()); String visibilityOverride = newMergedVDB.getPropertyValue(m.getName() + ".visible"); // $NON-NLS-1$ if (visibilityOverride != null) { boolean visible = Boolean.valueOf(visibilityOverride); newMergedVDB.setVisibilityOverride(m.getName(), visible); } } ConnectorManagerRepository childCmr = childVDB.getAttachment(ConnectorManagerRepository.class); if (childCmr == null) { throw new AssertionError("childVdb had not connector manager repository"); // $NON-NLS-1$ } if (!this.cmr.isShared()) { for (Map.Entry<String, ConnectorManager> entry : childCmr.getConnectorManagers().entrySet()) { if (mergedRepo.getConnectorManagers().put(entry.getKey(), entry.getValue()) != null) { throw new VirtualDatabaseException( RuntimePlugin.Event.TEIID40086, RuntimePlugin.Util.gs( RuntimePlugin.Event.TEIID40086, vdb.getName(), vdb.getVersion(), vdbImport.getName(), vdbImport.getVersion(), entry.getKey())); } } } } if (toSearch[0] != null) { CombinedClassLoader ccl = new CombinedClassLoader(toSearch[0].getParent(), toSearch); this.mergedVDB.addAttchment(ClassLoader.class, ccl); } this.mergedVDB = newMergedVDB; } private UDFMetaData getUDF() { UDFMetaData mergedUDF = new UDFMetaData(); if (this.udf != null) { mergedUDF.addFunctions(this.udf); } for (Schema schema : store.getSchemas().values()) { Collection<FunctionMethod> funcs = schema.getFunctions().values(); mergedUDF.addFunctions(schema.getName(), funcs); } if (this.cmr != null) { // system scoped common source functions for (ConnectorManager cm : this.cmr.getConnectorManagers().values()) { List<FunctionMethod> funcs = cm.getPushDownFunctions(); mergedUDF.addFunctions(CoreConstants.SYSTEM_MODEL, funcs); } } if (this.children != null) { // udf model functions - also scoped to the model for (CompositeVDB child : this.children.values()) { UDFMetaData funcs = child.getUDF(); if (funcs != null) { mergedUDF.addFunctions(funcs); } } } return mergedUDF; } /** TODO: we are not checking for collisions here. */ private LinkedHashMap<String, VDBResources.Resource> getVisibilityMap() { if (this.children == null || this.children.isEmpty()) { return this.visibilityMap; } LinkedHashMap<String, VDBResources.Resource> mergedvisibilityMap = new LinkedHashMap<String, VDBResources.Resource>(); for (CompositeVDB child : this.children.values()) { LinkedHashMap<String, VDBResources.Resource> vm = child.getVisibilityMap(); if (vm != null) { mergedvisibilityMap.putAll(vm); } } if (this.visibilityMap != null) { mergedvisibilityMap.putAll(this.visibilityMap); } return mergedvisibilityMap; } private MetadataStore getMetadataStore() { return this.store; } VDBMetaData getOriginalVDB() { return originalVDB; } public void metadataLoadFinished() { if (this.metadataloadFinished) { return; } this.metadataloadFinished = true; MetadataStore mergedStore = getMetadataStore(); // the order of the models is important for resolving ddl // TODO we might consider not using the intermediate MetadataStore List<Schema> schemas = mergedStore.getSchemaList(); schemas.clear(); for (ModelMetaData model : this.vdb.getModelMetaDatas().values()) { Schema s = mergedStore.getSchema(model.getName()); if (s != null) { schemas.add(s); } else { mergedStore.getSchemas().remove(model.getName()); } } if (this.children != null && !this.children.isEmpty()) { for (CompositeVDB child : this.children.values()) { MetadataStore childStore = child.getMetadataStore(); if (childStore != null) { mergedStore.merge(childStore); } } } TransformationMetadata metadata = buildTransformationMetaData( mergedVDB, getVisibilityMap(), mergedStore, getUDF(), systemFunctions, this.additionalStores); QueryMetadataInterface qmi = metadata; Map<String, String> multiSourceModels = MultiSourceMetadataWrapper.getMultiSourceModels(mergedVDB); if (multiSourceModels != null && !multiSourceModels.isEmpty()) { qmi = new MultiSourceMetadataWrapper(metadata, multiSourceModels); } mergedVDB.addAttchment(QueryMetadataInterface.class, qmi); mergedVDB.addAttchment(TransformationMetadata.class, metadata); mergedVDB.addAttchment(MetadataStore.class, mergedStore); } LinkedHashMap<VDBKey, CompositeVDB> getChildren() { return children; } public Collection<Future<?>> clearTasks() { ArrayList<Future<?>> copy = new ArrayList<Future<?>>(tasks); tasks.clear(); return copy; } public void removeTask(Future<?> future) { tasks.remove(future); } public void addTask(Future<?> future) { tasks.add(future); } }