I have a desktop Java application that is packaged using jpackage (Java 14).
Windows Installer
I would like to know how to modify/override the jpackage wix defaults such that the installation location is captured in an environment variable.
I have tried adding an environment variable (to the default main.wxs created by jpackage) using the method described in the
WiX Cookbook: https://learning.oreilly.com/library/view/wix-cookbook/9781784393212/ch13s02.html
<Component Id="cmpEnvironmentVariable"
Guid="{313075B5-BF2C-4012-9A6E-2F4E2C461306}"
KeyPath="yes">
<Environment Id="myEnvironmentVariable"
Name="MyVariable"
Value="some value"
Action="set"
System="yes" />
</Component>
I also attempted to add an environment variable to the overrides.wxi file created by jpackage, I don't believe this was the correct thing to do.
Both of these attempts caused jpackage to fail.
I have also spent time looking through WIX documentation, but found it fairly impenetrable.
So any hints, suggestions, or examples would be greatly appreciated.
For reference: the default main.wxs created by jpackage:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?ifdef JpIsSystemWide ?>
<?define JpInstallScope="perMachine"?>
<?else?>
<?define JpInstallScope="perUser"?>
<?endif?>
<?define JpProductLanguage=1033 ?>
<?define JpInstallerVersion=200 ?>
<?define JpCompressedMsi=yes ?>
<?include $(var.JpConfigDir)/overrides.wxi ?>
<Product
Id="$(var.JpProductCode)"
Name="$(var.JpAppName)"
Language="$(var.JpProductLanguage)"
Version="$(var.JpAppVersion)"
Manufacturer="$(var.JpAppVendor)"
UpgradeCode="$(var.JpProductUpgradeCode)">
<Package
Description="$(var.JpAppDescription)"
Manufacturer="$(var.JpAppVendor)"
InstallerVersion="$(var.JpInstallerVersion)"
Compressed="$(var.JpCompressedMsi)"
InstallScope="$(var.JpInstallScope)" Platform="x64"
/>
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
<?ifdef JpAllowDowngrades ?>
<?ifdef JpAllowUpgrades ?>
<MajorUpgrade
AllowDowngrades="yes"
Disallow="no"
/>
<?endif?>
<?endif?>
<?ifdef JpAllowDowngrades ?>
<?ifndef JpAllowUpgrades ?>
<MajorUpgrade
AllowDowngrades="yes"
Disallow="yes"
DisallowUpgradeErrorMessage="!(loc.DisallowUpgradeErrorMessage)"
/>
<?endif?>
<?endif?>
<?ifndef JpAllowDowngrades ?>
<?ifdef JpAllowUpgrades ?>
<MajorUpgrade
AllowDowngrades="no"
Disallow="no"
DowngradeErrorMessage="!(loc.DowngradeErrorMessage)"
/>
<?endif?>
<?endif?>
<?ifndef JpAllowDowngrades ?>
<?ifndef JpAllowUpgrades ?>
<MajorUpgrade
AllowDowngrades="no"
Disallow="yes"
DowngradeErrorMessage="!(loc.DowngradeErrorMessage)"
DisallowUpgradeErrorMessage="!(loc.DisallowUpgradeErrorMessage)"
/>
<?endif?>
<?endif?>
<!-- Standard required root -->
<Directory Id="TARGETDIR" Name="SourceDir"/>
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
<ComponentGroupRef Id="Shortcuts"/>
<ComponentGroupRef Id="Files"/>
<ComponentGroupRef Id="FileAssociations"/>
</Feature>
<?ifdef JpInstallDirChooser ?>
<Binary Id="JpCaDll" SourceFile="wixhelper.dll"/>
<CustomAction Id="JpCheckInstallDir" BinaryKey="JpCaDll" DllEntry="CheckInstallDir" />
<?endif?>
<UI>
<?ifdef JpInstallDirChooser ?>
<Dialog Id="JpInvalidInstallDir" Width="300" Height="85" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="JpInvalidInstallDirYes" Type="PushButton" X="100" Y="55" Width="50" Height="15" Default="no" Cancel="no" Text="Yes">
<Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
</Control>
<Control Id="JpInvalidInstallDirNo" Type="PushButton" X="150" Y="55" Width="50" Height="15" Default="yes" Cancel="yes" Text="No">
<Publish Event="NewDialog" Value="InstallDirDlg">1</Publish>
</Control>
<Control Id="Text" Type="Text" X="25" Y="15" Width="250" Height="30" TabSkip="no">
<Text>!(loc.message.install.dir.exist)</Text>
</Control>
</Dialog>
<!--
Run WixUI_InstallDir dialog in the default install directory.
-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"/>
<UIRef Id="WixUI_InstallDir" />
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="JpCheckInstallDir" Order="3">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="JpInvalidInstallDir" Order="5">INSTALLDIR_VALID="0"</Publish>
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="5">INSTALLDIR_VALID="1"</Publish>
<?ifndef JpLicenseRtf ?>
<!--
No license file provided.
Override the dialog sequence in built-in dialog set "WixUI_InstallDir"
to exclude license dialog.
-->
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Order="2">1</Publish>
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">1</Publish>
<?endif?>
<?else?>
<?ifdef JpLicenseRtf ?>
<UIRef Id="WixUI_Minimal" />
<?endif?>
<?endif?>
</UI>
<?ifdef JpLicenseRtf ?>
<WixVariable Id="WixUILicenseRtf" Value="$(var.JpLicenseRtf)"/>
<?endif?>
</Product>
</Wix>
For reference: the default overrides.wxi created by jpackage:
<?xml version="1.0" encoding="utf-8"?>
<!-- Stub by design -->
<Include>
</Include>
I need to parse an xml file with the structure given below and store the data to mysql DB. But, I'm not sure from where to start, since this is a xml structure I never faced before.
Dozens of examples over the internet treats a structure where every attribute is bounded by its tag.
For instance, this is excellent starting point, but xml structure is way different than mine.
https://dzone.com/articles/load-xml-into-mysql-using-java
Any suggestion would be highly appreciated.
Thanks in advance.
<?xml version="1.0" encoding="utf-8"?>
<Models>
<Model id="1">
<Nodes>
<Node i="0" key="" name="Node 0" Vb_kV="225" gsh="0" bsh="0"/>
<Node i="1" key="" name="Node 1" Vb_kV="380" gsh="0" bsh="0"/>
<Node i="2" key="" name="Node 2" Vb_kV="225" gsh="0" bsh="0"/>
</Nodes>
<Loads>
<Load node="0" key="" name="" P0="0.058" P1="0"/>
<Load node="2" key="" name="" P0="1.425" P1="0"/>
<Load node="4" key="" name="" P0="0.328" P1="0"/>
</Loads>
<Generators>
<Generator pos="0" node="1246" key="" name="""/>
<Generator pos="1" node="1333" key="" name="""/>
<Generator pos="2" node="8700" key="" name=""/>
</Generators>
<Branches>
<Branch pos="0" nodeFrom="691" nodeTo="0" key="" name="" />
<Branch pos="1" nodeFrom="260" nodeTo="1" key="" name="" />
<Branch pos="2" nodeFrom="660" nodeTo="1" key="" name="" />
</Branches>
<Measurements>
<Node>
<Meas node="1" type="Z" val="0" w="1000"/>
<Meas node="3" type="Z" val="0" w="1000"/>
<Meas node="6" type="Z" val="0" w="1000"/>
<Meas node="7" type="Z" val="0" w="1000"/>
</Node>
<Branch>
<Meas branch="0" node="691"/>
<Meas branch="0" node="691"/>
<Meas branch="1" node="260"/>
</Branch>
</Measurements>
</Model>
</Models>
So I'm transitioning over from C# in Unity, where reflection in XML was quite easy. I wanted to apply the same process in Java to this to a slightly varied version of already existing XML of this type of format:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="0206.img">
<imgdir name="02060003">
<imgdir name="info">
<canvas name="icon" width="32" height="32">
<vector name="origin" x="0" y="32" />
</canvas>
<canvas name="iconRaw" width="32" height="31">
<vector name="origin" x="0" y="32" />
</canvas>
<int name="price" value="20" />
<int name="slotMax" value="1000" />
<int name="incPAD" value="4" />
</imgdir>
<imgdir name="bullet">
<canvas name="0" width="43" height="18">
<vector name="origin" x="23" y="10" />
<int name="z" value="0" />
</canvas>
<canvas name="1" width="41" height="9">
<vector name="origin" x="22" y="5" />
<int name="z" value="0" />
</canvas>
</imgdir>
</imgdir>
<imgdir name="02060005">
<imgdir name="info">
<canvas name="icon" width="26" height="25">
<vector name="origin" x="-3" y="25" />
<int name="z" value="0" />
</canvas>
<canvas name="iconRaw" width="20" height="18">
<vector name="origin" x="-6" y="25" />
<int name="z" value="0" />
</canvas>
<int name="slotMax" value="800" />
<int name="incPAD" value="10" />
<int name="reqLevel" value="10" />
<int name="tradeBlock" value="1" />
</imgdir>
<imgdir name="bullet">
<canvas name="0" width="36" height="19">
<vector name="origin" x="22" y="9" />
<int name="delay" value="150" />
</canvas>
<canvas name="1" width="40" height="22">
<vector name="origin" x="20" y="11" />
<int name="delay" value="150" />
</canvas>
<canvas name="2" width="43" height="21">
<vector name="origin" x="21" y="10" />
<int name="delay" value="150" />
</canvas>
<canvas name="3" width="46" height="23">
<vector name="origin" x="20" y="11" />
<int name="delay" value="150" />
</canvas>
</imgdir>
<imgdir name="hit">
<canvas name="0" width="55" height="38">
<vector name="origin" x="13" y="20" />
<int name="delay" value="90" />
</canvas>
<canvas name="1" width="43" height="55">
<vector name="origin" x="17" y="29" />
<int name="delay" value="100" />
</canvas>
<canvas name="2" width="51" height="65">
<vector name="origin" x="26" y="34" />
<int name="delay" value="100" />
</canvas>
<canvas name="3" width="62" height="87">
<vector name="origin" x="34" y="57" />
<int name="delay" value="100" />
</canvas>
</imgdir>
</imgdir>
The catch is that there are many of these XML files, and each one has different header names, such as 0206.img, 0207.img. Each one has a very similar structure to the previous one in that header category (leading digit determines what type of object it is unmarshaling).
I really only want to reflect properties such as price, slotMax, incPad, and ignore the rest if possible. I'm not sure how to go about this, since in all the unmarshal examples the XML is much simpler, such as
<Employees>
<Employee>
<id>1</id>
</Employee>
<Employee>
<id>2</id>
</Employee>
</Employees>
Where you'd probably define a class like Employees which contains List, and Employee can be unmarshalled into. To clarify, I know you have to set the RootElement to the name of the top element, such as in this case 0206.img, but how can this be dynamic for 0207?
As for code ... I mean the code base is pretty simple since it's just defining the structure for which to unmarshal into. Defining this structure in respect to the above XML I linked is harder for me atm.
If you're only interested in a few easy-to-detect elements, and not in the whole structure, JAXB may be a wrong tool. JAXB is good for the cases where you have an XML Schema, interested in (more or less) complete structure, unmarshalling as well as marshalling.
If you only need a few parts of XML there are easier ways to do this. In this particular case I would probably use STAX. Something along the lines:
private static final QName INT_ELEMENT_NAME = new QName("int");
// ...
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(is);
while (reader.hasNext()) {
if (XMLStreamConstants.START_ELEMENT == reader.next()) {
if (Objects.equals(INT_ELEMENT_NAME, reader.getName())) {
String name = reader.getAttributeValue(null, "name");
String value = reader.getAttributeValue(null, "value");
System.out.println(name + "=" + value);
}
}
}
Prints name/value paits from all the int elements. Can be easily extended to further cases. Very fast, does not have the JAXB overhead, would easily work with big XML files, no matter how huge.
There are other tools as well. There was one parser (I could not recall the name) where you define XPath-based rules and the parser returns data according to these rules. That would also be suitable, but I just don't recall the name. I think it was some Apache project.
Update: I've finally found it, I was talking about Digester. It allows configuring XPath-like binding rules and the creates objects for you. Still, I'd probably stay with the STAX solution unless you're sure you'll get more and more complex rules.
I used the IntelliJ GUI Designer to create a JPanel. It has three JButtons that are stacked vertically. When I run the code it has the three JButtons side by side, like it is using FlowLayout. FlowLayout is the default layout for a JPanel. I have tried setting the layout manager to various layouts in the GUI Designer and in the code. It always looks like the FlowLayout. How can I use a different layout with a JPanel? I would like to use the designer's GridLayoutManager.
Here is the java code:
public class myJPanelTest extends JPanel
{
private JButton button1;
private JButton button2;
private JButton button3;
public myJPanelTest()
{
setLayout(new GridBagLayout());
add(button1);
add(button2);
add(button3);
}
}
Here is the form:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="abc.dfg.tbs.CM.myJPanelTest">
<grid id="27dc6" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="c8918" class="javax.swing.JButton" binding="button1" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Button 1"/>
</properties>
</component>
<vspacer id="8e9eb">
<constraints>
<grid row="1" column="1" row-span="2" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="dff25" class="javax.swing.JButton" binding="button2" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Button 2"/>
</properties>
</component>
<component id="ac93b" class="javax.swing.JButton" binding="button3" default-binding="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Button 3"/>
</properties>
</component>
</children>
</grid>
</form>
How can I stop the layout from only using FlowLayout for a JPanel?
a simpliest situation: I have a drools flow.
Very simple,like
"<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
type="RuleFlow" name="ruleflow" id="com.sample.ruleflow" package-name="com.sample" >
<header>
</header>
<nodes>
<start id="1" name="Start" x="16" y="16" width="48" height="48" />
<actionNode id="2" name="Hello" x="96" y="16" width="80" height="48" >
<action type="expression" dialect="mvel" >System.out.println("Hello World");</action>
</actionNode>
<end id="3" name="End" x="208" y="16" width="48" height="48" />
</nodes>
<connections>
<connection from="1" to="2" />
<connection from="2" to="3" />
</connections>
</process>"
How can I change it programmatically , not with loading the flow file to XML Parsers etc, but to add the nodes and connection through the code?
Thanks in advance
I don't think any Drools API will be there for modifying the rules