Functionalizing few lines of code with ant macrodef - function

I am trying to "function"alize few lines of ant-code using macrodef. But its resulting in error like :
copy doesn't support the nested "my-macro" element.
If I "inline" definition of my-macro of adding filterchian within copy-task it works.
My test target looks like this -
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<my-macro/>
</copy>
</sequential>
</target>
And my-macro looks like this:
<macrodef name="my-macro">
<sequential>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</sequential>
</macrodef>
Code which works (inlined-one ) looks like :
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</copy>
</sequential></target>

The copy task doesn't accept a nested macro element, thats what the errormessage says.
Put the whole copy stuff into your macrodef, f.e. :
<macrodef name="my-macro">
<attribute name="dest"/>
<attribute name="fsdir"/>
<attribute name="fsincludes"/>
<attribute name="fsexcludes"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="#dest}">
<fileset dir="#{fsdir}">
<include name="#{fsincludes}"/>
<exclude name="#{fsexcludes}"/>
</fileset>
<filterchain>
<fixcrlf includes="#{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
-- EDIT --
If number of filesets varies, remove the fsincludes and fsexcludes attribute if not valid for all filesets and use element like that :
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="#dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="#{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
</my-macro>
-- EDIT --
To copy a single file with nested fileset use :
<fileset file="C:/somepath/some.file"/>
-- EDIT --
If you need other copysteps with file tofile, you may use another element if that is sufficient:
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="copyfiles" description="nested copy"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="#dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="#{fixincl}" eol="lf"/>
</filterchain>
</copy>
<copyfiles/>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
<copyfiles>
<copy file="..." tofile="..."/>
<!-- ... -->
</copyfiles>
</my-macro>
Normally for bulk renaming of files a mapper is used.
After all if it gets more complicated you should consider scripting with Groovy or write your own Ant Task.

Rebse's answer already shows what you should go with <macrodef>, and here's some explanation.
Copy Task
<copy>, <macrodef>, <sequential> are Ant tasks. Each Ant task is backed with Java code. Most of Java classes of built-in Ant tasks are under org.apache.tools.ant.taskdefs, e.g. Copy.java is the backend of <copy> task.
The nested elements of a task is handled by the task's Java code. For <copy> task, it's code in Copy.java (or other classes it depends on) handling the nested elements.
You will see in Copy.java methods named with createFilterChain, addFileset, createMapper and others. That's why <copy> supports fileset, filterchain, mapper and other nested elements stated in Copy's manual page.
Macrodef
This defines a new task using a nested task as a template.
Macrodef is a way to define an Ant task without coding in Java. It turns its nested Ant xml lines into a new task, which works the same way as other Ant tasks.
Obviously, you should not just put a <filterchain> in <macrodef>, as <filterchain> is not an Ant task, but an Ant type.

Related

Add a block to product page by custom module without editing magento default template

I am trying to add a block to product page by using my custom module.
I do not want to modify any magento default files for this. I know it's possible by modifying the code in view.phtml template. Below is what I tried so far. I have copied the default magento view.phtml file in all module template folder as below. I included layout file inside config.xml of my module and written code for the block.
view.phtml file I placed under each template of module folder.
app/desifn/frontend/default/default/template/mymodule/view.phtml
config.xml file of module -
<frontend>
<routers>
<modulename>
<use>standard</use>
<args>
<module>Module_name</module>
<frontName>modulefrontname</ntNafrome>
</args>
</modulename>
</routers>
<layout>
<updates>
<modulename module="module_name">
<file>module.xml</file>
</modulename>
</updates>
</layout>
</frontend>
This file is under -
app/desifn/frontend/default/default/layout/modulename.xml
<reference name="product.info">
<block type="module_name/product_view" name="product_list">
<action method="setTemplate" ifconfig="module_name/sp_category/status">
<template>modulename/product/view.phtml</template>
</action>
</block>
</reference>
Node modulename is invalid (wrong closing tag)
<updates>
<modulename module="module_name">
<file>module.xml</file>
</module>
</updates>
and also template paths do not match
/mymodule/view.phtml
and
modulename/product/view.phtml
But back to your initial Question:
view.phtml of default template does not contain getChildHtml without any parameters. So the only way to inject custom stuff is to use a block of type core/text_list, which is "product.info.simple.extra". All you need is to make use of before or after attributes in your xml layout.

How to include biml file when it has more than one root node?

I have a biml file and want to use the include directive to bring in biml from another file that can get reused in other places, but it keeps giving this error when I do Check for Errors with BIDSHelper:
There are multiple root elements
I see examples online of people using the include directive but no mention on this problem. I can't find any valid element to wrap my biml in, it has to be this chunk.
ErrorHandling.biml:
<UnionAll Name="Union Errors">
<InputPaths>
<InputPath OutputPathName="Lookup Site.Error" />
<InputPath OutputPathName="Detail Level Source.Error" />
<InputPath OutputPathName="Site to Integer.Error" />
</InputPaths>
</UnionAll>
<DerivedColumns Name="Error Metadata">
<InputPath OutputPathName="Union Errors.Output" />
<Columns>
<Column Name="execution_guid" DataType="AnsiString" Length="50" CodePage="1252">(DT_STR,50,1252)#[User::ExecutionGUID]</Column>
<Column Name="error_time" DataType="DateTime" >GETDATE()</Column>
<Column Name="PackageID" DataType="AnsiString" Length="38" CodePage="1252">(DT_STR,38,1252)#[System::PackageID]</Column>
<Column Name="DataflowID" DataType="AnsiString" Length="38" CodePage="1252">(DT_STR,38,1252)#[System::TaskID]</Column>
<Column Name="Step_Name" DataType="AnsiString" Length="50" CodePage="1252">(DT_STR,50,1252)"QI Load"</Column>
<Column Name="Task_Name" DataType="AnsiString" Length="50" CodePage="1252">(DT_STR,50,1252)"Detail Level Check"</Column>
</Columns>
</DerivedColumns>
Master.biml snippet:
<RowCount Name="Row Count" VariableName="User.CheckRowCount">
<InputPath OutputPathName="Lookup Site.Match" />
</RowCount>
<## include file="ErrorHandling.biml" #>
</Transformations>
I found two ways to get this to work- either change the extension of the file to something like .txt or simply don't select it when you "compile" your files with BIDSHelper and do "Check BIML for Errors" or "Generate SSIS packages". Just select the main files that use any included files and contain proper XML.

How to Prevent the TransformXml build task replacing line breaks?

I am using the following in my project files:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterCompile" Condition="Exists('App.$(Configuration).config')">
<!--Generate transformed app config in the intermediate directory-->
<TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
<!--Force build process to use the transformed configuration file from now on.-->
<ItemGroup>
<AppConfigWithTargetPath Remove="App.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
However, if I have a config item on multi-lines
<add key="MultiLine" value="option1,
option2,
option3 />
It gets transformed to
<add key="MultiLine" value="
option1,
option2,
option3/>
How can I prevent that?
Thank you
Ryan

NHibernate "Repeated column in mapping for collection" exception

Consider the following NHibernate mapping, and notice the commented properties. These are the same columns as the key and index column specified in the map. When I remove the comments (thus including the TypeOfPart and UnitId columns for the properties) I get the "Repeated column in mapping for collection" exception.
<map name="Parts" table="ActiveUnitParts" lazy="false">
<key column="UnitId" />
<index column="TypeOfPart" type="integer"/>
<composite-element class="ActiveUnitPart">
<property name="Id" />
<property name="CreationDate" />
<property name="PartInfo"/>
<property name="Remarks"/>
<!-- <property name="TypeOfPart" /> -->
<!-- <property name="UnitId" /> -->
</composite-element>
</map>
What I need in code is a Dictinonary<TypeOfpart, ActiveUnitPart>. But the problem I have is that the values for the properties UnitId and TypeOfPart aren't set in the ActiveUnitPart instance in the Dictinonary<TypeOfpart, ActiveUnitPart>.
Yes, the list of related parts of this unit is loaded, and yes the key in the dictionary is related to the right part. But I do not understand why I can not reference the TypeOfPart and UnitId to fill the properties in ActiveUnitPart itself as well.
How can I solve or workaround this?
Motivation of why I need this:
I must be able to work with ActiveUnitParts without referencing the related Unit (UnitId)
EDIT 1:
I know I can intercept the setter of the Parts property of the Unit and iterate through the Dictinonary<TypeOfpart, ActiveUnitPart> to set the values in code, but it seems like a hack and I wish to learn a more elegant NHibernate way of getting it done, if possible.
It is possible, just change the mapping from column to formula. The best way how to achieve that would be:
<property name="TypeOfPart" formula="TypeOfPart" insert="false" update="false" />
<property name="UnitId" formula="UnitId" insert="false" update="false" />

How do I get autocompletion for Flex Metadata?

I took a look at flex metadata and it seems to be quiet straight forward. Though I have a problem, I don't get autocompletion for the metadata.
I'll tell you what I did, maybe you find an error. I want to create my own Style metadata tag named e.g. MyStyle. I want to create my own because it's easier for me to determine at runtime if the metadata was added by me or by the flex framework (therefore I will not use the predefined Style metadata tag).
To add metadata is pretty simple, I just wrote this code to get it work:
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="1024" height="768">
<fx:Metadata>
[MyStyle(required="true")]
</fx:Metadata>
</s:Group>
On my WindowedApplication component I added an added to stage listener to the stage. So all elements that are added to the application will fire that Event.ADDED when they are added to the stage. In that eventHandler I scan added elements for my metadata tag.
protected function addedToStageListener(event:Event):void
{
var classInfo:XML = describeType(event.target);
for each (var x:XML in classInfo..metadata)
{
if (x.#name == "MyStyle")
trace(x);
}
}
I also added a flex-config.xml file (in the toplevel of my src folder) to add the compiler options, so that I can read my custom metadata tag on runtime. The file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<flex-config>
<compiler>
<keep-as3-metadata>
<name>MyStyle</name>
</keep-as3-metadata>
</compiler>
</flex-config>
When I run this, I get the result I expect
<metadata name="MyStyle">
<arg key="required" value="true"/>
</metadata>
So this works. My next step was to add autocompletion when adding the metadata tag to the code. To do this you should create a metadata.xml which specifies the metadata tags right?
So I did this and I ended up with this simple metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<annotations version="2.1.1">
<metadata name="MyStyle" description="Adds style.">
<context name="class" />
<attribute name="required" type="Boolean" required="true" />
</metadata>
</annotations>
To add the metadata.xml correctly to the project I followed that tutorial by Adobe, but it doesn't work. I don't get autocompletion. Do you have any suggestions?
Update: I use Flash Builder 4.6 Professional and I created a Flex Library Project.