I am having trouble understanding the Phing documentation regarding multiple conditions for a given <if> tag. It implies you cannot have multiple conditions unless you use the <and> tag, but there are no examples of how to use it. Consequently I nested two <if> tags, however I feel silly doing this when I know there is a better way. Does anyone know how I can use the <and> tag to accomplish the following:
<if><equals arg1="${deployment.host.type}" arg2="unrestricted" /><then>
<if><equals arg1="${db.adapter}" arg2="PDO_MYSQL"/><then>
<!-- Code Here -->
</then></if>
</then></if>
I find it very surprising that no one has had any experience with this. Phing is an implementation of the 'ANT' build tool in PHP instead of Java. It is very useful for PHP developers who feel a lack of a simple and powerful deployment tool. Java's ability to package self contained web projects into a single file or package multiple web project files into a yet bigger file is an amazing capability. ANT or Phing does not get PHP to that point, but its a definite step in the right direction and leaps and bounds easier to understand and use than GNU Make ever was or will be.
According to the Phing documentation:
The <or> element doesn't have any attributes and accepts an arbitrary number of conditions as nested elements. This condition is true if at least one of its contained conditions is, conditions will be evaluated in the order they have been specified in the build file.
It may sound confusing at first, especially with no handy examples available, but the keywords to note are, "accepts an arbitrary number of conditions as nested elements." If you try the following build snippet out, you should easily realize how to use <or> and <and> conditions:
<if>
<or>
<equals arg1="foo" arg2="bar" />
<equals arg1="baz" arg2="baz" />
</or>
<then>
<echo message="Foo equals bar, OR baz equals baz!" />
</then>
</if>
<if>
<or>
<equals arg1="foo" arg2="bar" />
<equals arg1="baz" arg2="bam" />
</or>
<then>
<echo message="Foo equals bar, OR baz equals baz!" />
</then>
<else>
<echo message="No match to OR found." />
</else>
</if>
<fail />
Related
While migrating from GWT 2.7.0 to 2.8.2 I came upon property:
<define-configuration-property name="CssResource.gssDefaultInUiBinder"
is-multi-valued="true" />
If this is left as it is, I get an error: The configuration property named CssResource.gssDefaultInUiBinder is already defined with a different 'is-multi-valued' setting.
Does that mean that I can't set attribute is-multi-valued to already defined property? Why would this work with GWT 2.7.0 then? Can anyone give me an explanation about this attribute? Because I am failing to find one...
Attribute set in GWT resources:
<!-- The default for GSS in UiBinder -->
<define-configuration-property name="CssResource.gssDefaultInUiBinder" is-multi-valued="false" />
gwt/user/src/com/google/gwt/resources/Resources.gwt.xml
Correct - you should not be trying to change is-multi-valued, it doesn't really make any sense. You can't re-define a property or configuration-property after it has been set, you can only set the value.
If you want to turn the gss-in-ui-binder flag on, use this:
<set-configuration-property name="CssResource.gssDefaultInUiBinder" value="true" />
If you want to turn it off, either do nothing, or do this:
<set-configuration-property name="CssResource.gssDefaultInUiBinder" value="false" />
If I put "<commentGenerator>" after "<jdbcConnection>", MBG proposed an error that context content should match: blablabla...
But when I put "<commentGenerator>" before "<jdbcConnection>", everything is ok. Here I have something to complain to the official website that if the order of these items is need, why you do not tell us! What an important thing! You r kidding the freshmen. Maybe it is some where I do not know, but this is a key point to build the MBG's configuration file successfully, why not put this NOTE on the top of the tutorial or somewhere eye-catching?
<generatorConfiguration >
<classPathEntry location="D:\mariadb-java-client-1.1.7.jar" />
<context id="db" >
<commentGenerator>
<property name="suppressAllComments" value="true" />
<property name="suppressDate" value="true" />
</commentGenerator>
<jdbcConnection driverClass="org.mariadb.jdbc.Driver"
connectionURL="jdbc:mariadb://localhost:3306/dbname"
userId="root"
password="password"
/>
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- Model Class -->
<javaModelGenerator targetPackage="org.infrastructure.model" targetProject="infrastructure\src\main\java">
<property name="enableSubPackages" value="false" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- XML Files -->
<sqlMapGenerator targetPackage="sqlMap" targetProject="infrastructure\src\main\config">
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- DAO -->
<javaClientGenerator type="XMLMAPPER" targetPackage="org.infrastructure.dao" targetProject="infrastructure\src\main\java">
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- Tables -->
<table tableName="user" domainObjectName="User" ></table>
</context>
</generatorConfiguration>
First of all, in your xml configuration file, it doesn't contains a valid root element, which always should be like <!DOCTYPE .../>. About how to add a correct root element of mybatis generator configuration file, please see example from MyBatis GeneratorXML Configuration File Reference.
If you correctly specified root element such as following:
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"
>
This root element contains a typical DTD declaration located at http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd. This is the definition of the order of these items is need. And we are going to see what it looks like.
From line 47 of this document type definition, it defines element named context. The content is as following:
<!--
The context element is used to describe a context for generating files, and the source tables.
-->
<!ELEMENT context (property*, plugin*, commentGenerator?, jdbcConnection, javaTypeResolver?,javaModelGenerator, sqlMapGenerator?, javaClientGenerator?, table+)>
Which obviously defined the order of the element in context, that is:
property*, plugin*, commentGenerator?, jdbcConnection,
javaTypeResolver?,javaModelGenerator, sqlMapGenerator?,
javaClientGenerator?, table+
In this element, all children must occurs as following rules:
+ for specifying that there must be one or more occurrences of the item — the effective content of each occurrence may be different;
* for specifying that any number (zero or more) of occurrences is allowed — the item is optional and the effective content of each occurrence may be different;
? for specifying that there must not be more than one occurrence — the item is optional;
If there is no quantifier, the specified item must occur exactly one time at the specified position in the content of the element.
After we understanding its real meaning, why you could not change the order of commentGenerator and jdbcConnection should be clear.
Maybe you want to know how to make the element out of order, question How to define DTD without strict element order could be useful.
Wish it helpful.
I've got a software that consists of different plugins that can be selected during installation in IzPack. These plugins provide different features to the software: input, processing, output. The software needs at least one input and output plugin to work.
How do I specify that at least one plugin providing a certain feature is selected in the PackPanel?
I believe that this was implemented in izpack v5.0.0-rc5 and newer. PacksPanel does not allow you to continue if you have deselected all the options.
Based on your comment I would solve this by using conditionvalidator:
Basically add condition for each of your packs:
<condition type="packselection" id="pack1inputselected">
<name>Pack 1 input</name>
</condition>
Then make OR conditions with groups of your packs (input, processing, output), e.g. like this:
<condition type="or" id="inputgroup">
<condition type="ref" refid="pack1inputselected" />
<condition type="ref" refid="pack2inputselected" />
</condition>
Then add a final AND validation condition (id is crucial as it has to always start by conditionvalidator word! The conditionvalidator class gets to validate all the conditions starting with conditionvalidator.):
<condition type="and" id="conditionvalidator.packsselected">
<condition type="ref" refid="inputgroup" />
<condition type="ref" refid="processinggroup" />
<condition type="ref" refid="outputgroup" />
</condition>
Add conditionvalidator to PacksPanel in panels element:
<panel classname="PacksPanel" id="panel.packs">
<validator classname="com.izforge.izpack.installer.validator.ConditionValidator" />
</panel>
There. Everytime the condition that is validated (when clicking on next) by conditionvalidator will not be true (that is if you will not have the correct packs selected), it will throw a message and will not allow you to continue. You can change the message by adding string to CustomLangPack with .error.message (e.g. in this example conditionvalidator.packsselected.error.message).
I have a web.config file in which I need to either insert the <configSections /> element or manipulate children of that node if it already exists.
If it already exists I don't want to insert it again (obviously, as it is only allowed to exist once).
Normally, that would not be a problem, however:
If this element is in a configuration file, it must be the first child element of the element.
Source: MSDN.
So if I use xdt:Transform="InsertIfMissing" the <configSections /> element will always be inserted after any existing child elements (and there are always some), violating the above restriction of it having to be the first child element of <configuration />
I attempted to make this work in the following way:
<configSections
xdt:Transform="InsertBefore(/configuration/*[1])"
xdt:Locator="Condition(not(.))" />
Which works perfect, if the <configSections /> element doesn't already exist. However, the condition I've specified seems to be ignored.
In fact, I've tried a few conditions like:
Condition(not(/configuration[configSections]))
Condition(/configuration[configSections] = false())
Condition(not(/configuration/configSections))
Condition(/configuration/configSections = false())
Finally, out of desperation, I tried:
Condition(true() = false())
It still inserted the <configSections /> element.
It is important to note that I'm trying to include this in a NuGet package, so I will be unable to use a custom transform (like the one AppHarbor uses).
Is there any other clever way to get my element in the right place only if it doesn't yet exist?
To test this out, use AppHarbors config transform tester. Replace the Web.config with the following:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="initialSection" />
</configSections>
</configuration>
And Web.Debug.config with the following:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<configSections
xdt:Transform="InsertBefore(/configuration/*[1])"
xdt:Locator="Condition(true() = false())" />
<configSections>
<section name="mySection" xdt:Transform="Insert" />
</configSections>
</configuration>
The result will show two <configSections /> elements, the one containing "mySection" being the first, as specified in the InsertBefore Transform.
Why was the Locator Condition not taken into account?
So after facing the same issue, I came up with a solution. It's not pretty nor elegant, but it works. (At least on my machine)
I just split the logic into 3 different statements. First, I add an empty configSections at the correct position (first). Then I insert the new config to the last configSections, which would be the new one if it is the only one, or a previously existing one otherwise.
Lastly I remove any empty configSections elemnt which might exist. I'm using RemoveAll for no good reason, you should probably use Remove.
The overall code looks like so:
<configSections xdt:Transform="InsertBefore(/configuration/*[1])" />
<configSections xdt:Locator="XPath(/configuration/configSections[last()])">
<section name="initialSection" xdt:Locator="Match(name)" xdt:Transform="InsertIfMissing" />
</configSections>
<configSections xdt:Transform="RemoveAll" xdt:Locator="Condition(count(*)=0)" />
The question which still remains unanswered is why Locator conditions are not taken into account for InsertBefore. Or why I can't handle an empty match set for InsertBefore, because that would allowed me to do fun things such as
//configuration/*[position()=1 and not(local-name()='configSections')]
Which to be honest is a much clearer way of doing what I want to achieve.
How can I check whether the selection variable value is null when I open the editor?
I want to activate a context menu command when the certain editor is opened, it is not dirty and nothing was selected by the user. First two coditions are working fine:
<and>
<with
variable="activePartId">
<equals
value="com.eclipse.someeditor">
</equals>
</with>
<with
variable="activePart">
<not>
<test
property="com.eclipse.isEditorDirty">
</test>
</not>
</with>
<and>
My current problem is that the straightforward solution would be to include another condition:
<with variable="selection">
<count value="0" />
</with>
Unfortunately when the editor is first opened, the count is not 0. It probably is null. If the user selects something and then deselects, it becomes 0. Any ideas how to check whether the value of selection is null or similar?
UPDATE
I also tried creating a property tester that checks whether the value of the selection is null, but the code is not executed. I think that it happens, because it does not even go inside the selection if the user did not select/deselect anything.
<with variable="selection">
<test
property="com.eclipse.isSelectionNullOrEmpty">
</test>
</with>
Try using 'instanceof' and 'and'. Like:
<and>
<instanceof value="fully_qualified_class_name_of_your_selection_class"/>
<equals value="0" />
</and>
Hope this helps.
The following solution worked:
I made the Editor a SelectionProvider that is capable of delegating to another SelectionProvider to be able to switch between them (e.g. when I have an inner table that provides selection as well and take procedence.
Then I set the getSelection() to return an empty StructuredSelection when there is no delegate (opposite to returning null). Thanks to that there is always a StructuredSelection being returned, but sometimes it is empty.
public ISelection getSelection() {
return delegate == null ? new StructuredSelection() : delegate.getSelection();
}
After that I could add the simple condition that I mentioned earlier:
<with variable="selection">
<count value="0" />
</with>
Some people may find this useful.