2

私は、そのクラスのオブジェクトを作成せずにJavaクラスをXMLにマーシャリングできるアルゴリズムを考え出そうとしています(これが問題であり、私が持っているツールで行うのは非常に複雑です)。ログ ファイルからデータを読み取り、それを XML ファイルに変換する必要があります。ログ ファイルのサンプル:

2206:org.powertac.common.RandomSeed::4::init::TariffMarket::0::fees::-6239716112490883981
2213:org.powertac.common.msg.BrokerAccept::null::new::1
2214:org.powertac.common.msg.BrokerAccept::null::new::1::null
2216:org.powertac.common.RandomSeed::5::init::org.powertac.du.DefaultBrokerService::0::pricing::8741252857248937781
2226:org.powertac.common.TariffSpecification::6::new::1::CONSUMPTION
2231:org.powertac.common.Rate::7::new
2231:org.powertac.common.Rate::7::withValue::-0.5
2232:org.powertac.common.Rate::7::setTariffId::6

ログ ファイルのパターンは次のとおりです。

<id>:<class_name>::<order_of_execution>::<method_or_new>::<arguments>

したがって、次の行をに変換したいと思いますXML

2231:org.powertac.common.Rate::7::new

次のように記述されます。

<org.powertac.common.Rate>
    <rate>0</rate>
</org.powertac.common.Rate>

値を提供するパーサーがあるので、そのデータにアクセスできます。これまでのところ、Reflection Java API を使用して汚い仕事をするという考えにたどり着きました。それ以外の場合は、目的を達成するためにシンボル テーブルをほとんど作成する必要がありました。ReflectionAPI を使用してシンボルを検索できることはわかっています。

private static void printMembers(Member[] mbrs, String s) {
    out.format("%s:%n", s);
    for (Member mbr : mbrs) {
        if (mbr instanceof Field)
        out.format("  %s%n", ((Field)mbr).toGenericString());
        else if (mbr instanceof Constructor)
        out.format("  %s%n", ((Constructor)mbr).toGenericString());
        else if (mbr instanceof Method)
        out.format("  %s%n", ((Method)mbr).toGenericString());
    }
    if (mbrs.length == 0)
        out.format("  -- No %s --%n", s);
    out.format("%n");
    }

私が達成しようとしている一例は次のとおりです。

2231:org.powertac.common.Rate::7::withValue::-0.5

次に、class名前を取り、org.powertac.common.Rateを使用しますClass

 Class<?> c = Class.forName(args[0]);
 printMembers(c.getMethods(), "Methods");

withValueメソッドとその引数を返すため、プログラムで次のXMLコードを作成できます。

<org.powertac.common.Rate>
   <withValue>-0.5</withValue>
</org.powertac.common.Rate>

また、methodorを例にclassとると、複雑になる可能性があるobjectため、正しい結果を生成するには何らかの再帰的アプローチが必要です。私はReflectionAPI にまったく慣れていないので、誰かがそれを達成する方法を私よりもよく知っているかどうか疑問に思っていました。ありがとう

*更新 クラスへのアクセス権があり、それらをインスタンス化できますが、正しい引数を見つける必要があるため、これはより複雑なタスクです。

4

2 に答える 2

1

あなたの質問は不明確です:あなたはデータを保存するためのクラスを持っていますか、そうではありませんか?データを表すクラスがまだなく、それらを作成したくない場合は、リフレクションは役に立ちません。

代わりに、JAXPを使用して出力を生成することをお勧めします。を作成しDocument、それにElement子を追加してから、シリアライザーを使用して出力を生成します。いくつかの例を見つけるための「DOMチュートリアル」のためのグーグル。

于 2012-08-29T13:28:52.150 に答える
0

次のクラスの構造を作成するためだけにサンプルアプリケーションを作成しました

class Rate
{
private double minValue;

public Rate withValue(double value)
{
    minValue = value;
    return this;
}

public double getValue()
{
    return minValue;
}
}

次のクラスは、 APIをRate使用して作成しReflection、呼び出しますwithValue

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test
{

public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException,
        IllegalAccessException, InvocationTargetException, InstantiationException
{
    Class<?> class1 = Class.forName("Rate");
    Object obj = class1.newInstance();
    for (Method m : class1.getMethods())
    {
        if (m.getName().equals("withValue"))
        {
            Class<?>[] parameterTypes = m.getParameterTypes();
            System.out.println(Arrays.toString(m.getParameterTypes()));
            Object methodArgs[] = new Object[parameterTypes.length];
            for (Class<?> parameterType : parameterTypes)
            {
                // Here I know there is primitive and double but your logic
                // should check for each and every type
                if (parameterType == Double.TYPE)
                {
                    double value = 0.5;// Value to be passed
                    // directly using 0 since I know only element is there
                    methodArgs[0] = value;
                }
            }
            // Now Creating Rate here directly to check but you may have to
            // again cast to generic object
            Rate rate = (Rate) m.invoke(obj, methodArgs);
            System.out.println(rate.getValue());

        }

    }
}
}
于 2012-08-29T13:56:29.173 に答える