Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jackson Json dependency must not be in api #10384 #10935

Merged
merged 7 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

import com.enonic.xp.core.internal.json.ObjectMapperHelper;
import com.enonic.xp.event.Event;
import com.enonic.xp.json.ObjectMapperHelper;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import org.junit.jupiter.api.Test;

import com.enonic.xp.json.ObjectMapperHelper;
import com.enonic.xp.core.internal.json.ObjectMapperHelper;
import com.enonic.xp.server.VersionInfo;
import com.enonic.xp.web.WebResponse;

Expand Down
1 change: 1 addition & 0 deletions modules/app/app-system/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dependencies {
compileOnly project( ':core:core-api' )
compileOnly project( ':script:script-api' )
compileOnly project( ':core:core-internal' )

testImplementation project( ':tools:testing' )
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;

import com.enonic.xp.app.system.listener.VacuumListenerImpl;
import com.enonic.xp.json.ObjectMapperHelper;
import com.enonic.xp.core.internal.json.ObjectMapperHelper;
import com.enonic.xp.script.bean.BeanContext;
import com.enonic.xp.script.bean.ScriptBean;
import com.enonic.xp.task.ProgressReporter;
Expand Down
4 changes: 2 additions & 2 deletions modules/core/core-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ dependencies {
api ( libs.guava.guava ) {
exclude group: 'com.google.code.findbugs'
}
api libs.jackson.databind
api libs.osgi.core
api libs.jakarta.mail
api libs.metrics.core

// The following libraries are not really API. Remove in future versions of XP.
api libs.jackson.databind
api libs.slf4j.api
compileOnlyApi libs.osgi.service.componentannotations
api libs.osgi.service.component

implementation project( ':core:core-internal' )

implementation libs.jackson.datatype.jsr310
implementation libs.jparsec

testFixturesImplementation libs.junit.jupiter.api
testFixturesImplementation libs.mockito.core
testFixturesImplementation project( ':core:core-internal' )

testImplementation project( ':core:core-internal' )
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,15 @@
package com.enonic.xp.data;

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import com.enonic.xp.annotation.PublicApi;

@PublicApi
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PropertyArrayJson
public final class PropertyArrayJson
{
@JsonProperty("name")
private String name;

@JsonProperty("type")
private String type;

@JsonProperty("values")
private List<PropertyValueJson> values;

public PropertyArrayJson()
{
}

static PropertyArrayJson toJson( final PropertyArray propertyArray )
{
final PropertyArrayJson json = new PropertyArrayJson();
json.name = propertyArray.getName();
json.type = propertyArray.getValueType().getName();

json.values = new ArrayList<>( propertyArray.size() );
for ( final Property property : propertyArray.getProperties() )
{
json.values.add( new PropertyValueJson( property ) );
}

return json;
}

void fromJson( final PropertySet parent )
{
final ValueType valueType = ValueTypes.getByName( type );
final PropertyArray array = new PropertyArray( parent, name, valueType, values.size() );
public String name;

for ( final PropertyValueJson valueJson : values )
{
valueJson.fromJson( array, valueType );
}
public String type;

parent.addPropertyArray( array );
}
public List<PropertyValueJson> values;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -317,15 +318,15 @@ public Property setProperty( final PropertyPath path, final Value value )
/**
* WARNING: This method may be removed at any time. It is not recommended to use it in new code.
* This method is only used to simulate the behavior of PropertySet Serialisation.
* See {@link com.enonic.xp.data.PropertyArrayJson#fromJson}
* See {@link com.enonic.xp.data.PropertyTreeJson#fromJson}
* <br>
* <br>
* Ensures that the property with the given name has type of valueType given.
* If the property does not exist, empty property (without values) will be created.
* If the property with values exists and is not a type of valueType given, an exception will be thrown.
* Difference with setProperty is that this method does not set the property value.
*
* @param name property name
* @param name property name
* @param valueType expected value type
*/
public void ensureProperty( final String name, final ValueType valueType )
Expand Down Expand Up @@ -675,9 +676,7 @@ public Property[] addStrings( final String name, final String... values )

public Property[] addStrings( final String name, final Collection<String> values )
{
return values.stream().
map( ( value ) -> addProperty( name, ValueFactory.newString( value ) ) ).
toArray( Property[]::new );
return values.stream().map( ( value ) -> addProperty( name, ValueFactory.newString( value ) ) ).toArray( Property[]::new );
}

// setting xml
Expand Down Expand Up @@ -1436,4 +1435,60 @@ private String enumToString( final Enum e )
return e.toString();
}

static void translate( final Map<String, ?> json, final PropertySet into )
{
for ( Map.Entry<String, ?> field : json.entrySet() )
{
addValue( into, field.getKey(), field.getValue() );
}
}

private static void addValue( final PropertySet parent, final String key, final Object value )
{
if ( value instanceof Collection )
{
for ( final Object objNode : (Collection<?>) value )
{
addValue( parent, key, objNode );
}
}
else if ( value instanceof Map )
{
final PropertySet parentSet = parent.addSet( key );
for ( final Map.Entry<String, ?> next : ( (Map<String, ?>) value ).entrySet() )
{
addValue( parentSet, next.getKey(), next.getValue() );
}
}
else
{
parent.addProperty( key, resolveCoreValue( value ) );
}
}

private static Value resolveCoreValue( final Object value )
{
return switch ( value )
{
case String s -> ValueFactory.newString( s );
case Integer i -> ValueFactory.newLong( i.longValue() );
case Float v -> ValueFactory.newDouble( v.doubleValue() );
case Double v -> ValueFactory.newDouble( v );
case Boolean b -> ValueFactory.newBoolean( b );
case Long l -> ValueFactory.newLong( l );
case Byte b -> ValueFactory.newLong( b.longValue() );
case Short s -> ValueFactory.newLong( s.longValue() );
case Instant instant -> ValueFactory.newDateTime( instant );
case Date date -> ValueFactory.newDateTime( date.toInstant() );
case LocalTime localTime -> ValueFactory.newLocalTime( localTime );
case LocalDateTime localDateTime -> ValueFactory.newLocalDateTime( localDateTime );
case LocalDate localDate -> ValueFactory.newLocalDate( localDate );
case GeoPoint geoPoint -> ValueFactory.newGeoPoint( geoPoint );
case Reference reference -> ValueFactory.newReference( reference );
case BinaryReference binaryReference -> ValueFactory.newBinaryReference( binaryReference );
case Link link -> ValueFactory.newLink( link );
case null -> ValueFactory.newString( null );
default -> ValueFactory.newString( value.toString() );
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ public Map<String, Object> toMap()
return root.toMap();
}

public static PropertyTree fromMap( Map<String, ?> map )
{
final PropertyTree into = new PropertyTree();
PropertySet.translate( map, into.root );
return into;
}

@Override
public boolean equals( final Object o )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static PropertyTree fromJson( final List<PropertyArrayJson> list )
final PropertySet propertySet = tree.getRoot();
for ( PropertyArrayJson propertyArrayJson : list )
{
propertyArrayJson.fromJson( propertySet );
fromArrayJson( propertyArrayJson, propertySet );
}
return tree;
}
Expand All @@ -24,8 +24,87 @@ public static List<PropertyArrayJson> toJson( final PropertyTree propertyTree )
final List<PropertyArrayJson> list = new ArrayList<>();
for ( final PropertyArray propertyArray : propertyTree.getRoot().getPropertyArrays() )
{
list.add( PropertyArrayJson.toJson( propertyArray ) );
list.add( propertyArrayToJson( propertyArray ) );
}
return list;
}

private static void fromArrayJson( PropertyArrayJson from, final PropertySet parent )
{
final ValueType valueType = ValueTypes.getByName( from.type );
final PropertyArray array = new PropertyArray( parent, from.name, valueType, from.values.size() );

for ( final PropertyValueJson valueJson : from.values )
{
fromValueJson( valueJson, array, valueType );
}

parent.addPropertyArray( array );
}

private static void fromValueJson( PropertyValueJson valueJson, final PropertyArray into, final ValueType type )
{
final Value value;
if ( type.equals( ValueTypes.PROPERTY_SET ) )
{
if ( valueJson.set != null )
{
final PropertySet newSet = new PropertySet( into.getParent().getTree(), valueJson.set.size() );

for ( final PropertyArrayJson propertyArrayJson : valueJson.set )
{
fromArrayJson( propertyArrayJson, newSet );
}
value = ValueFactory.newPropertySet( newSet );
}
else
{
value = ValueFactory.newPropertySet( null );
}
}
else
{
value = type.fromJsonValue( valueJson.v );
}

into.addValue( value );
}

static PropertyArrayJson propertyArrayToJson( final PropertyArray propertyArray )
{
final PropertyArrayJson json = new PropertyArrayJson();
json.name = propertyArray.getName();
json.type = propertyArray.getValueType().getName();

json.values = new ArrayList<>( propertyArray.size() );
for ( final Property property : propertyArray.getProperties() )
{
json.values.add( propertyToJson( property ) );
}

return json;
}

private static PropertyValueJson propertyToJson( final Property property) {
final PropertyValueJson json = new PropertyValueJson();
if ( property.getType().equals( ValueTypes.PROPERTY_SET ) )
{
final PropertySet propertySet = property.getSet();
if ( propertySet != null )
{
final List<PropertyArrayJson> propertyArrayJsonList = new ArrayList<>();

for ( final PropertyArray propertyArray : propertySet.getPropertyArrays() )
{
propertyArrayJsonList.add( propertyArrayToJson( propertyArray ) );
}
json.set = propertyArrayJsonList;
}
}
else
{
json.v = property.getValue().toJsonValue();
}
return json;
}
}
Loading