Comments (17)
The intent, in your case, is that you want to keep the original file structure (comments and the order of the file properties), correct?
The library, can load properties from a single property file (the first available from a list of @Sources
) or load the properties from multiple @Sources
(then merge them in memory following the order), the property replacement shall be done in the same file from where it has been loaded - if the file is writable-, or the narrowest writeable one (and throw an exception if none is writeable?).
I find the RFE interesting; I need to think a little bit on how to implement this in the correct way.
from owner.
Exactly. Preserve original file structure but update the specified (or all) property values.
Your override capability is of interest to me too. That would allow PHP-like behavior where there is a base config file and then personal setting overrides. Perhaps it would make sense to have an annotation attribute to specify preferred write destination in the event of multiple sources?
I'm not in a hurry. Thanks for your consideration.
from owner.
I do agree that this would be a nice addition. I will focus on automatic properties reload first (I'll try to take example from commons-config), and a reload()
method that can be triggered manually as well if you modify the file by yourself. So, at first you can update the file as you are doing, then trigger the reload()
.
The update
mechanism may not be trivial due to the fact of the loading happens from multiple resources (which can be a file, but also an URL resource), in different ways (MERGE, FIRST), and (as soon as I can) will involve also different file formats.
The new annotation attribute to specify preferred write destination doesn't convince me.
I think that the preferred destination can be guessed by the framework itself:
- if the property is already available in one of the files (which is writable), that's where it should be overwritten, the narrowest should be preferred. But if the narrowest is not writable, the property will not take effect... (and should it throw an exception maybe)
- if the property is not available in any of the writable files specified in
@Sources
, then the narrowest writable one should apply. If no files are writable, then we have an exception.
But once determined the path to be updated, this can be delegated to a specific method like
public void update(URL target); // updates sounds better than save, since the 'smart' save is
// keeping what was there before; but if the file doesn't exists,
// then the file will be created.
That can be made public (and available earlier). This will read the file then do the smart update as you described.
I don't like very much to specify a java.io.File inside a method signature; I would prefer OutputStream or a Writer, but since the content must be read first then updated later... URL may be better? since also an FTP url can be updatable and a URL is more flexible to specify a generic source that can be read and eventually updated...
So, at the end the methods that could be added to the Config interface can be something like:
public interface UpdatableConfig extends Config {
void reload();
void setProperty(String key, String value);
void setProperties(Map<String, String> newProperties)
void update(); // will guess the resource where update
void update(URL target); // or string?
}
The update()
methods will also imply a reload()
.
Implementing UpdatableConfig will add the support for updating the properties in memory or on the specified @Sources
or to a specified target.
This is what it comes to my mind at the moment, but I'll think more about it.
I think the above methods could satisfy your RFE. You can do:
Map<String, String> updatedProps = ...
cfg.setProperties(updatedProps)
cfg.update(new URL("file:${baseFolder}/gitblit.properties"));
And this should make the changes on the file and reload the properties immediately.
It's not a single API call, but this allows people to change properties in memory without saving them to a file, that can also be desirable in some circumstances.
Since the setProperties
and the update()
are separated calls, I'll probably need to keep trac of which properties have been changed since last load (to update only those in the 'smart way'), also to minimize the lookup on the resources where things should be updated in several sources.
Comments and suggestions, are welcome.
from owner.
At first I didn't think that save(destination) would work for me, but that actually would be fine. I currently only call that in one place for the server.
You see that I too use the ${} notation in my properties. However, I don't resolve that against the properties file. I resolve those properties based on runtime parameters (e.g. baseFolder is a command-line parameter or it is set by the web.xml). Is there a way to disable OWNER's resolution of ${} properties?
from owner.
It's not possible to disable properties resolution, if a variable ${} is not set, an empty string is replaced. There is no way to avoid this.
But, you can pass an external context for your variables resolution (I called this "importing properties")
Example:
public interface MyConfig extends Config {
@DefaultValue("Hello ${world}.")
String foo();
}
@Test
public void testPropertyNotSet() {
MyConfig cfg = ConfigFactory.create(MyConfig.class);
assertEquals("Hello .", cfg.foo());
}
@Test
public void testPropertySet() {
Map<String, String> ctx = new HashMap<String, String>() {{
put("world", "Earth");
}};
MyConfig cfg = ConfigFactory.create(MyConfig.class, ctx); // here
assertEquals("Hello Earth.", cfg.foo());
}
The second parameter in ConfigFactory.create() is a vararg, so you can specify more than one map to resolve the properties. So, for example you can do ConfigFactory.create(MyConfig.class, ctx1, ctx2, System.getenv(), System.getProperties(), ...);
Hope this helps.
from owner.
Do you you resolve these properties at property retrieval or at source load?
from owner.
When ConfigFactory.create(class, map)
is invoked, all the values from map are copied inside an internal properties list.
So this won't work:
@Test
public void testPropertyChanged() {
Map<String, String> ctx = new HashMap<String, String>() {{
put("world", "Earth");
}};
MyConfig cfg = ConfigFactory.create(MyConfig.class, ctx);
ctx.put("world", "Mars");
assertEquals("Hello Mars.", cfg.foo());
}
// output
org.junit.ComparisonFailure:
Expected :Hello Mars.
Actual :Hello Earth.
The variables are substituted when the method foo()
is called (at retrieval), but the map specified on ConfigFactory.create(class, map)
are copied when the method is invoked.
from owner.
Actually, I wanted to know when a value of "${baseFolder}/data" is resolved? At getting that property or at loading/copying the map into OWNER?
from owner.
The value is substituted when you call the method to retrieve the property (when you do cfg.foo()
in the above examples).
See PropertiesInvokationHandler.resolveProperty()
, line 72
When you call MyConfig.foo() (that is actually a dynamic proxy), the PropertiesInvokationHandler.invoke()
is called, and this calls resolveProperty()
that calls substitutor.replace()
.
from owner.
James, I've not forgot these things. I've been busy these days with other issues but I count to get back on this asap. Thanks for the patience.
from owner.
No problem, it will be a while before I would be ready to integrate OWNER. No hurry, really.
from owner.
Hi James.
About this question:
Is there a way to disable OWNER's resolution of ${} properties?
I just committed a new annotation that allows to disable the ${} and the parameter formatters, as described in the issue #20 .
Documentation is updated and - as example - the junit test can be seen.
This annotation, when specified on class level is not inherited by subclasses by design.
This annotation will be available in version 1.0.4, and at the moment is available on the latest snapshot.
If you need this to be released into 1.0.4 final, I'll release it.
from owner.
I've implemented a Mutable
interface which allows to modify the config properties (above is described as UpdatableConfig
), the request related is the #31
And modifying the file from which the configuration was loaded, it's possible to programmatically invoke the method reload()
.
Now I want to make some progress in the automatic reload (changing the file on the disk, the configuration is reloaded automatically in the Config object)
The smart update of files as you indicated here is not available yet. And I feel I need to think more on how this should be designed in the API interfaces.
from owner.
Hi James.
I will release 1.0.4 soon, and it will include the hot reload feature, as well the @DisableFeatures
that allow you to disable variable expansion that was causing you some issues.
Regarding the smart properties save, I thought long time how this should be implemented, and - they way I feel it should be - is very complicated, as I described above.
I think it may be just simpler to include your method in a utility method that is implemeted as you already did, but I quite don't feel it fitting in the rest of the API.
Any suggestion?
from owner.
I am also interested in a smart save() method as described. You can see an implementation of such in Apache Commons Configuration using the PropertiesConfigurationLayout helper class:
Have you had additional thoughts since the original posts a year ago?
Thank you for your excellent work on OWNER.
from owner.
I didn't do any work on this, but after initial (complicated) idea I had, I thought I would do something like the implementation you pointed out from commons-configuration. Actually I was thinking to use some layout engine like velocity or freemarker (in a separate maven module).
Unfortunately lately I have been very busy and I am not dedicating much time to this project. And in the meantime I was focusing on other features.
I also think this would be a nice feature, and it's something that I would like to add.
Thanks.
L.
from owner.
Hi Luigi,
Thanks for the information and for your work on this project. The design of
OWNER web site is very creative, visually appealing and practical.
All the best,
Gary
On Tue, Mar 18, 2014 at 8:00 AM, Luigi R. Viggiano <[email protected]
wrote:
I didn't do any work on this, but after initial (complicated) idea I had,
I thought I would do something like the implementation you pointed out from
commons-configuration. Actually I was thinking to use some layout engine
like velocity or freemarker (in a separate maven module).Unfortunately lately I have been very busy and I am not dedicating much
time to this project. And in the meantime I was focusing on other features.I also think this would be a nice feature, and it's something that I would
like to add.Thanks.
L.
Reply to this email directly or view it on GitHubhttps://github.com//issues/16#issuecomment-37935253
.
from owner.
Related Issues (20)
- CVE-2020-8908 (Low) detected in guava-27.0.1-jre.jar
- CVE-2018-10237 (Medium) detected in guava-16.0.1.jar - autoclosed HOT 1
- CVE-2023-2976 (High) detected in guava-27.0.1-jre.jar
- CVE-2021-4104 (High) detected in log4j-1.2.17.jar
- CVE-2014-0193 (Medium) detected in netty-3.7.0.Final.jar - autoclosed HOT 1
- CVE-2023-26464 (High) detected in log4j-1.2.17.jar
- CVE-2018-8012 (High) detected in zookeeper-3.4.8.jar - autoclosed HOT 1
- CVE-2023-44981 (Critical) detected in zookeeper-3.5.7.jar
- CVE-2019-17571 (Critical) detected in log4j-1.2.17.jar
- CVE-2020-9493 (Critical) detected in log4j-1.2.17.jar
- CVE-2015-2156 (High) detected in netty-3.7.0.Final.jar - autoclosed HOT 1
- CVE-2022-24823 (Medium) detected in netty-common-4.1.45.Final.jar
- CVE-2023-34462 (Medium) detected in netty-handler-4.1.45.Final.jar
- CVE-2021-37136 (High) detected in netty-codec-4.1.45.Final.jar
- CVE-2021-37137 (High) detected in netty-codec-4.1.45.Final.jar
- CVE-2020-11612 (High) detected in netty-codec-4.1.45.Final.jar
- CVE-2021-21290 (Medium) detected in netty-handler-4.1.45.Final.jar
- WS-2020-0408 (High) detected in netty-handler-4.1.45.Final.jar
- Possibility to get only those properties that explicitly declared in MyProperties interface
- Property keys defined at methods overridden by sub-interface not mapped by PropertiesManager
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from owner.