スイープ・アクション・ハンドラーの実装
スイープ・アクション・ハンドラーの Java™ による実装と JavaScript による実装の例を以下に示します。
ハンドラーは、渡された Document インスタンスのクラスを変更します。ドキュメント・インスタンスは、SweepItem オブジェクトの配列として渡されます。ハンドラーは、配列を反復処理し、各 Document インスタンスのクラスを変更します。
スイープ・アクション・ハンドラーを開発する際には、以下の例に示すベスト・プラクティスに従ってハンドラーをコーディングすることをお勧めします。
- トレース・ロギング用に HandlerCallContext を使用します。
- HandlerCallContext を使用して、ハンドラーを呼び出す際にサーバーがシャットダウン処理中かどうかを判別します。sweepItems 処理ループの先頭で、isShuttingDown メソッドを呼び出します。
- try-catch ブロックを使用して、バッチ内のアイテムごとに結果を設定します。正常に処理された SweepItem オブジェクトについて、ハンドラーは、アイテムの結果を SweepItemOutcome.PROCESSED に設定します。しかし、例外がスローされた場合、ハンドラーの catch ブロックは、アイテムの結果を SweepItemOutcome.FAILED に設定します。失敗の結果について、状況値は、CmSweepResult オブジェクトの形式で永続化されます。
一般に、例外はすべて処理して、呼び出し元に伝搬されることのないようにします。
- getRequiredProperties メソッドを使用します。このメソッドは、ハンドラー処理に必要なプロパティーを指定する名前の配列を返します。
ハンドラーの例では ID プロパティーが必要です。ハンドラーが、処理する SweepItem ごとにこの情報をログに記録するためです。
Java の例
import com.filenet.api.sweep.*;
import com.filenet.api.engine.SweepActionHandler;
import com.filenet.api.engine.SweepItemOutcome;
import com.filenet.api.core.*;
import com.filenet.api.constants.*;
import com.filenet.api.exception.*;
public class CustomSweepHandler implements SweepActionHandler
{
// Implement for custom job and queue sweeps.
public void onSweep(CmSweep sweepObject, SweepActionHandler.SweepItem [] sweepItems)
throws EngineRuntimeException
{
HandlerCallContext hcc = HandlerCallContext.getInstance();
hcc.traceDetail("Entering CustomSweepHandler.onSweep");
hcc.traceDetail("sweepObject = "
+ sweepObject.getProperties().getIdValue(PropertyNames.ID)
+ " sweepItems.length = " + sweepItems.length);
// Iterate the sweepItems and change the class.
for (int i = 0; i < sweepItems.length; i++)
{
// At the top of your loop, always check to make sure
// that the server is not shutting down.
// If it is, clean up and return control to the server.
if (hcc != null && hcc.isShuttingDown())
{
throw new EngineRuntimeException(ExceptionCode.E_BACKGROUND_TASK_TERMINATED,
this.getClass().getSimpleName()
+ " is terminating prematurely because the server is shutting down");
}
// Extract the target object from the SweepItem array.
IndependentlyPersistableObject obj = sweepItems[i].getTarget();
String msg = "sweepItems[" + i + "]= " + obj.getProperties().getIdValue("ID");
hcc.traceDetail(msg);
try
{
Document doc = (Document) obj;
doc.changeClass("{5C1D0459-7F8A-4D6F-A9D1-63C7B3F6A7A9}");
doc.save(RefreshMode.NO_REFRESH);
// Set outcome to PROCESSED if item processed successfully.
sweepItems[i].setOutcome(SweepItemOutcome.PROCESSED,
"item processed by " + this.getClass().getSimpleName());
}
// Set failure status on objects that fail to process.
catch (EngineRuntimeException e)
{
sweepItems[i].setOutcome(SweepItemOutcome.FAILED,
"CustomSweepHandler: " + e.getMessage());
}
}
hcc.traceDetail("Exiting CustomSweepHandler.onSweep");
}
/*
* Called automatically when the handler is invoked by a custom sweep job or sweep policy.
* Specify properties required by the handler, if any.
* If you return an empty array, then all properties are fetched.
*/
public String [] getRequiredProperties()
{
String [] names = {PropertyNames.ID};
return names;
}
/* Implement for custom sweep policies.
* This method is not implemented because this is an example of a custom sweep job.
*/
public void onPolicySweep(CmSweep sweepObject,CmSweepPolicy policyObject,
SweepActionHandler.SweepItem [] sweepItems)
{}
}
JavaScript の例
importPackage(Packages.com.filenet.api.core);
importPackage(Packages.com.filenet.api.constants);
importPackage(Packages.com.filenet.api.exception);
importPackage(Packages.com.filenet.api.sweep);
importPackage(Packages.com.filenet.api.engine);
// Implement for custom job and queue sweeps.
function onSweep (sweepObject, sweepItems)
{
var hcc = HandlerCallContext.getInstance();
hcc.traceDetail("Entering CustomSweepHandler.onSweep");
hcc.traceDetail("sweepObject = "
+ sweepObject.getProperties().getIdValue(PropertyNames.ID)
+ "sweepItems.length = " + sweepItems.length);
// Iterate the sweepItems and change the class.
ii = 0;
for (ii = 0; ii < sweepItems.length; ii++)
{
// At the top of your loop, always check to make sure
// that the server is not shutting down.
// If it is, clean up and return control to the server.
if (hcc != null && hcc.isShuttingDown())
{
throw new EngineRuntimeException(ExceptionCode.E_BACKGROUND_TASK_TERMINATED,
this.constructor.name + " is terminating prematurely because the server is shutting down");
}
var item = sweepItems[ii].getTarget();
String msg = "sweepItems[" + ii + "]= " + item.getProperties().getIdValue("ID");
hcc.traceDetail(msg);
try
{
var doc = Document (item);
doc.changeClass("{5C1D0459-7F8A-4D6F-A9D1-63C7B3F6A7A9}");
doc.save(RefreshMode.NO_REFRESH);
// Set outcome to PROCESSED if item processed successfully.
sweepItems[ii].setOutcome(SweepItemOutcome.PROCESSED,
"item processed by " + this.constructor.name);
}
// Set failure status on objects that fail to process.
catch (ioe)
{
sweepItems[ii].setOutcome(SweepItemOutcome.FAILED, "CustomSweepHandler: " +
ioe.rhinoException.getMessage());
}
}
hcc.traceDetail("Exiting CustomSweepHandler.onSweep");
}
/*
* Called automatically when the handler is invoked by a custom sweep job
* or sweep policy. Specify properties required by the handler, if any.
* If you return an empty array, then all properties are fetched.
*/
function getRequiredProperties()
{
var pnames = ['Id'];
return pnames.toString();
}
/* Implement for custom sweep policies.
* This method is not implemented because this is an example of a custom sweep job.
*/
function onPolicySweep (sweepObject, policyObject, sweepItems)
{}