4

バックグラウンド

componentFromJsonJSON からコンポーネント グラフを再構成できる関数を作成しようとしています。getMetaDataコンポーネントのプロパティを検索して適切な型をインスタンス化するために使用している単純なアプローチを採用しました。

関数は次のように使用されます。comp = componentFromJson(json, 'RootComponentType')

問題

問題は、以下に示すように、名前空間がインポートされている可能性があるため、プロパティの型が必ずしも完全修飾されていないことです。

<cfimport path="some.namespace.Test">

<cfcomponent>
    <cfproperty name="test" type="Test">
</cfcomponent>

createObject('Test')関数コンテキストから実行しようとするとcomponentFromJson、呼び出しコンテキストにインポートがないため、明らかに失敗します。

親コンポーネントでコンポーネント ファクトリ関数を一時的に動的に定義し、親 CFC のコンテキストでファクトリ関数を呼び出すために使用するなど、さまざまな方法で問題を解決しようとしましinvokeたが、うまくいきません。

例えば

<cfscript>
    parentCmp = createObject('SomeCmp');
    parentCmp.createComponent = function (type) {
        return createObject(type);
    };
    childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>

恐ろしい解決策

現時点でこの問題を解決するには、CFC の ColdFusion コードを解析してインポート ステートメントを抽出するしかないと思いますが、これは目的に対して遅すぎると予想されます。それだけでなく、これはすべてのエッジケースをカバーするわけではありません.

アイデア?

誰かがこの問題を解決するためのより良いアイデアを持っているかどうか知りたいですか? 私が取ることができるまったく異なるアプローチはありますか?おそらく、ColdFusion ランタイム クラスを使用してこれを行う方法がありますが、まだわかりません。

4

1 に答える 1

1

ColdFusion ランタイムの根底にあるメカニズムを知っていれば、それほど難しくはなかったことがわかります (最初は見つけるのに苦労しました)。

として表される ColdFusion コンポーネントが、メソッドを持つインスタンスをcoldfusion.runtime.TemplateProxyカプセル化していたことを最終的に発見しました。coldfusion.runtime.CFPagecreateObject

したがって、Javaリフレクションを使用して思いついたソリューションは次のとおりです。

<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>
于 2016-08-24T22:28:56.780 に答える