Skip to content

Conversation

@ZENEGIX
Copy link
Contributor

@ZENEGIX ZENEGIX commented Sep 3, 2018

I am change structure of property.
Now we can use a 4 default proeprty (common, array, list, map) and any type of property (string, integer, enum, bean, etc.)

For example, if we want to create string array property:

import static ch.jalu.configme.properties.PropertyBuilder.*;
import static ch.jalu.configme.properties.types.PropertyType.*;

public static final Property<String[]> STRING_ARRAY = arrayProperty(stringType())
    .path("string_array")
    .defaultValue("it is default text", "you can modify it c:")
    .build();

And use it:

String[] array = settingsManager.getProperty(STRING_ARRAY);

Or you want use map? It is simple c:

public static final Property<Map<String, TimeUnit>> TIMEUNIT_MAP = mapProperty(enumProperty(TimeUnit.class))
    .path("timeunit_map")
    .defaultEntry("seconds", TimeUnit.SECONDS)
    .defaultEntry("minutes", TimeUnit.MINUTES)
    .build();

[...]

Map<String, TimeUnit> map = settingsManager.getProperty(TIMEUNIT_MAP);

You can use any properties type. Or you can create a new property type ^-^
And I change a version to 3.0, because previous version was a 2.*. I think, it is continuation this project c:

UPD: Sorry me, I am did not write a JavaDoc, because my english is bad. I hope, you write JavaDoc yourself.

I am change structure of property.
Added PropertyType.
Now we can use a 4 default proeprty (common, array, list, map) and any type of property (string, integer, enum, bean, etc.)
And I change a version to 3.0, because previous version was a 2.*. I think, it is continuation this project c:
@ljacqu
Copy link
Member

ljacqu commented Sep 3, 2018

Wow, this is awesome! I want to look through it in detail tomorrow but it looks very promising and it's a nice concept.
Pertaining to the version, 1.0 is the current development version which hasn't been released yet (last release was 0.4.1) so I'd suggest to keep with the 1.0 version :)

@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 3, 2018

Oh, sorry, I didn't notice, that previous version was a 0.*

@coveralls
Copy link

coveralls commented Sep 4, 2018

Coverage Status

Coverage decreased (-6.05%) to 93.308% when pulling 48a7c85 on ZENEGIX:master into b22e6b0 on AuthMe:master.

Copy link
Member

@ljacqu ljacqu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review time :) Comments are throughout the code. Feel free to challenge anything you don't agree with.

Just again to say, in overall I love this and you've managed to introduce property types in a reusable way, which I love.

Scheduling -- you've changed the POM version to 1.1; I agree with this. I'd like to release 1.0 before these changes. I don't have any changes planned for 1.0 anymore, so probably I'll release 1.0 this weekend. Until then we can either merge to a separate branch if you'd like, or we just keep the PR open for another week.

Test coverage -- as the @coveralls bot commented the test coverage went down by almost 19%. Test coverage is really important for me as it protects us from regressions at a later date. For example during the refactoring of 1.0 the tests were immensely helpful.
The lack of test is not a blocker for merging. I'll also create some unit tests myself, once 1.0 is released.

Introduced types -- do you actually need arrays and floats? I don't mind their addition but why is it interesting to have array properties if you can have lists; same for float vs. double? (I commented this in the code but these are important questions to me.)

super(path, defaultValue);

if (type instanceof BeanPropertyType<?>) {
throw new IllegalArgumentException("BeanPropertyType not support for array property (maybe, temporarily)");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this out of intention (was there a problem?) or just a precaution? Is it because BeanPropertyType#convert is not supported?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Is it because BeanPropertyType#convert is not supported?" - Yes,I could not come up with the implementation of the conversion, and I hope this can be done by you

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, after I do the changes to Mapper we should be good to go :)


// If target type is String and object is string, then return splitted string.
if (this.type.getType() == String.class && object instanceof String) {
return (T[]) ((String) object).split("\\\\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this special case. Could we not have that as a separate property type if this is somehow a requirement? IMHO it would make more sense that the generic array property type behaves always the same way; that's also what I would expect as a user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not thought about it yet, but I think together we will be able to come up with the best option c:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully you are OK to remove the special case. As mentioned, if needed a separate property type could be added. :)

array[i] = this.type.toExportValue(value[i]);
}

return array;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory we could return a collection as export value and then the property resource doesn't have to be changed to support arrays. This keeps the contract of what is allowed as export values slim.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but I do not understand what you're talking about :c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in the method toExportValue and its return value is Object, but actually the PropertyResource expects that the return value be either a String, a Number, or lists/maps with those types. You had to extend the PropertyResource to also support arrays, because in this implementation toExportValue returns an array. You could have avoided this by returning a list from this method instead.
For me this is not an issue; it's just an observation. It's probably a nice addition that toExportValue can return arrays, also :) So this is really not a problem.


import javax.annotation.Nullable;

public class CommonProperty<T> extends BaseProperty<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why both CommonProperty and BaseProperty are necessary. Hopefully later on we can find names that are more different from each other (maybe something with "type" in this class' name). But that's for the future. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can rename CommonProperty to SignletonProperty, and BaseProperty to AbstractProperty, for example

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's think of names for a while before doing any renamings :)


// If raw list is null, then return default value
if (rawList == null) {
return this.getDefaultValue();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should return null if the value cannot be constructed from the reader.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excuse me. I will keep this in mind in the future

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return EnumPropertyType.of(type);
}

static FloatPropertyType floatType() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some issues with the visibility of members, like these being package-private here (wouldn't we want public?) but that's small stuff we can visit later on.


import ch.jalu.configme.resource.PropertyReader;

public class IntegerPropertyType implements PropertyType<Integer> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully in the future we can replace a lot of the existing property implementations with these property types. This doesn't have to be done in the scope of this PR but it would be a goal of 1.1.


import ch.jalu.configme.resource.PropertyReader;

public class FloatPropertyType implements PropertyType<Float> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need float, when we have double? Kind of sad to see property reader receive a new getFloat method (= more work a user needs to implement to create a new property reader)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, another users want to use float, why not?
I am not use it, but SneakyYML allows to do this
Maybe, we can make NumberPropertyType implements PropertyType<Number> for Double, Float, Short and Byte values

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me everything is OK 👍 . I just wanted to make sure float was introduced intentionally.


T convert(Object object);

Class<T> getType();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we dropped the array property type we'd be able to remove this method :P Or the array property type could require a Class object on it directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, getType() using is only in ArrayProperty

import java.util.Collection;
import java.util.List;

public class ArrayProperty<T> extends BaseProperty<T[]> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need an array type? When is it interesting to use this vs. a List<T> property?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am use array in next case:
player.sendMessage(settingsManager.getProperty(ARRAY_PROPERTY))
Player have a methods sendMessage(String message) and sendMessage(String[] message)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK for now :) I wanted to make sure that the array type is introduced for a reason; this is a good reason.


@Override
public B convert(Object object) {
throw new UnsupportedOperationException();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably change the mapper to expect an Object as argument and not know about the reader. This is a change I can still do in 1.0 so we avoid a breaking change in 1.1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do it yourself, because I am not read packet beanmapper

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll do it today~ ✨

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done on master with b22e6b0

@ljacqu ljacqu added this to the 1.1 Release milestone Sep 4, 2018
ljacqu added a commit that referenced this pull request Sep 4, 2018
- In preparation for generic property types in 1.1 (#66), change the Mapper to no longer be aware of the property resource, but to take an Object directly that it attempts to convert to a bean
- Remove path from root context in mappingContext: a root context now always has empty string as its path (i.e. paths are now relative to the mapping)
@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 5, 2018

Well, I took into account all your remarks and changed some points.
In general, it remains for us to resolve several issues in order to arrive at the best option. In particular, the clearer class names and the feasibility of some possibilities.

@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 5, 2018

And sorry me, sometimes I accidentally do things, for example, I place space in Mapper :c

@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 6, 2018

As you asked, I changed some points in the ArrayProperty.
Now when creating ArrayProperty, we can indicate ConvertHelper, which will convert the string into an array of objects, and will correctly store the data in a config.

Example of use PrimitiveConvertHelper.DEFAULT_STRING:

public static final Property<String[]> MESSAGE = PropertyBuilder.arrayProperty(PropertyType.stringType())
    .path("message")
    .convertHelper(PrimitiveConvertHelper.DEFAULT_STRING)
    .defaultValue("hello, my friend!", "it is example message")
    .build();

The following will be created in the config file::

message: |-
  hello, my friend!
  it is example message

However, we can also use these options:

message: hello, my friend\nit is example message
message:
- hello, my friend!
- it is example message

The same can be done with numbers:

numbers: 1, 2, 666
numbers:
- 1
- 2
- 666

@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 6, 2018

I also added support for relative property.

For example, we have a next config:

groups:
  player:
    prefix: '[player]'
  vip: 
    prefix: '[vip]'

Now, we can create a property with path 'prefix' and do this:

Property<String> PREFIX = [...]; //create the property with path 'prefix'

public String getPrefixForGroup(String group) {
  return settingsManager.getRelativeProperty("groups." + group, PREFIX);
}

However, when creating SettingsManager, we should not specify relative property, as standard values do not need to fit into our config.

@ZENEGIX
Copy link
Contributor Author

ZENEGIX commented Sep 6, 2018

Yay! +12% coverage!
UPD: +5%

@ljacqu
Copy link
Member

ljacqu commented Sep 8, 2018

This is great news! Thanks for everything. I'm going to merge to a 1.1 development branch now. A lot of new stuff has been added since — stuff we haven't discussed and stuff I'm not sure I'd want ConfigMe to include (replacements, relative properties).
It could be that I revert this on the 1.1 branch and if you need these features maybe it will be better if you have those changes locally in your application using ConfigMe, or keep your own kind of version. But this is all stuff for the future ;)

This weekend I will release 1.0 and then all the changes of the 1.1 branch will go into master and it will be the current development version. 😉

@ljacqu ljacqu changed the base branch from master to configme-1.1-dev September 8, 2018 07:40
@ljacqu ljacqu merged commit 779fa79 into AuthMe:configme-1.1-dev Sep 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants