アノテーション・オブジェクトの操作
以下のコード例は、アノテーション関連の操作を示しています。オブジェクトに関するアノテーションの作成例は、汎用的な例です。実際には、アノテーションには何らかのカスタム・サブクラス、またはコンテンツ・エレメントの特定のコンテンツ・タイプ、あるいはその両方が通常使用されます。アノテーションは、特定のクライアント・アプリケーションによって作成および解釈されるものなので、Annotation オブジェクトのコンテンツは通常、そのアプリケーションに固有のフォーマットに従います。このようなアプリケーションの例としては、Application Engine/Workplace XT Image Viewer アプレットがあります。Content Engine では、コンテンツやカスタム・プロパティーの意味は解釈されません。したがって、示されているコード例は、クライアント・アプリケーションが認識できる Annotation オブジェクトを作成するには不十分な可能性があります。
アノテーションの概要については、『アノテーション』を参照してください。
ドキュメントへのアノテーションの付加
Annotation オブジェクトをドキュメントに追加する方法を、次の Java™ および C# の例に示します。 Annotation オブジェクトを作成し、AnnotatedContentElement プロパティーを含むプロパティーを設定します。このオプションのプロパティーはアノテーションとドキュメントの特定のコンテンツ・エレメントを関連付けます。
以下の例では、Factory メソッドを使用して Annotation オブジェクトが直接作成されます。ただし、Document インターフェースは便利メソッド createAnnotation を継承します。このメソッドは、Annotation オブジェクトを間接的に作成し、Annotation オブジェクトに特定のドキュメント・コンテンツ・エレメントを設定します。
Java の例
// ドキュメントのコンテンツ・エレメントに対してプロパティー・フィルターの作成
// これはエレメントを識別するエレメント番号を取得する際に必要
PropertyFilter pf = new PropertyFilter();
pf.addIncludeProperty(new FilterElement(null, null, null, PropertyNames.CONTENT_ELEMENTS, null));
// ドキュメント・オブジェクトのフェッチ
Document doc=Factory.Document.fetchInstance(os, "{2A96C18B-CF94-4853-B105-3F0553A37D7F}", pf);
// ドキュメントの 最初のコンテンツ・エレメントのエレメント・シーケンス番号を取得
ContentElementList docContentList = doc.get_ContentElements();
Integer elementSequenceNumber = ((ContentElement) docContentList.get(0)).get_ElementSequenceNumber();
// アノテーションのコンテンツを作成
Annotation annObject = Factory.Annotation.createInstance(os, "Annotation");
// アノテーションに、そのアノテーションが適用される Document オブジェクトを設定
annObject.set_AnnotatedObject(doc);
// アノテーションが適用されるドキュメントの ContentElement を識別
// ContentElement がそのエレメント・シーケンス番号により識別される
annObject.set_AnnotatedContentElement(elementSequenceNumber.intValue() );
// アノテーションの DescriptiveText プロパティーを設定
annObject.set_DescriptiveText("Annotation applied to the document's 1st content element.");
// アノテーション・コンテンツで File オブジェクトを作成
File annotationFile = new File("C:¥¥annotation.txt");
// アノテーションに ContentTransfer、ContentElementList オブジェクトを作成
ContentTransfer ctObject = Factory.ContentTransfer.createInstance();
ContentElementList annContentList = Factory.ContentTransfer.createList();
try
{
FileInputStream fileIS = new FileInputStream(annotationFile.getAbsolutePath());
ctObject.setCaptureSource(fileIS);
}
catch (Exception e)
{
System.out.println(e.getMessage() );
}
// ContentTransfer オブジェクトをリストに追加し、アノテーションにリストを設定
annContentList.add(ctObject);
annObject.set_ContentElements(annContentList);
annObject.save(RefreshMode.REFRESH);
C# の例
// ドキュメントのコンテンツ・エレメントに対してプロパティー・フィルターの作成
// これはエレメントを識別するエレメント番号を取得する際に必要
PropertyFilter pf = new PropertyFilter();
pf.AddIncludeProperty(new FilterElement(null, null, null, PropertyNames.CONTENT_ELEMENTS, null));
// ドキュメント・オブジェクトのフェッチ
IDocument doc=Factory.Document.FetchInstance(os, "{2A96C18B-CF94-4853-B105-3F0553A37D7F}", pf);
// ドキュメントの 最初のコンテンツ・エレメントのエレメント・シーケンス番号を取得
IContentElementList docContentList = doc.ContentElements;
int elementSequenceNumber = (int)((IContentElement)docContentList[0]).ElementSequenceNumber;
// アノテーションのコンテンツを作成
IAnnotation annObject = Factory.Annotation.CreateInstance(os, "Annotation");
// アノテーションに、そのアノテーションが適用される Document オブジェクトを設定
annObject.AnnotatedObject = doc;
// アノテーションが適用されるドキュメントの ContentElement を指定
// ContentElement がそのエレメント・シーケンス番号により識別される
annObject.AnnotatedContentElement = elementSequenceNumber;
// アノテーションの DescriptiveText プロパティーを設定
annObject.DescriptiveText = "Annotation applied to the document's 1st content element.";
// アノテーション・コンテンツで Stream オブジェクトを作成
Stream fileStream = File.OpenRead(@"C:¥¥annotation.txt");
// アノテーションに ContentTransfer、ContentElementList オブジェクトを作成
IContentTransfer ctObject = Factory.ContentTransfer.CreateInstance();
IContentElementList annContentList = Factory.ContentTransfer.CreateList();
ctObject.SetCaptureSource(fileStream);
// ContentTransfer オブジェクトをリストに追加し、アノテーションにリストを設定
annContentList.Add(ctObject);
annObject.ContentElements = annContentList;
annObject.Save(RefreshMode.REFRESH);
フォルダーへのアノテーションの付加
Annotation オブジェクトをフォルダーに追加する方法を、次の Java および C# の例に示します。 カスタム・オブジェクトの場合も手順は同様です。
Java の例
// Folder オブジェクトを取得
Folder folder=Factory.Folder.getInstance(os, "Folder", new Id("{1A570F51-63B9-4600-B717-03D44ECC54A1}") );
// Annotation オブジェクトを作成し、アノテーションされるオブジェクトに Folder を設定
Annotation annObject = Factory.Annotation.createInstance(os, "Annotation");
annObject.set_DescriptiveText("Annotation applied to folder via Content Engine Java API");
annObject.set_AnnotatedObject(folder);
// アノテーション・コンテンツで File オブジェクトを作成
File annotationFile = new File("C:¥¥annotation.txt");
// アノテーションに ContentTransfer、ContentElementList オブジェクトを作成
ContentTransfer ctObject = Factory.ContentTransfer.createInstance();
ContentElementList contentList = Factory.ContentTransfer.createList();
try
{
FileInputStream fileIS = new FileInputStream(annotationFile.getAbsolutePath());
ctObject.setCaptureSource(fileIS);
}
catch (Exception e)
{
System.out.println(e.getMessage() );
}
// ContentTransfer オブジェクトをリストに追加
contentList.add(ctObject);
annObject.set_ContentElements(contentList);
annObject.save(RefreshMode.REFRESH);
C# の例
// Folder オブジェクトを取得
IFolder folder=Factory.Folder.GetInstance(os, "Folder", new Id("{1A570F51-63B9-4600-B717-03D44ECC54A1}") );
// Annotation オブジェクトを作成し、アノテーションされるオブジェクトに Folder を設定
IAnnotation annObject = Factory.Annotation.CreateInstance(os, "Annotation");
annObject.DescriptiveText = "Annotation applied to folder via Content Engine .NET API";
annObject.AnnotatedObject = folder;
// アノテーション・コンテンツで Stream オブジェクトを作成
Stream fileStream = File.OpenRead(@"C:¥¥annotation.txt");
// アノテーションに ContentTransfer、ContentElementList オブジェクトを作成
IContentTransfer ctObject = Factory.ContentTransfer.CreateInstance();
IContentElementList contentList = Factory.ContentTransfer.CreateList();
ctObject.SetCaptureSource(fileStream);
// ContentTransfer オブジェクトをリストに追加
contentList.Add(ctObject);
annObject.ContentElements = contentList;
annObject.Save(RefreshMode.REFRESH);
アノテーションの取得
Document オブジェクトに適用されているアノテーションの取得方法を、次の Java および C# の例に示します。このコードでは、Document オブジェクトから AnnotationSet オブジェクトを取得し、取得したセットを反復処理しながら、セット内の各 Annotation オブジェクトのプロパティー値を出力します。アノテーションには 複数のコンテンツ・エレメントが含まれることがあるため、コードは Annotation オブジェクトの ContentElementsPresent プロパティーの StringList オブジェクトに対しても反復処理します。
Java の例
// アノテーションに対する PropertyFilter を作成
PropertyFilter pf = new PropertyFilter();
pf.addIncludeProperty(new FilterElement(null, null, null, "Annotations", null));
// ドキュメントを取得する
Document doc=Factory.Document.fetchInstance(os, "{2A96C18B-CF94-4853-B105-3F0553A37D7F}", pf);
// ドキュメントから AnnotationSet を取得
// AnnotationSet を反復処理し、各アノテーションのプロパティー値を表示
AnnotationSet as = doc.get_Annotations();
Iterator iter = as.iterator();
while (iter.hasNext() )
{
Annotation annObject = (Annotation)iter.next();
System.out.println("Name: " + annObject.get_Name() + "¥n" +
"Description: " + annObject.get_DescriptiveText() + "¥n" +
"Document's content element that's annotated: " + annObject.get_AnnotatedContentElement() + "¥n" +
"Content size: " + annObject.get_ContentSize().toString() + "¥n" +
"Storage area: " + annObject.get_StorageArea().get_DisplayName() + "¥n" +
"No. of content elements in annotation: " + annObject.get_ContentElements().size()
);
// アノテーションのコンテンツ・エレメントの MIME タイプを表示
// アノテーションによっては、複数のコンテンツ・エレメントを持つ
StringList sl = annObject.get_ContentElementsPresent();
for(int i=0; i < sl.size(); i++ )
{
System.out.println("MIME type of annotation content element #" + (i+1) + ": " +
sl.get(i) );
}
}
C# の例
// アノテーションに対する PropertyFilter を作成
PropertyFilter pf = new PropertyFilter();
pf.AddIncludeProperty(new FilterElement(null, null, null, PropertyNames.ANNOTATIONS, null));
// ドキュメントを取得する
IDocument doc=Factory.Document.FetchInstance(os, "{2A96C18B-CF94-4853-B105-3F0553A37D7F}", pf);
// ドキュメントから IAnnotationSet を取得
// IAnnotationSet を反復処理し、各アノテーションのプロパティー値を表示
IAnnotationSet annSet = doc.Annotations;
System.Collections.IEnumerator annSetIter = annSet.GetEnumerator();
while (annSetIter.MoveNext())
{
IAnnotation annObject = (IAnnotation)annSetIter.Current;
System.Console.WriteLine("Name: " + annObject.Name + "¥n" +
"Description: " + annObject.DescriptiveText + "¥n" +
"Document's content element that's annotated: " + annObject.AnnotatedContentElement + "¥n" +
"Content size: " + annObject.ContentSize.ToString() + "¥n" +
"Storage area: " + annObject.StorageArea.DisplayName + "¥n" +
"No. of content elements in annotation: " + annObject.ContentElements.Count
);
// アノテーションのコンテンツ・エレメントの MIME タイプを表示
// アノテーションによっては、複数のコンテンツ・エレメントを持つ
IStringList sl = annObject.ContentElementsPresent;
for(int i=0; i < sl.Count; i++ )
{
System.Console.WriteLine("MIME type of annotation content element #" + (i+1) + ": " +
sl[i] );
}
}
異なるストレージ域へのコンテンツの移動
Annotation オブジェクトのコンテンツを異なるストレージ域に移動する方法を、次の Java と C# の例に示します。この例では、領域は FileStorageArea オブジェクトで表されています。
Java の例
// アノテーション・コンテンツを移動する保存領域を取得
FileStorageArea fsa = Factory.FileStorageArea.fetchInstance(os, new Id("{AF44998A-9779-464E-AC23-E94F6E14D79B}"), null);
// コンテンツを移動する Annotation オブジェクトを取得
Annotation annObject = Factory.Annotation.getInstance(os, "Annotation", new Id("{CD467BBD-5CC1-44A4-9842-13368996BDD6}") );
// コンテンツを移動し、Annotation オブジェクトを保存
annObject.moveContent(fsa);
annObject.save(RefreshMode.REFRESH);
C# の例
// アノテーション・コンテンツを移動する保存領域を取得
IFileStorageArea fsa = Factory.FileStorageArea.FetchInstance(os, new Id("{AF44998A-9779-464E-AC23-E94F6E14D79B}"), null);
// コンテンツを移動する IAnnotation オブジェクトを取得
IAnnotation annObject = Factory.Annotation.GetInstance(os, "Annotation", new Id("{CD467BBD-5CC1-44A4-9842-13368996BDD6}") );
// コンテンツを移動し、IAnnotation オブジェクトを保存
annObject.MoveContent(fsa);
annObject.Save(RefreshMode.REFRESH);
アノテーションのサブクラスの作成
システム提供の Annotation 基本クラスからサブクラスを作成する方法を、次の Java および C# の例に示します。この例では、サブクラスに「Proposal」と名前を付け企画書 (proposal) のレビューに必要な、コメント用のアノテーションとして使用します。PropertyTemplateBoolean 型のカスタム・プロパティーがサブクラスに追加されます。このカスタム・プロパティーは「Change Type」と呼ばれ、必要に応じて定義されます。「Change Type」は企画書の作成者に、付加されたアノテーションが単なる意見なのか、必須の変更項目なのかを示すものです。したがって、レビューアーは、企画書にアノテーションを設定する際は、「Change Type」プロパティーを設定しなければなりません。
新規アノテーション・サブクラスを使用すると、「新規サブクラス・インスタンスの作成」で説明するように、新規アノテーション・インスタンスを作成できます。新規サブクラスは、「アノテーションのクラスの変更」で説明するように、別のアノテーション・クラスで定義されている既存インスタンスに適用することもできます。
Java の例
// 選択したクラス定義をサーバーからフェッチ
ClassDefinition parentClassDef = Factory.ClassDefinition.fetchInstance(os, "Annotation", null);
String subclassName = "Proposal";
// Annotaion クラスのサブクラスを作成
ClassDefinition newClassDef = parentClassDef.createSubclass();
// ロケール固有の文字列に必須プロパティーを設定
LocalizedString locStr1 = getLocalizedString(subclassName, os.get_LocaleName() );
newClassDef.set_DisplayNames(Factory.LocalizedString.createList() );
newClassDef.get_DisplayNames().add(locStr1);
LocalizedString locStr2 = getLocalizedString("For annotations specific to Proposal document",
os.get_LocaleName() );
newClassDef.set_DescriptiveTexts(Factory.LocalizedString.createList() );
newClassDef.get_DescriptiveTexts().add(locStr2);
// ブール型のプロパティー用に、必要な値で、新しい PropertyTemplate を作成
PropertyTemplateBoolean newPropTemplate = Factory.PropertyTemplateBoolean.createInstance(os);
newPropTemplate.set_Cardinality (Cardinality.SINGLE);
newPropTemplate.set_IsValueRequired(Boolean.TRUE);
// ロケール固有の文字列に必須プロパティーを設定
LocalizedString locStr3 = getLocalizedString("Change Type", os.get_LocaleName() );
newPropTemplate.set_DisplayNames (Factory.LocalizedString.createList() );
newPropTemplate.get_DisplayNames().add(locStr3);
LocalizedString locStr4 = getLocalizedString("Indicates suggested or required change to proposal",
os.get_LocaleName() );
newPropTemplate.set_DescriptiveTexts(Factory.LocalizedString.createList() );
newPropTemplate.get_DescriptiveTexts().add(locStr4);
// プロパティー・テンプレートをサーバーに保存
newPropTemplate.save(RefreshMode.REFRESH);
// プロパティー・テンプレートからプロパティー定義を作成
PropertyDefinitionBoolean newPropDef = (PropertyDefinitionBoolean)newPropTemplate.createClassProperty();
// PropertyDefinitions プロパティーをプロパティー・キャッシュから取得
PropertyDefinitionList propDefs = newClassDef.get_PropertyDefinitions();
// 新規プロパティー定義をクラス定義に追加
propDefs.add(newPropDef);
newClassDef.save(RefreshMode.REFRESH);
private LocalizedString getLocalizedString(String text, String locale)
{
LocalizedString locStr = Factory.LocalizedString.createInstance ();
locStr.set_LocalizedText(text);
locStr.set_LocaleName (locale);
return locStr;
}
C# の例
// 選択したクラス定義をサーバーからフェッチ
IClassDefinition parentClassDef = Factory.ClassDefinition.FetchInstance(os, "Annotation", null);
String subclassName = "Proposal";
// Annotaion クラスのサブクラスを作成
IClassDefinition newClassDef = parentClassDef.CreateSubclass();
// ロケール固有の文字列に必須プロパティーを設定
ILocalizedString locStr1 = GetLocalizedString(subclassName, os.LocaleName);
newClassDef.DisplayNames = Factory.LocalizedString.CreateList();
newClassDef.DisplayNames.Add(locStr1);
ILocalizedString locStr2 = GetLocalizedString("For annotations specific to Proposal document",
os.LocaleName);
newClassDef.DescriptiveTexts = Factory.LocalizedString.CreateList();
newClassDef.DescriptiveTexts.Add(locStr2);
// ブール型のプロパティー用に、必要な値で、新しい PropertyTemplate を作成
IPropertyTemplateBoolean newPropTemplate = Factory.PropertyTemplateBoolean.CreateInstance(os);
newPropTemplate.Cardinality = Cardinality.SINGLE;
newPropTemplate.IsValueRequired = true;
// ロケール固有の文字列に必須プロパティーを設定
ILocalizedString locStr3 = GetLocalizedString("Change Type", os.LocaleName);
newPropTemplate.DisplayNames = Factory.LocalizedString.CreateList();
newPropTemplate.DisplayNames.Add(locStr3);
ILocalizedString locStr4 = GetLocalizedString("Indicates suggested or required change to proposal",
os.LocaleName);
newPropTemplate.DescriptiveTexts = Factory.LocalizedString.CreateList();
newPropTemplate.DescriptiveTexts.Add(locStr4);
// プロパティー・テンプレートをサーバーに保存
newPropTemplate.Save(RefreshMode.REFRESH);
// プロパティー・テンプレートからプロパティー定義を作成
IPropertyDefinitionBoolean newPropDef = (IPropertyDefinitionBoolean)newPropTemplate.CreateClassProperty();
// PropertyDefinitions プロパティーをプロパティー・キャッシュから取得
IPropertyDefinitionList propDefs = newClassDef.PropertyDefinitions;
// 新規プロパティー定義をクラス定義に追加
propDefs.Add(newPropDef);
newClassDef.Save(RefreshMode.REFRESH);
private ILocalizedString GetLocalizedString(String text, String locale)
{
ILocalizedString locStr = Factory.LocalizedString.CreateInstance();
locStr.LocalizedText = text;
locStr.LocaleName = locale;
return locStr;
}
新規サブクラス・インスタンスの作成
前述のアノテーションのサブクラスの作成で解説したように、「Proposal」という名前のサブクラスを作成しました。「Proposal」サブクラスを使用して新規アノテーションを作成し、それをドキュメントに設定する方法を、次の Java および C# の例に示します。「Proposal」サブクラスには新規アノテーションに設定することが必須であるカスタム・プロパティーが含まれます。これが設定されない場合、新規アノテーションを保存しようとすると例外がスローされます。
Java の例
// 企画書を取得
Document doc=Factory.Document.getInstance(os, "Document", new Id("{512D355A-8DBF-40D4-9485-683CBDF3C860}") );
// Proposal 型のアノテーションを新規作成し、企画書に設定
Annotation annObject = Factory.Annotation.createInstance(os, "Proposal");
annObject.set_DescriptiveText("Annotation of class type Proposal");
annObject.set_AnnotatedObject(doc);
// 必要なカスタム・プロパティーを識別する Proposal クラスを取得
ClassDefinition newClass = Factory.ClassDefinition.fetchInstance(os, "Proposal", null);
PropertyDefinitionList pdl = newClass.get_PropertyDefinitions();
Iterator iter = pdl.iterator();
String custProperty=null;
while (iter.hasNext() )
{
PropertyDefinition pd = (PropertyDefinition)iter.next();
if (!pd.get_IsSystemOwned().booleanValue())
{
System.out.println("Custom property: " + pd.get_DisplayName() );
System.out.println("Value required?: " + pd.get_IsValueRequired() );
custProperty = pd.get_SymbolicName();
}
}
// 新しいアノテーションに必要なカスタム・プロパティーを設定
com.filenet.api.property.Properties props = annObject.getProperties();
props.putValue(custProperty, true);
annObject.save(RefreshMode.REFRESH);
C# の例
// 企画書を取得
IDocument doc=Factory.Document.GetInstance(os, "Document", new Id("{512D355A-8DBF-40D4-9485-683CBDF3C860}") );
// Proposal 型のアノテーションを新規作成し、企画書に設定
IAnnotation annObject = Factory.Annotation.CreateInstance(os, "Proposal");
annObject.DescriptiveText = "Annotation of class type Proposal";
annObject.AnnotatedObject = doc;
// 必要なカスタム・プロパティーを識別する Proposal クラスを取得
IClassDefinition newClass = Factory.ClassDefinition.FetchInstance(os, "Proposal", null);
IPropertyDefinitionList pdl = newClass.PropertyDefinitions;
System.Collections.IEnumerator Iter = pdl.GetEnumerator();
String custProperty=null;
while (Iter.MoveNext())
{
IPropertyDefinition pd = (IPropertyDefinition)Iter.Current;
if (!(bool)pd.IsSystemOwned)
{
System.Console.WriteLine("Custom property: " + pd.DisplayName);
System.Console.WriteLine("Value required?: " + pd.IsValueRequired);
custProperty = pd.SymbolicName;
}
}
// 新しいアノテーションに必要なカスタム・プロパティーを設定
annObject.Properties[custProperty] = true;
annObject.Save(RefreshMode.REFRESH);
アノテーションのクラスの変更
前述のアノテーションのサブクラスの作成で解説したように、「Proposal」という名前のサブクラスを作成しました。アノテーションのクラスを変更することによって、この新規アノテーション・サブクラスを既存のアノテーション・インスタンスに設定する方法を、次の Java および C# の例に示します。既存のアノテーション・インスタンスのプロパティーの設定値は、新規サブクラスの影響を受けません。また、「Change Type」という名前の、「Proposal」サブクラスの必須のカスタム・プロパティーを既存のインスタンスに設定する必要はありません。
Java の例
// 変更するクラスのアノテーションを取得
Annotation annObject = Factory.Annotation.getInstance(os, "Annotation", new Id("{A59A7728-1804-499B-B564-7F6C5443174F}") );
// 新しい「Proposal」サブクラスの ID を指定してクラスを変更し、
// アノテーションを保存
annObject.changeClass("{0E628F78-AF62-49D9-88CB-18B6F4E89210}");
annObject.save(RefreshMode.REFRESH);
C# の例
// 変更するクラスのアノテーションを取得
IAnnotation annObject = Factory.Annotation.GetInstance(os, "Annotation", new Id("{A59A7728-1804-499B-B564-7F6C5443174F}"));
// 新しい「Proposal」サブクラスの ID を指定してクラスを変更し、
// アノテーションを保存
annObject.ChangeClass("{0E628F78-AF62-49D9-88CB-18B6F4E89210}");
annObject.Save(RefreshMode.REFRESH);
アノテーション・テキストの検索
索引付けされたアノテーション・テキストの検索は、索引付けされたドキュメントの内容の検索と同じです。(「照会の操作」セクションの「コンテンツの検索」を参照してください。) 以下の SQL ステートメントは、CONTAINS 演算子を使用して、索引付けされたアノテーション・テキスト (この例では「test」という単語) を検索する方法を示しています。
SELECT anno.This FROM Annotation anno INNER JOIN ContentSearch c ON anno.This = c.QueriedObject WHERE CONTAINS(anno.*, 'test')
以下の SQL ステートメントは、アノテーションの索引付けされたプロパティーの文字列を検索します (ただし、フォルダー・プロパティーの文字列に関しては同じになります)。
SELECT anno.This FROM Annotation anno INNER JOIN ContentSearch c ON anno.This = c.QueriedObject WHERE CONTAINS(IndexedPropString1, 'test')