/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.salesforce; import static org.teiid.translator.TypeFacility.RUNTIME_NAMES.*; import java.util.Arrays; import java.util.List; import javax.resource.cci.ConnectionFactory; import org.teiid.language.Argument; import org.teiid.language.Call; import org.teiid.language.Command; import org.teiid.language.QueryExpression; import org.teiid.language.visitor.SQLStringVisitor; import org.teiid.logging.LogConstants; import org.teiid.logging.LogManager; import org.teiid.metadata.MetadataFactory; import org.teiid.metadata.Procedure; import org.teiid.metadata.RuntimeMetadata; import org.teiid.translator.ExecutionContext; import org.teiid.translator.ExecutionFactory; import org.teiid.translator.MetadataProcessor; import org.teiid.translator.ProcedureExecution; import org.teiid.translator.ResultSetExecution; import org.teiid.translator.Translator; import org.teiid.translator.TranslatorException; import org.teiid.translator.TranslatorProperty; import org.teiid.translator.UpdateExecution; import org.teiid.translator.salesforce.execution.DeleteExecutionImpl; import org.teiid.translator.salesforce.execution.DirectQueryExecution; import org.teiid.translator.salesforce.execution.InsertExecutionImpl; import org.teiid.translator.salesforce.execution.ProcedureExecutionParentImpl; import org.teiid.translator.salesforce.execution.QueryExecutionImpl; import org.teiid.translator.salesforce.execution.UpdateExecutionImpl; import com.sforce.soap.partner.QueryResult; import com.sforce.soap.partner.sobject.SObject; @Translator(name="salesforce", description="A translator for Salesforce") public class SalesForceExecutionFactory extends ExecutionFactory<ConnectionFactory, SalesforceConnection> { private static final String SALESFORCE = "salesforce"; //$NON-NLS-1$ private static final String EXCLUDES = "excludes";//$NON-NLS-1$ private static final String INCLUDES = "includes";//$NON-NLS-1$ private boolean auditModelFields = false; private int maxInsertBatchSize = 2048; private boolean supportsGroupBy = true; public SalesForceExecutionFactory() { // http://jira.jboss.org/jira/browse/JBEDSP-306 // Salesforce supports ORDER BY, but not on all column types setSupportsOrderBy(false); setSupportsOuterJoins(true); setSupportsInnerJoins(true); setTransactionSupport(TransactionSupport.NONE); setSupportedJoinCriteria(SupportedJoinCriteria.KEY); } @TranslatorProperty(display="Model Audit Fields", advanced=true) public boolean isModelAuditFields() { return this.auditModelFields; } public void setModelAuditFields(boolean modelAuditFields) { this.auditModelFields = modelAuditFields; } @Override public void start() throws TranslatorException { super.start(); addPushDownFunction(SALESFORCE, INCLUDES, BOOLEAN, STRING, STRING); addPushDownFunction(SALESFORCE, EXCLUDES, BOOLEAN, STRING, STRING); LogManager.logTrace(LogConstants.CTX_CONNECTOR, "Salesforce ExecutionFactory Started"); //$NON-NLS-1$ } @Override public ResultSetExecution createResultSetExecution(QueryExpression command, ExecutionContext executionContext, RuntimeMetadata metadata, SalesforceConnection connection) throws TranslatorException { return new QueryExecutionImpl(command, connection, metadata, executionContext, this); } @Override public UpdateExecution createUpdateExecution(Command command, ExecutionContext executionContext, RuntimeMetadata metadata, SalesforceConnection connection) throws TranslatorException { UpdateExecution result = null; if(command instanceof org.teiid.language.Delete) { result = new DeleteExecutionImpl(this, command, connection, metadata, executionContext); } else if (command instanceof org.teiid.language.Insert) { result = new InsertExecutionImpl(this, command, connection, metadata, executionContext); } else if (command instanceof org.teiid.language.Update) { result = new UpdateExecutionImpl(this, command, connection, metadata, executionContext); } return result; } @Override public ProcedureExecution createProcedureExecution(Call command,ExecutionContext executionContext, RuntimeMetadata metadata, SalesforceConnection connection) throws TranslatorException { Procedure metadataObject = command.getMetadataObject(); String nativeQuery = metadataObject.getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false); if (nativeQuery != null) { return new DirectQueryExecution(command.getArguments(), command, connection, metadata, executionContext, nativeQuery, false); } return new ProcedureExecutionParentImpl(command, connection, metadata, executionContext); } @Override public ProcedureExecution createDirectExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, SalesforceConnection connection) throws TranslatorException { return new DirectQueryExecution(arguments.subList(1, arguments.size()), command, connection, metadata, executionContext, (String)arguments.get(0).getArgumentValue().getValue(), true); } @Override public void getMetadata(MetadataFactory metadataFactory, SalesforceConnection connection) throws TranslatorException { metadataFactory.getModelProperties().setProperty("importer.modelAuditFields", String.valueOf(this.auditModelFields)); //$NON-NLS-1$ super.getMetadata(metadataFactory, connection); } @Override public MetadataProcessor<SalesforceConnection> getMetadataProcessor(){ return new SalesForceMetadataProcessor(); } @Override public List<String> getSupportedFunctions() { return Arrays.asList(INCLUDES, EXCLUDES); } @Override public boolean supportsCompareCriteriaEquals() { return true; } @Override public boolean supportsInCriteria() { return true; } @Override public boolean supportsLikeCriteria() { return true; } @Override public boolean supportsRowLimit() { return true; } @Override public boolean supportsAggregatesCountStar() { return true; } @Override public boolean supportsAggregatesCount() { return true; } @Override public boolean supportsAggregatesMax() { return true; } @Override public boolean supportsAggregatesMin() { return true; } @Override public boolean supportsAggregatesSum() { return true; } @Override public boolean supportsAggregatesAvg() { return true; } @TranslatorProperty(display="Supports Group By", description="Defaults to true. Set to false to have Teiid process group by aggregations, such as those returning more than 2000 rows which error in SOQL", advanced=true) @Override public boolean supportsGroupBy() { return this.supportsGroupBy ; } @Override public boolean supportsOnlySingleTableGroupBy() { return true; } @Override public boolean supportsNotCriteria() { return true; } @Override public boolean supportsOrCriteria() { return true; } @Override public boolean supportsCompareCriteriaOrdered() { return true; } @Override public boolean supportsIsNullCriteria() { return true; } @Override public boolean supportsOnlyLiteralComparison() { return true; } @Override public boolean supportsHaving() { return true; } @Override public int getMaxFromGroups() { return 2; } @Override public boolean useAnsiJoin() { return true; } @Override public boolean supportsBulkUpdate() { return true; } @TranslatorProperty(display="Max Bulk Insert Batch Size", description="The max size of a bulk insert batch. Default 2048.", advanced=true) public int getMaxBulkInsertBatchSize() { return maxInsertBatchSize; } public void setMaxBulkInsertBatchSize(int maxInsertBatchSize) { if (maxInsertBatchSize < 1) { throw new AssertionError("Max bulk insert batch size must be greater than 0"); //$NON-NLS-1$ } this.maxInsertBatchSize = maxInsertBatchSize; } public void setSupportsGroupBy(boolean supportsGroupBy) { this.supportsGroupBy = supportsGroupBy; } public QueryResult buildQueryResult(SObject[] objects) { QueryResult result = new QueryResult(); result.setRecords(objects); result.setSize(objects.length); result.setDone(true); return result; } @Override public boolean supportsUpsert() { return true; } }