Z
Zergling
Gast
Hallo,
wer nicht alles lesen möchte, ich habe die Frage einmal zusammengefasst:
Also Kurzzusammenfassung:
Ich habe das Propertyfile config.properties:
Wie kann ich daraus ein:
basteln?
Die Frage im Kontext:
Ich arbeite seit einiger Zeit mit Ant. Dabei sollen C++ Klassen kompiliert werden, welche wiederrum von anderen abhängig sein können, welche auch wiederum von anderen abhängig sein können usw. Sprich ich habe eine unbekannte Tiefe von Abhängigkeiten.
Definiert ist das in einem Ant-Propertyfile (config.properties) z.B. so:
list = KlasseA
KlasseA = KlasseB,KlasseC,KlasseD
KlasseC = KlasseE
KlasseD = KlasseE,KlasseF
KlasseG = KlasseH
Mein Ziel ist es, eine Property zu haben, die dann so aussieht:
return = KlasseA,KlasseB,KlasseC,KlasseE,KlasseD,KlasseE,KlasseF.
Ein Ant-Target, dass mir doppelte Einträge herauslöscht habe ich bereits geschrieben.
Soviel zum Zweck und Ziel meiner Aufgabe.
Mein Lösungsansatz war, in einer foreach-Schleife alle Elemente durchzulaufen, zu prüfen ob ein Element als Property existiert und das Value davon erneut als Liste zu interpretieren und in der obigen foreach-Schleife auch zu durchlaufen. Wenn ein ListenElement keine Property ist (z.B. KlasseB) wird diese in einer return-Property hinzugefügt.
Soweit so gut, mein Lösungsansatz bis jetzt:
Wobei dem XML-Build die Property
config.properties (Dateiname, Datei enthält list-Property und die Zuordnung der Abhängigkeiten)
tmp.properties (Dateiname, temporäre Properties)
delimiter ist Trennzeichen der Liste
Ein Selbstaufruf per <antcall> schlägt fehl, da Propertys nicht überschrieben werden können (in einer Datei schon, nicht aber zur Laufzeit wieder abgefragt werden können). Ein kompletter Selbstaufruf per <exec> schlägt wegen einer IOException auch fehl (darum habe ich probiert, dass von der build.xml eine Kopie angelegt wird, welche dann aufgerufen wird, klappt auch nicht).
Ich habe die Info gefunden, es soll per JavaScript in Ant möglich sein, rekursiv vorzugehen, allerdings habe ich dazu nur ein Beispiel für einen Ordnerdurchlauf gefunden, was mir nicht weitergeholfen. Ich habe zwar solide bis gute JavaScript Vorkenntnisse, aber bekannt kam mir bei diesem Beispiel auch überhaupt nichts vor. Außer eben der Syntax, aber die kann ja ja jeder mit Programmier-Vorkenntnissen.
wer nicht alles lesen möchte, ich habe die Frage einmal zusammengefasst:
Also Kurzzusammenfassung:
Ich habe das Propertyfile config.properties:
Code:
list = KlasseA
KlasseA = KlasseB,KlasseC,KlasseD
KlasseC = KlasseE
KlasseD = KlasseE,KlasseF
KlasseG = KlasseH
Wie kann ich daraus ein:
Code:
all = KlasseA,KlasseB,KlasseC,KlasseE,KlasseD,KlasseE,KlasseF
basteln?
Die Frage im Kontext:
Ich arbeite seit einiger Zeit mit Ant. Dabei sollen C++ Klassen kompiliert werden, welche wiederrum von anderen abhängig sein können, welche auch wiederum von anderen abhängig sein können usw. Sprich ich habe eine unbekannte Tiefe von Abhängigkeiten.
Definiert ist das in einem Ant-Propertyfile (config.properties) z.B. so:
list = KlasseA
KlasseA = KlasseB,KlasseC,KlasseD
KlasseC = KlasseE
KlasseD = KlasseE,KlasseF
KlasseG = KlasseH
Mein Ziel ist es, eine Property zu haben, die dann so aussieht:
return = KlasseA,KlasseB,KlasseC,KlasseE,KlasseD,KlasseE,KlasseF.
Ein Ant-Target, dass mir doppelte Einträge herauslöscht habe ich bereits geschrieben.
Soviel zum Zweck und Ziel meiner Aufgabe.
Mein Lösungsansatz war, in einer foreach-Schleife alle Elemente durchzulaufen, zu prüfen ob ein Element als Property existiert und das Value davon erneut als Liste zu interpretieren und in der obigen foreach-Schleife auch zu durchlaufen. Wenn ein ListenElement keine Property ist (z.B. KlasseB) wird diese in einer return-Property hinzugefügt.
Soweit so gut, mein Lösungsansatz bis jetzt:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Build RecursiveList" default="recursiveList_all">
<target name="recursiveList_init">
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<if>
<not><isset property="config.properties"/></not>
<then>
<fail>Property &config.properties& is not set.</fail>
</then>
</if>
<if>
<not><isset property="tmp.properties"/></not>
<then>
<fail>Property &tmp.properties& is not set.</fail>
</then>
</if>
<property file="${config.properties}"/>
<if>
<not><isset property="list"/></not>
<then>
<fail>Config file &${config.properties}& does not set property &list&.</fail>
</then>
</if>
<if>
<not><isset property="delimiter"/></not>
<then>
<property name="delimiter" value="+"/>
</then>
</if>
<if>
<not><isset property="self"/></not>
<then>
<property name="self" value="build-recursiveList.xml"/>
</then>
</if>
<propertyfile file="${tmp.properties}">
<entry key="counter" value="0"/>
</propertyfile>
</target>
<target name="recursiveList">
<property file="${tmp.properties}"/>
<foreach list="${list}" delimiter="${delimiter}" target="recursiveList_single" param="current" inheritall="true"/>
</target>
<target name="recursiveList_single">
<propertyfile file="${tmp.properties}">
<entry key="counter" operation="+" type="int" value="1" default="0"/>
</propertyfile>
<property file="${tmp.properties}"/>
<if>
<isset property="${current}"/>
<then>
<propertycopy name="content" from="${current}"/>
<property name="tmp.config.properties" value="tmp.${counter}.config.properties"/>
<property name="tmp.tmp.properties" value="tmp.${counter}.tmp.properties"/>
<copy file="${config.properties}" tofile="${tmp.config.properties}"/>
<replaceregexp file="${tmp.config.properties}"
match="list\s*=\s*(.*)"
replace="list=${content}"/>
<!--<ant antfile="build-recursiveList.xml" inheritall="false">
<property name="config.properties" value="${tmp.config.properties}"/>
<property name="tmp.properties" value="${tmp.properties}"/>
<property name="delimiter" value="${delimiter}"/>
</ant>-->
<copy file="${self}" tofile="tmp.${self}"/>
<exec executable="ant">
<arg line="-buildfile tmp.${self} -Dconfig.properties=${tmp.config.properties} -Dtmp.properties=${tmp.tmp.properties} -Dself=copy.${self}"/>
</exec>
<delete file="tmp.${self}"/>
</then>
<else>
<echo>Property &${current}& is not set, no recursion needed here.</echo>
</else>
</if>
<propertyfile file="${tmp.properties}">
<entry key="recursiveList.return" operation="+" type="string" value="${current}${delimiter}" default=""/>
</propertyfile>
</target>
<target name="recursiveList_summary">
<property file="${tmp.properties}"/>
<echo>
--- RecursiveList --- summary ----------------------------------
List : ${list}
Delimiter : ${delimiter}
Return : ${recursiveList.return}
</echo>
</target>
<target name="recursiveList_all" depends="recursiveList_init,recursiveList,recursiveList_summary"/>
</project>
Wobei dem XML-Build die Property
config.properties (Dateiname, Datei enthält list-Property und die Zuordnung der Abhängigkeiten)
tmp.properties (Dateiname, temporäre Properties)
delimiter ist Trennzeichen der Liste
Ein Selbstaufruf per <antcall> schlägt fehl, da Propertys nicht überschrieben werden können (in einer Datei schon, nicht aber zur Laufzeit wieder abgefragt werden können). Ein kompletter Selbstaufruf per <exec> schlägt wegen einer IOException auch fehl (darum habe ich probiert, dass von der build.xml eine Kopie angelegt wird, welche dann aufgerufen wird, klappt auch nicht).
Ich habe die Info gefunden, es soll per JavaScript in Ant möglich sein, rekursiv vorzugehen, allerdings habe ich dazu nur ein Beispiel für einen Ordnerdurchlauf gefunden, was mir nicht weitergeholfen. Ich habe zwar solide bis gute JavaScript Vorkenntnisse, aber bekannt kam mir bei diesem Beispiel auch überhaupt nichts vor. Außer eben der Syntax, aber die kann ja ja jeder mit Programmier-Vorkenntnissen.