【VSeWSS で作る製品パッケージ(3)】 Provisioning Handler の活用


環境 :
Microsoft Office SharePoint Server (MOSS) 2007
Visual Studio 2005
Visual Studio 2005 Extensions for Windows SharePoint Services 3.0 (VSeWSS) Version 1.0 または 1.1

VSeWSS で作る製品パッケージ

  1. VSeWSS 進化のポイント
  2. CAML によるサイト/フィーチャーカスタマイズの基本
  3. Provisioning Handler の活用
  4. 新機能 WSP View の活用(例 : Workflow feature の追加)
  5. 新機能 WSP View の活用(例 : Master Page feature の追加)

こんにち 

こんにちは。

またまた VSeWSS 1.1 の新機能の話ではありませんが (VSeWSS 1.0 から使える機能です)、Solution Generator を有効に活用してもらうための大切な予備知識 (最終回へのプロローグ) として、今回は Site Provisioning Handler について記載をおこなっておきます。

前回、CAML (XML) で設定するサイト定義の話を記載しましたが、設定によっては CAML で記載できないものがあり、こうした場合は「コード」(プログラム)の出番になってきます。今回は、これを「Web パーツ (WebPart) の接続」を例に記載していくことにします。

今回は、かなり前に記載した こちら のブログの Web パーツの サンプル を使います。(← サンプルコードをダウンロードできるように変更しておきました! コードの中では、SQL Server のサンプルデータベースである AdventureWorks に接続していますので、AdventureWorks データベースの準備と、コード内の接続文字列の変更をおこなっておいてください。)

まずは、以下に実験をしてみましょう。

  1. SharePoint (MOSS/WSS) から [空のサイト] でサイトを新規作成し、トップページに上記 (サンプルソース) の Web Parts を挿入して Web パーツどうしを接続してみます (下図)。



  2. このサイトを VSeWSS の Solution Generator を使用してサイト定義 (Site Definition) として抽出します (Visual Studio のプロジェクトが作成されます。この詳細は前回記述していますので省略します。)

  3. 作成されたサイト定義のプロジェクト (Visual Studio のプロジェクト) をそのままビルドし、配置 (デプロイ) してみましょう。

  4. サイト定義がサイトテンプレートとして組み込まれましたので、あとは、SharePoint 上からこのテンプレートを使ってサイトの作成をおこないます (下図)。

さてここで、作成されたサイトを確認してみてください。実は、先ほど設定したはずの Web パーツの接続関係は切れてしまっているのがわかります。

SharePoint がデフォルトで提供しているサイトテンプレートや、各社から出ているアドイン製品、ダウンロード可能なアドイン機能 (コニュニティサイトなどで配布されているもの) などにおいても、実際、こうした接続関係を維持したサイトテンプレートは少ないと思います。このようになってしまう理由は、CAML の XML 上 (もしくは default.aspx などの UI 上) にはこの「接続」関係は構成として反映されないためです。
ではこうしたことが必要になった場合の対策はないのでしょうか?

そこで、こうした規定の CAML の仕様を超えたカスタマイズの場合にはコード(プログラム) の出番になります。では、Web パーツの接続がおこなえるようにコード(プログラム)を記載してみたいと思います。

まず、ご存じの方も多いかもしれませんが、フィーチャー(feature)フレームワークでは、存在するフィーチャー以外にまったく自作のコードを使ったカスタムフィーチャーを作成することができます。非常にざっくりとした書き方をしますが、SPFeatureReceiver 抽象クラスを継承して、インストール時の動作 (FeatureInstalled オーバーライドメソッド)、Activate 時の動作 (FeatureActivated オーバーライドメソッド)、などを実装することで、例えば、あるフィーチャーをサイトにインストールすると「サイトのタイトルが変更される」といったような、コードで実現可能な自由自在なフィーチャーを自作することができます。
「では、今回もこの方法で切り抜けよう!」と思うかもしれませんが、実は今回はその手法を使うことができません。理由は前回の投稿をみて頂くと明白です。今回は、フィーチャーそのものをインストールするときに実行すべき設定ではありません。フィーチャーをインストールした際には「サイトテンプレート」がインストールされ、ユーザ(利用者)がその「サイトテンプレート」から「サイト」を作る、その "タイミング!" で実行しなければなりません。
こうしたタイミングで動作する処理が、今回ご紹介する「サイト プロビジョニング」 (Site Provisioning Handler) です。

では、このサイトプロビジョニングを使用して Web パーツどうしの接続を設定してみましょう。

まず、先ほど作成したサイト定義のプロジェクトを Visual Studio で開いてみましょう。
「Site Provisioning Handler」というフォルダに SiteProvisioning.cs というソースがあり、ここに OnActivated というメソッドがあるのがわかります。これが前述した「サイトが作成されたとき」に呼ばれる処理になります。
ですので、ここに以下の処理を記述します。(今回は Web パーツどうしの接続なので、以下のような記述になります)

public void OnActivated(SPFeatureReceiverProperties properties)
{
    // 作成する「サイト」を取得 (サイトコレクションの場合もあるためチャック!)
    SPWeb web;
    if (properties.Feature.Parent is SPWeb)
        web = (SPWeb) properties.Feature.Parent;
    else
        web = ((SPSite)properties.Feature.Parent).RootWeb;

    // このサイトの default.aspx 上の Web パーツマネージャを取得
    Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager partmgr = web.GetLimitedWebPartManager("default.aspx", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

    // 接続する Web パーツを取得
    System.Web.UI.WebControls.WebParts.WebPart webpart1 = partmgr.WebParts[1];
    System.Web.UI.WebControls.WebParts.WebPart webpart2 = partmgr.WebParts[2];

    // プロバイダとコンシューマのコネクションポイントを取得して接続
    System.Web.UI.WebControls.WebParts.ProviderConnectionPoint point1 = partmgr.GetProviderConnectionPoints(webpart1)["ITransformableFilterValues"];
    System.Web.UI.WebControls.WebParts.ConsumerConnectionPoint point2 = partmgr.GetConsumerConnectionPoints(webpart2)["IFilterValues"];
    Microsoft.SharePoint.WebPartPages.TransformableFilterValuesToFilterValuesTransformer trans = new Microsoft.SharePoint.WebPartPages.TransformableFilterValuesToFilterValuesTransformer();
    partmgr.SPWebPartConnections.Add(partmgr.SPConnectWebParts(webpart1, point1, webpart2, point2, trans));
}

上記で、partmgr.WebParts[1]、partmgr.WebParts[2] と記載している箇所は、onet.xml において AllUsersWebPart タグで挿入されている Web パーツの順番です。
また、Web パーツどうしの接続では、コンシューマ (Consumer) とプロバイダー (Provider) という概念がありました (こちら の投稿を思い出してください)。最後のほうでわけのわからない処理を記述しているように思うかもしれませんが、こちら の投稿に載せたソースをみて頂くとおわかりのように、プロバイダー (Provider) 側の Web パーツでは ITransformableFilterValues インタフェースを渡し、コンシューマ (Consumer) 側では IFilterValues インタフェースを受け取っています。このように異なるインタフェースどうしを接続する必要があるため、上記のソースではこの変換のための Transfomer クラス(変換クラス) を作成して接続をおこなっているのです。
ですので最後の箇所は接続する Web パーツによってコードが変わってきます。(なお、インタフェースが同じ場合には、変換クラスや SPConnectWebParts メソッドの最後の引数は必要ありません)

では先ほどインストールしてしまったサイト定義を setup.bat /uninstall でアンインストールし、再度ハンドラが変更された上記のサイト定義を使ってビルドと配置 (デプロイ) をおこなってみましょう。(注意ですが、リビルドをおこなって setup.bat で配置すると、binDebug 下の solution フォルダや .wsp ファイルが再作成されず、プログラムを変えても配置するアセンブリなども更新されません。ですので、こうした場合には、必ず Visual Studio の中から [配置] を選択して配置してください。)
今度は、サイト作成をおこなうと、めでたく 2 つの Web パーツどうしが接続された状態でサイトが作成されるはずです。

なお、この Provisioning Handler をデバッグするには、いったんブラウザなどでサイトにアクセスして (ワーカープロセス(w3wp.exe) を確実に起動してから)、ブレークポイントを置いて、メニュー [デバッグ] - [プロセスにアタッチ] で w3wp.exe をすべてアタッチします。(web.config で compilation debug を true にしておくのを忘れないようにしてください。)
コードのバグなどでゴミのサイト (UI から表示されず見えないサイトなど) が作成されてしまった場合は、以下のコマンドで削除しておくと良いでしょう。

stsadm -o deleteweb -url <ゴミになっているサイトの URL>

今回は Web パーツの例ですが、ソリューションパッケージで細かな制御を考えはじめると、実は CAML のカスタマイズでは不可能なこうした処理がいくつか存在することに気づきます。こうした場合には、上記のようにコードを記述します。

さて、これで何でもかんでも自由自在にパッケージ作成ができるような気がするかもしれませんが、実は VSeWSS 1.0 には、「便利さ」 ゆえの見返りとして、これらの方法を使っても回避不可能なある重大な課題が残っていました。
次回は、いよいよ VSeWSS 1.1 の WSP ビュー (新機能) を使って、この点を説明していきたいと思います (今回の Provisioning Handler などもおそらく使うことになりますので、次回読まれる際も概念は頭にとどめておいてください)。

 

Comments (3)

  1. 環境: Microsoft Office SharePoint Server (MOSS) 2007 Visual Studio 2005 Visual Studio 2005 Extensions for

  2. こんにちは。 Visual Studio 2005 Extensions for Windows Share Service 3.0 (VSeWSS) の新バージョン 1.1 について、その日本語版が、昨日提供されました。

Skip to main content