[Salesforce SOAP API] SOQLラッパー

 Salesforce API Java
2013.07.22

唐突に、Salesforce.com SOAP APIの、
SOQL (Salesforce Object Query Language) の実行クラスをラップしたっていう話。

 

Clouds in the ceiling Clouds in the ceiling / Jon Mountjoy

 

.wsdlから生成したスタブだけではどうにもあれだと思っていたら、ちゃんとあった。
Using a Wrapper Class for Common API Functions

 

1行でログインしたい。メソッド追加。

public SfdcClient login(String username, String password) throws UnexpectedErrorFault,
		InvalidIdFault, LoginFault, RemoteException, ServiceException {
	setUsername(username);
	setPassword(password);
	login();
	return this;
}

 

エラーがあったらログを吐きたいので、ちょっと修正。

if (records.length <= batchSize) {
	checkLogin();
- 	return batchOperation.perform(records);
+	SaveResult[] saveResults = batchOperation.perform(records);
+	for (SaveResult result : saveResults) {
+		Logger.error(result.isSuccess() ? "success" : result.getId());
+		if (result.getErrors().length > 0) {
+			for (com.sforce.soap.partner.Error error : result.getErrors()) {
+				Logger.error(error.getMessage());
+				Logger.error(Arrays.toString(error.getFields()));
+			}
+		}
+	}
+	return saveResults;
}

 

うん、いい。

 

あとSOQL実行で返ってくるQueryResult、
Iterator実装してほしかったしQueryMoreとか気にしたくないし、自前でラップ。

package supinf.sample;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;

import com.sforce.soap.partner.QueryResult;
import com.sforce.soap.partner.sobject.SObject;

/**
 * Wrapped class of Force.com's QueryResult
 * @author SUPINF
 */
public class SfdcResultSet implements Iterator {
	private QueryResult rawQueryResult;
	private Iterator buffer;
	private boolean done;

	public SfdcResultSet(String query) throws Exception {
		this.rawQueryResult = SfdcSoap.client().executeQuery(query);
		judge();
	}
	private void judge() {
		if ((this.rawQueryResult == null) || (this.rawQueryResult.getSize() == 0)) {
			this.buffer = Collections.emptyList().iterator();
			this.done = true;
		} else {
			this.buffer = Arrays.asList(this.rawQueryResult.getRecords()).iterator();
			this.done = false;
		}
	}

	@Override
	public boolean hasNext() {
		if (this.done && (! this.buffer.hasNext())) {
			return false;
		}
		if ((! this.done) && (! this.buffer.hasNext())) {
			try {
				this.rawQueryResult = SfdcSoap.client().executeQueryMore(
						rawQueryResult.getQueryLocator());
			} catch (Exception ignore) {
				this.rawQueryResult = null;
			}
			judge();
		}
		return this.buffer.hasNext();
	}

	@Override
	public SObject next() {
		return this.buffer.next();
	}

	@Override
	public void remove() {
	}
}

いい。