Giter Site home page Giter Site logo

Comments (8)

mordechaim avatar mordechaim commented on May 18, 2024

from update4j.

painos avatar painos commented on May 18, 2024

I'm planning to use update4j as installer as well, so all business application files are downloaded in first run. My app has multiple files that users might make edits to, and usually I don't want them updated, but if the files are missing completely I want them downloaded. I think a flag "overwrite" that defaults true could be useful. I could of course make this in business app side by building the editable files from by making a copy on first run if they are missing, but it would be simpler and could be useful in other scenarios as well if it was included in update4j.

Example config:
<file path="/editable.grf" size="9702" checksum="dccc1abd" overwrite="false" signature="MD0CHEN67JCqupFBTKONYu7z9Zm6rWBEuQFVOCVZw5wCHQC1ODeHcj3ESpoVMPXMO9s1UuBONBNliOs4CzGq"/>

Thank you by the way for update4j, this makes my life so much easier. I was thinking of building an updater from scratch but update4j has basically everything and much more than I need for update part.

from update4j.

mordechaim avatar mordechaim commented on May 18, 2024

from update4j.

painos avatar painos commented on May 18, 2024

Let me clarify: You have a single global entry-point into your app, on initial run it actually does an installation but subsequent runs start the application.

Yes, subsequent runs start the application, or update and then start if updates are required.

I might be doing it all wrong, but so far on the client side I have completely separate update JAR I'm getting conf xml from URL input stream reader, doing Configuration.read, building a DSA public key object and generating a new custom UpdateHandler that is communicating with user update GUI.

Then if updates are required I pass public key and custom update handler to config.update and start business jar if everything goes smoothly.

from update4j.

mordechaim avatar mordechaim commented on May 18, 2024

So far you do it exactly as it should; namely, the updating logic should be kept in a separate jar.

Before I post an answer to your initial question, let me tell you about configurable fields, which might be vital for installers and will help you understand one of the solutions:

Say you want to install your app but first show a dialog and let the user choose an installation location. In update4j, this is the base path, but given the nature of the Configuration class as immutable it is impossible to modify the base path once the config is read.

There are 2 ways of doing this:

Refer the base path to a system property. Many config fields support property placeholders, which first lookup user listed properties then falls back to system properties and last to environment variables. The value is read when the config file is read. Say we have a config with the base path like:

<base path=${my.base.path}>

The code in the client-side updater:

String myBasePath = letUserChoosePath(); 
System.setProperty("my.base.path", myBasePath);

// Only *after* setting system property we can read
Configuration config = letsReadTheConfig();

The problem with this approach is you cannot set anything after being read; here's where the other approach comes in:

Create dynamic configuration. You can create dynamic configurations in code from scratch, or continue with an existing and modify fields via the ConfigMapper class and Configuration::parse method. Remember, the latter still won't modify the existing, it will create a new with the values of the existing preset.

Let's see how we can make a small modification. Say the base path was set to some default value and the user want's to change it:

Configuration config = letsReadTheConfig();
String myBasePath = letUserChoosePath();

ConfigMapper mapper = config.generateXmlMapper();
// we can use this instance to hand modify the xml
mapper.basePath = myBasePath;

// now create a new with the modified value
Config newConfig = Configuration.parse(mapper);

from update4j.

mordechaim avatar mordechaim commented on May 18, 2024

Now to answer your question:

Create dynamic configuration reading the file comments. The file element comes with a handy attribute called comment. You can put just anything there, it has no effect on the framework itself. This is very useful to add your own flags, as restart to restart the application if that given file was just updated now.

Let's use it to create your own dontOverwrite flag:

<file path="/editable.grf" size="9702" checksum="dccc1abd" comment="dontOverwrite" />

Now in your bootstrap app (what you call updater) we can dynamically create a new config with these files stripped if present on client machine:

Configuration config = letsReadTheConfig();
Configuration actualConfig = modifyConfig(config);

private Configuration modifyConfig(Configuration config) throws IOException {
    List<Integer> removeIndex = new ArrayList<>();

    // I can't use enhanced for-loop since I need the index
    for(int i = 0; i < config.getFiles().size(); i++)) {

        FileMetadata file = config.getFiles().get(i);
        if("dontOverwrite".equals(file.getComment()) && Files.exists(file.getPath())) {
            removeIndex.add(i);
        }
    }

    ConfigMapper mapper = config.generateXmlMapper();

    // go from reverse so indices don't get messed up
    for(int i = mapper.files.size() - 1; i >=0 ; i--) {
        if(removeIndex.contains(i)) {
            mapper.files.remove(i);
        }
    }

    return Configuration.parse(mapper);
}

This is a quite hacky solution, but is the closest I could get to your requirement. The other solutions are simpler but requires keeping track of 2 configs.

Use different configs for installation and update. Probably the best way here. Simply put, if your application knows whether it is installing or updating you can have the bootstrap read a complete different config for the different tasks. Simple, isn't it?

Installation config overwrites itself. A bit more complicated, but you only have one config at a time and is the only solution that work's with the default bootstrap. One of the file entries in the installer config is the config file itself. When the installation finishes you no longer need the original config so it will overwrite itself with the regular update config. This solution does not require you know if you are installing or updating, the config files do the magic themselves.

from update4j.

painos avatar painos commented on May 18, 2024

At the moment I'm leaning towards keeping it simple and keep track of installation status and use different config after installation.

I thank you for in-depth answer!

from update4j.

mordechaim avatar mordechaim commented on May 18, 2024

I'm planning to add a feature to allow the user to skip files from being updated. Re-opening this issue.

from update4j.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.