Replace Properties with Map<String, String> in the v4 api (#808)

This commit is contained in:
Guillaume Nodet 2022-10-05 16:52:17 +02:00 committed by GitHub
parent 37b579b053
commit bff84bd634
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 342 additions and 170 deletions

View File

@ -26,7 +26,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.Properties;
import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.annotations.Nonnull;
@ -57,12 +56,11 @@ public interface Session
@Nonnull @Nonnull
SessionData getData(); SessionData getData();
// TODO: investigate using Map<String, String> or Map<String, Object> for all properties in the new API
@Nonnull @Nonnull
Properties getUserProperties(); Map<String, String> getUserProperties();
@Nonnull @Nonnull
Properties getSystemProperties(); Map<String, String> getSystemProperties();
/** /**
* Returns the current maven version * Returns the current maven version

View File

@ -51,6 +51,9 @@
#set ( $dummy = $imports.add( "java.util.Collection" ) ) #set ( $dummy = $imports.add( "java.util.Collection" ) )
#set ( $dummy = $imports.add( "java.util.List" ) ) #set ( $dummy = $imports.add( "java.util.List" ) )
#set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) ) #set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) )
#elseif ( $field.type == "java.util.Properties" )
#set ( $dummy = $imports.add( "java.util.Map" ) )
#set ( $dummy = $types.put( $field, "Map<String, String>" ) )
#elseif ( $field.type == "DOM" ) #elseif ( $field.type == "DOM" )
#set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) )
#set ( $dummy = $types.put( $field, "Dom" ) ) #set ( $dummy = $types.put( $field, "Dom" ) )

View File

@ -47,10 +47,13 @@
#set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) )
#foreach ( $field in $allFields ) #foreach ( $field in $allFields )
#if ( $field.type == "java.util.List" ) #if ( $field.type == "java.util.List" )
#set ( $dummy = $imports.add( "java.util.ArrayList" ) ) #set ( $dummy = $imports.add( "java.util.ArrayList" ) )
#set ( $dummy = $imports.add( "java.util.Collection" ) ) #set ( $dummy = $imports.add( "java.util.Collection" ) )
#set ( $dummy = $imports.add( "java.util.List" ) ) #set ( $dummy = $imports.add( "java.util.List" ) )
#set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) ) #set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) )
#elseif ( $field.type == "java.util.Properties" )
#set ( $dummy = $imports.add( "java.util.Map" ) )
#set ( $dummy = $types.put( $field, "Map<String, String>" ) )
#elseif ( $field.type == "DOM" ) #elseif ( $field.type == "DOM" )
#set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) )
#set ( $dummy = $types.put( $field, "Dom" ) ) #set ( $dummy = $types.put( $field, "Dom" ) )

View File

@ -47,10 +47,13 @@
#set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.annotations.ThreadSafe" ) )
#foreach ( $field in $allFields ) #foreach ( $field in $allFields )
#if ( $field.type == "java.util.List" ) #if ( $field.type == "java.util.List" )
#set ( $dummy = $imports.add( "java.util.ArrayList" ) ) #set ( $dummy = $imports.add( "java.util.ArrayList" ) )
#set ( $dummy = $imports.add( "java.util.Collection" ) ) #set ( $dummy = $imports.add( "java.util.Collection" ) )
#set ( $dummy = $imports.add( "java.util.List" ) ) #set ( $dummy = $imports.add( "java.util.List" ) )
#set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) ) #set ( $dummy = $types.put( $field, "List<" + $field.to + ">" ) )
#elseif ( $field.type == "java.util.Properties" )
#set ( $dummy = $imports.add( "java.util.Map" ) )
#set ( $dummy = $types.put( $field, "Map<String, String>" ) )
#elseif ( $field.type == "DOM" ) #elseif ( $field.type == "DOM" )
#set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) ) #set ( $dummy = $imports.add( "org.apache.maven.api.xml.Dom" ) )
#set ( $dummy = $types.put( $field, "Dom" ) ) #set ( $dummy = $types.put( $field, "Dom" ) )

View File

@ -28,7 +28,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Properties;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -180,16 +179,16 @@ public class DefaultSession extends AbstractSession
@Nonnull @Nonnull
@Override @Override
public Properties getUserProperties() public Map<String, String> getUserProperties()
{ {
return mavenSession.getUserProperties(); return new PropertiesAsMap( mavenSession.getUserProperties() );
} }
@Nonnull @Nonnull
@Override @Override
public Properties getSystemProperties() public Map<String, String> getSystemProperties()
{ {
return mavenSession.getSystemProperties(); return new PropertiesAsMap( mavenSession.getSystemProperties() );
} }
@Nonnull @Nonnull

View File

@ -0,0 +1,113 @@
package org.apache.maven.internal.impl;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
class PropertiesAsMap extends AbstractMap<String, String>
{
private final Map<Object, Object> properties;
PropertiesAsMap( Map<Object, Object> properties )
{
this.properties = properties;
}
@Override
public Set<Entry<String, String>> entrySet()
{
return new AbstractSet<Entry<String, String>>()
{
@Override
public Iterator<Entry<String, String>> iterator()
{
Iterator<Entry<Object, Object>> iterator = properties.entrySet().iterator();
return new Iterator<Entry<String, String>>()
{
Entry<Object, Object> next;
@Override
public boolean hasNext()
{
while ( next == null && iterator.hasNext() )
{
Entry<Object, Object> e = iterator.next();
if ( PropertiesAsMap.matches( e ) )
{
next = e;
break;
}
}
return next != null;
}
@Override
public Entry<String, String> next()
{
if ( next == null )
{
throw new NoSuchElementException();
}
return new Entry<String, String>()
{
@Override
public String getKey()
{
return (String) next.getKey();
}
@Override
public String getValue()
{
return (String) next.getValue();
}
@Override
public String setValue( String value )
{
return (String) next.setValue( value );
}
};
}
};
}
@Override
public int size()
{
return (int) properties.entrySet()
.stream().filter( PropertiesAsMap::matches )
.count();
}
};
}
private static boolean matches( Entry<Object, Object> entry )
{
return entry.getKey() instanceof String
&& entry.getValue() instanceof String;
}
}

View File

@ -45,7 +45,7 @@ import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
* <tr><td><code>session.*</code></td> <td>(since Maven 3)</td><td></td></tr> * <tr><td><code>session.*</code></td> <td>(since Maven 3)</td><td></td></tr>
* <tr><td><code>localRepository</code></td> <td></td> * <tr><td><code>localRepository</code></td> <td></td>
* <td>{@link Session#getLocalRepository()}</td></tr> * <td>{@link Session#getLocalRepository()}</td></tr>
* <tr><td><code>reactorProjects</code></td> <td></td> <td>{@link MavenSession#getProjects()}</td></tr> * <tr><td><code>reactorProjects</code></td> <td></td> <td>{@link Session#getProjects()}</td></tr>
* <tr><td><code>project</code></td> <td></td> * <tr><td><code>project</code></td> <td></td>
* <td>{@link Session#getCurrentProject()}</td></tr> * <td>{@link Session#getCurrentProject()}</td></tr>
* <tr><td><code>project.*</code></td> <td></td> <td></td></tr> * <tr><td><code>project.*</code></td> <td></td> <td></td></tr>
@ -402,7 +402,7 @@ public class PluginParameterExpressionEvaluatorV4
if ( ( value == null ) && ( ( project != null ) && ( project.getModel().getProperties() != null ) ) ) if ( ( value == null ) && ( ( project != null ) && ( project.getModel().getProperties() != null ) ) )
{ {
value = project.getModel().getProperties().getProperty( expression ); value = project.getModel().getProperties().get( expression );
} }
} }

View File

@ -117,7 +117,8 @@ public final class SettingsUtils
profile.activation( activation.build() ); profile.activation( activation.build() );
} }
profile.properties( modelProfile.getProperties() ); profile.properties( modelProfile.getProperties().entrySet().stream()
.collect( Collectors.toMap( e -> e.getKey().toString(), e -> e.getValue().toString() ) ) );
List<org.apache.maven.model.Repository> repos = modelProfile.getRepositories(); List<org.apache.maven.model.Repository> repos = modelProfile.getRepositories();
if ( repos != null ) if ( repos != null )

View File

@ -21,7 +21,9 @@ package org.apache.maven.settings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Random; import java.util.Random;
@ -87,11 +89,11 @@ public class SettingsUtilsTest
.property( ap ) .property( ap )
.os( ao ) .os( ao )
.build(); .build();
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
int count = entropy.nextInt( 10 ); int count = entropy.nextInt( 10 );
for ( int i = 0; i < count; i++ ) for ( int i = 0; i < count; i++ )
{ {
props.setProperty( "name" + Long.toHexString( entropy.nextLong() ), props.put( "name" + Long.toHexString( entropy.nextLong() ),
"value" + Long.toHexString( entropy.nextLong() ) ); "value" + Long.toHexString( entropy.nextLong() ) );
} }
count = entropy.nextInt( 3 ); count = entropy.nextInt( 3 );

View File

@ -24,7 +24,6 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -64,7 +63,7 @@ public class DefaultInheritanceAssembler
ModelProblemCollector problems ) ModelProblemCollector problems )
{ {
Map<Object, Object> hints = new HashMap<>(); Map<Object, Object> hints = new HashMap<>();
String childPath = child.getProperties().getProperty( CHILD_DIRECTORY_PROPERTY, child.getArtifactId() ); String childPath = child.getProperties().getOrDefault( CHILD_DIRECTORY_PROPERTY, child.getArtifactId() );
hints.put( CHILD_DIRECTORY, childPath ); hints.put( CHILD_DIRECTORY, childPath );
hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent, childPath ) ); hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent, childPath ) );
return merger.merge( child, parent, false, hints ); return merger.merge( child, parent, false, hints );
@ -210,7 +209,7 @@ public class DefaultInheritanceAssembler
ModelBase target, ModelBase source, boolean sourceDominant, ModelBase target, ModelBase source, boolean sourceDominant,
Map<Object, Object> context ) Map<Object, Object> context )
{ {
Properties merged = new Properties(); Map<String, String> merged = new HashMap<>();
if ( sourceDominant ) if ( sourceDominant )
{ {
merged.putAll( target.getProperties() ); merged.putAll( target.getProperties() );
@ -227,9 +226,9 @@ public class DefaultInheritanceAssembler
source.getLocation( "properties" ), sourceDominant ) ); source.getLocation( "properties" ), sourceDominant ) );
} }
private void putAll( Map<Object, Object> s, Map<Object, Object> t, Object excludeKey ) private void putAll( Map<String, String> s, Map<String, String> t, Object excludeKey )
{ {
for ( Map.Entry<Object, Object> e : t.entrySet() ) for ( Map.Entry<String, String> e : t.entrySet() )
{ {
if ( !e.getKey().equals( excludeKey ) ) if ( !e.getKey().equals( excludeKey ) )
{ {

View File

@ -25,7 +25,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
@ -96,7 +96,7 @@ public abstract class AbstractStringBasedModelInterpolator
protected List<ValueSource> createValueSources( final Model model, final File projectDir, protected List<ValueSource> createValueSources( final Model model, final File projectDir,
final ModelBuildingRequest config ) final ModelBuildingRequest config )
{ {
Properties modelProperties = model.getProperties(); Map<String, String> modelProperties = model.getProperties();
ValueSource projectPrefixValueSource = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false ); ValueSource projectPrefixValueSource = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false );

View File

@ -20,7 +20,7 @@ package org.apache.maven.model.interpolation;
*/ */
import java.util.Date; import java.util.Date;
import java.util.Properties; import java.util.Map;
import org.codehaus.plexus.interpolation.AbstractValueSource; import org.codehaus.plexus.interpolation.AbstractValueSource;
@ -29,7 +29,7 @@ class BuildTimestampValueSource
{ {
private final MavenBuildTimestamp mavenBuildTimestamp; private final MavenBuildTimestamp mavenBuildTimestamp;
BuildTimestampValueSource( Date startTime, Properties properties ) BuildTimestampValueSource( Date startTime, Map<String, String> properties )
{ {
super( false ); super( false );
this.mavenBuildTimestamp = new MavenBuildTimestamp( startTime, properties ); this.mavenBuildTimestamp = new MavenBuildTimestamp( startTime, properties );

View File

@ -22,7 +22,7 @@ package org.apache.maven.model.interpolation;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Properties; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
/** /**
@ -49,9 +49,9 @@ public class MavenBuildTimestamp
this( time, DEFAULT_BUILD_TIMESTAMP_FORMAT ); this( time, DEFAULT_BUILD_TIMESTAMP_FORMAT );
} }
public MavenBuildTimestamp( Date time, Properties properties ) public MavenBuildTimestamp( Date time, Map<String, String> properties )
{ {
this( time, properties != null ? properties.getProperty( BUILD_TIMESTAMP_FORMAT_PROPERTY ) : null ); this( time, properties != null ? properties.get( BUILD_TIMESTAMP_FORMAT_PROPERTY ) : null );
} }
public MavenBuildTimestamp( Date time, String timestampFormat ) public MavenBuildTimestamp( Date time, String timestampFormat )

View File

@ -25,8 +25,10 @@ import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.TimeZone; import java.util.TimeZone;
@ -177,7 +179,7 @@ public abstract class AbstractModelInterpolatorTest
public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression() throws Exception
{ {
Scm scm = Scm.newBuilder().connection( "${test}/somepath" ).build(); Scm scm = Scm.newBuilder().connection( "${test}/somepath" ).build();
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "test", "test" ); props.put( "test", "test" );
Model model = Model.newBuilder().scm( scm ).properties( props ).build(); Model model = Model.newBuilder().scm( scm ).properties( props ).build();
@ -316,8 +318,8 @@ public abstract class AbstractModelInterpolatorTest
Properties context = new Properties(); Properties context = new Properties();
context.put( "env.HOME", "/path/to/home" ); context.put( "env.HOME", "/path/to/home" );
Properties modelProperties = new Properties(); Map<String, String> modelProperties = new HashMap<>();
modelProperties.setProperty( "outputDirectory", "${env.HOME}" ); modelProperties.put( "outputDirectory", "${env.HOME}" );
Model model = Model.newBuilder().properties( modelProperties ).build(); Model model = Model.newBuilder().properties( modelProperties ).build();
@ -328,15 +330,15 @@ public abstract class AbstractModelInterpolatorTest
collector ); collector );
assertProblemFree( collector ); assertProblemFree( collector );
assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) ); assertEquals( "/path/to/home", out.getProperties().get( "outputDirectory" ) );
} }
@Test @Test
public void envarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception public void envarExpressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
{ {
Properties modelProperties = new Properties(); Map<String, String> modelProperties = new HashMap<>();
modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" ); modelProperties.put( "outputDirectory", "${env.DOES_NOT_EXIST}" );
Model model = Model.newBuilder().properties( modelProperties ).build(); Model model = Model.newBuilder().properties( modelProperties ).build();
@ -347,14 +349,14 @@ public abstract class AbstractModelInterpolatorTest
collector ); collector );
assertProblemFree( collector ); assertProblemFree( collector );
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" ); assertEquals( out.getProperties().get( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
} }
@Test @Test
public void expressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception public void expressionThatEvaluatesToNullReturnsTheLiteralString() throws Exception
{ {
Properties modelProperties = new Properties(); Map<String, String> modelProperties = new HashMap<>();
modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" ); modelProperties.put( "outputDirectory", "${DOES_NOT_EXIST}" );
Model model = Model.newBuilder().properties( modelProperties ).build(); Model model = Model.newBuilder().properties( modelProperties ).build();
@ -365,7 +367,7 @@ public abstract class AbstractModelInterpolatorTest
collector ); collector );
assertProblemFree( collector ); assertProblemFree( collector );
assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" ); assertEquals( out.getProperties().get( "outputDirectory" ), "${DOES_NOT_EXIST}" );
} }
@Test @Test
@ -420,9 +422,9 @@ public abstract class AbstractModelInterpolatorTest
@Test @Test
public void testRecursiveExpressionCycleNPE() throws Exception public void testRecursiveExpressionCycleNPE() throws Exception
{ {
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.setProperty( "aa", "${bb}" ); props.put( "aa", "${bb}" );
props.setProperty( "bb", "${aa}" ); props.put( "bb", "${aa}" );
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = Model.newBuilder().properties( props ).build(); Model model = Model.newBuilder().properties( props ).build();
@ -438,8 +440,8 @@ public abstract class AbstractModelInterpolatorTest
@Test @Test
public void testRecursiveExpressionCycleBaseDir() throws Exception public void testRecursiveExpressionCycleBaseDir() throws Exception
{ {
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.setProperty( "basedir", "${basedir}" ); props.put( "basedir", "${basedir}" );
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
Model model = Model.newBuilder().properties( props ).build(); Model model = Model.newBuilder().properties( props ).build();

View File

@ -20,6 +20,8 @@ package org.apache.maven.model.interpolation;
*/ */
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -31,8 +33,8 @@ public class MavenBuildTimestampTest
@Test @Test
public void testMavenBuildTimestampUsesUTC() public void testMavenBuildTimestampUsesUTC()
{ {
Properties interpolationProperties = new Properties(); Map<String, String> interpolationProperties = new HashMap<>();
interpolationProperties.setProperty( "maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'" ); interpolationProperties.put( "maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'" );
MavenBuildTimestamp timestamp = new MavenBuildTimestamp( new Date(), interpolationProperties ); MavenBuildTimestamp timestamp = new MavenBuildTimestamp( new Date(), interpolationProperties );
String formattedTimestamp = timestamp.formattedTimestamp(); String formattedTimestamp = timestamp.formattedTimestamp();
assertTrue( formattedTimestamp.endsWith( "Z" ), "We expect the UTC marker at the end of the timestamp." ); assertTrue( formattedTimestamp.endsWith( "Z" ), "We expect the UTC marker at the end of the timestamp." );

View File

@ -27,6 +27,7 @@ import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException; import java.util.InvalidPropertiesFormatException;
import java.util.Map; import java.util.Map;
@ -41,10 +42,10 @@ import java.util.function.Supplier;
class WrapperProperties extends Properties class WrapperProperties extends Properties
{ {
final Supplier<Properties> getter; final Supplier<Map<String, String>> getter;
final Consumer<Properties> setter; final Consumer<Properties> setter;
WrapperProperties( Supplier<Properties> getter, Consumer<Properties> setter ) WrapperProperties( Supplier<Map<String, String>> getter, Consumer<Properties> setter )
{ {
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
@ -53,25 +54,25 @@ class WrapperProperties extends Properties
@Override @Override
public String getProperty( String key ) public String getProperty( String key )
{ {
return getter.get().getProperty( key ); return getter.get().get( key );
} }
@Override @Override
public String getProperty( String key, String defaultValue ) public String getProperty( String key, String defaultValue )
{ {
return getter.get().getProperty( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue );
} }
@Override @Override
public Enumeration<?> propertyNames() public Enumeration<?> propertyNames()
{ {
return getter.get().propertyNames(); return Collections.enumeration( getter.get().keySet() );
} }
@Override @Override
public Set<String> stringPropertyNames() public Set<String> stringPropertyNames()
{ {
return getter.get().stringPropertyNames(); return getter.get().keySet();
} }
@Override @Override
@ -101,19 +102,19 @@ class WrapperProperties extends Properties
@Override @Override
public Enumeration<Object> keys() public Enumeration<Object> keys()
{ {
return getter.get().keys(); return Collections.enumeration( (Set) getter.get().keySet() );
} }
@Override @Override
public Enumeration<Object> elements() public Enumeration<Object> elements()
{ {
return getter.get().elements(); return Collections.enumeration( (Collection) getter.get().values() );
} }
@Override @Override
public boolean contains( Object value ) public boolean contains( Object value )
{ {
return getter.get().contains( value ); return getter.get().containsKey( value != null ? value.toString() : null );
} }
@Override @Override
@ -143,19 +144,19 @@ class WrapperProperties extends Properties
@Override @Override
public Set<Object> keySet() public Set<Object> keySet()
{ {
return getter.get().keySet(); return (Set) getter.get().keySet();
} }
@Override @Override
public Collection<Object> values() public Collection<Object> values()
{ {
return getter.get().values(); return (Collection) getter.get().values();
} }
@Override @Override
public Set<Map.Entry<Object, Object>> entrySet() public Set<Map.Entry<Object, Object>> entrySet()
{ {
return getter.get().entrySet(); return (Set) getter.get().entrySet();
} }
@Override @Override
@ -177,7 +178,7 @@ class WrapperProperties extends Properties
@Override @Override
public Object getOrDefault( Object key, Object defaultValue ) public Object getOrDefault( Object key, Object defaultValue )
{ {
return getter.get().getOrDefault( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue != null ? defaultValue.toString() : null );
} }
@Override @Override
@ -320,19 +321,25 @@ class WrapperProperties extends Properties
@Override @Override
public void save( OutputStream out, String comments ) public void save( OutputStream out, String comments )
{ {
getter.get().save( out, comments ); Properties props = new Properties();
props.putAll( getter.get() );
props.save( out, comments );
} }
@Override @Override
public void store( Writer writer, String comments ) throws IOException public void store( Writer writer, String comments ) throws IOException
{ {
getter.get().store( writer, comments ); Properties props = new Properties();
props.putAll( getter.get() );
props.store( writer, comments );
} }
@Override @Override
public void store( OutputStream out, String comments ) throws IOException public void store( OutputStream out, String comments ) throws IOException
{ {
getter.get().store( out, comments ); Properties props = new Properties();
props.putAll( getter.get() );
props.store( out, comments );
} }
@Override @Override
@ -344,13 +351,17 @@ class WrapperProperties extends Properties
@Override @Override
public void storeToXML( OutputStream os, String comment ) throws IOException public void storeToXML( OutputStream os, String comment ) throws IOException
{ {
getter.get().storeToXML( os, comment ); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment );
} }
@Override @Override
public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException
{ {
getter.get().storeToXML( os, comment, encoding ); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment, encoding );
} }
} }

View File

@ -122,10 +122,10 @@ public class ${className}
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) ); builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) );
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties src = source.get${capField}(); Map<String, String> src = source.get${capField}();
if ( !src.isEmpty() ) if ( !src.isEmpty() )
{ {
Properties tgt = target.get${capField}(); Map<String, String> tgt = target.get${capField}();
if ( tgt.isEmpty() ) if ( tgt.isEmpty() )
{ {
builder.${field.name}( src ); builder.${field.name}( src );
@ -135,7 +135,7 @@ public class ${className}
} }
else else
{ {
Properties merged = new Properties(); Map<String, String> merged = new HashMap<>();
merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() ); merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() );
merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() ); merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() );
builder.${field.name}( merged ); builder.${field.name}( merged );

View File

@ -197,6 +197,13 @@ public class ${class.name}
update( getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() ) ); update( getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() ) );
( ( Xpp3Dom ) ${field.name} ).setChildrenTracking( this::replace ); ( ( Xpp3Dom ) ${field.name} ).setChildrenTracking( this::replace );
} }
#elseif( $field.type == "java.util.Properties" )
Map<String, String> map = ${field.name}.entrySet().stream()
.collect( Collectors.toMap( e -> e.getKey().toString(), e -> e.getValue().toString() ) );
if ( !Objects.equals( map, getDelegate().get${cap}() ) )
{
update( getDelegate().with${cap}( map ) );
}
#else #else
if ( !Objects.equals( ${field.name}, getDelegate().${pfx}${cap}() ) ) if ( !Objects.equals( ${field.name}, getDelegate().${pfx}${cap}() ) )
{ {

View File

@ -43,7 +43,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.apache.maven.api.annotations.Generated; import org.apache.maven.api.annotations.Generated;
import org.apache.maven.internal.xml.DomBuilder; import org.apache.maven.internal.xml.DomBuilder;
@ -274,7 +273,7 @@ public class ${className}
${classLcapName}.${field.name}( ${field.name} ); ${classLcapName}.${field.name}( ${field.name} );
break; break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties ${field.name} = new Properties(); Map<String, String> ${field.name} = new HashMap<>();
locations = new HashMap<>(); locations = new HashMap<>();
while ( parser.nextTag() == XmlPullParser.START_TAG ) while ( parser.nextTag() == XmlPullParser.START_TAG )
{ {

View File

@ -39,9 +39,10 @@ import java.io.Reader;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.maven.api.annotations.Generated; import org.apache.maven.api.annotations.Generated;
import org.apache.maven.internal.xml.DomBuilder; import org.apache.maven.internal.xml.DomBuilder;
@ -296,7 +297,7 @@ public class ${className}
${classLcapName}.${field.name}( ${field.name} ); ${classLcapName}.${field.name}( ${field.name} );
break; break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties ${field.name} = new Properties(); Map<String, String> ${field.name} = new HashMap<>();
while ( parser.nextTag() == XmlPullParser.START_TAG ) while ( parser.nextTag() == XmlPullParser.START_TAG )
{ {
String key = parser.getName(); String key = parser.getName();

View File

@ -107,23 +107,20 @@ public class ${className}
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
builder.${field.name}( transform( target.get${capField}(), this::transform ) ); builder.${field.name}( transform( target.get${capField}(), this::transform ) );
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties props = target.get${capField}(); Map<String, String> props = target.get${capField}();
Properties newProps = null; Map<String, String> newProps = null;
for ( Map.Entry<Object, Object> entry : props.entrySet() ) for ( Map.Entry<String, String> entry : props.entrySet() )
{ {
if ( entry.getKey() instanceof String && entry.getValue() instanceof String ) String newVal = transform( entry.getValue() );
if ( newVal != null && newVal != entry.getValue() )
{ {
String newVal = transform( ( String ) entry.getValue() ); if ( newProps == null )
if ( newVal != null && newVal != entry.getValue() )
{ {
if ( newProps == null ) newProps = new HashMap<>();
{ newProps.putAll( props );
newProps = new Properties(); builder.${field.name}( newProps );
newProps.putAll( props );
builder.${field.name}( newProps );
}
newProps.put( ( String ) entry.getKey(), newVal );
} }
newProps.put( entry.getKey(), newVal );
} }
} }
#elseif ( $field.to && $field.multiplicity == "1" ) #elseif ( $field.to && $field.multiplicity == "1" )

View File

@ -298,17 +298,17 @@ public class ${className}
} }
} }
private <T> void writeProperties( String tagName, Properties props, XmlSerializer serializer, InputLocationTracker locationTracker ) private <T> void writeProperties( String tagName, Map<String, String> props, XmlSerializer serializer, InputLocationTracker locationTracker )
throws IOException throws IOException
{ {
if ( props != null && !props.isEmpty() ) if ( props != null && !props.isEmpty() )
{ {
serializer.startTag( NAMESPACE, tagName ); serializer.startTag( NAMESPACE, tagName );
InputLocation location = locationTracker != null ? locationTracker.getLocation( tagName ) : null; InputLocation location = locationTracker != null ? locationTracker.getLocation( tagName ) : null;
for ( Map.Entry<Object, Object> entry : props.entrySet() ) for ( Map.Entry<String, String> entry : props.entrySet() )
{ {
String key = entry.getKey().toString(); String key = entry.getKey();
writeTag( key, null, entry.getValue().toString(), serializer, null ); writeTag( key, null, entry.getValue(), serializer, null );
writeLocationTracking( location, key, serializer ); writeLocationTracking( location, key, serializer );
} }
serializer.endTag( NAMESPACE, tagName ); serializer.endTag( NAMESPACE, tagName );

View File

@ -273,15 +273,15 @@ public class ${className}
} }
} }
private <T> void writeProperties( String tagName, Properties props, XmlSerializer serializer ) private <T> void writeProperties( String tagName, Map<String, String> props, XmlSerializer serializer )
throws IOException throws IOException
{ {
if ( props != null && !props.isEmpty() ) if ( props != null && !props.isEmpty() )
{ {
serializer.startTag( NAMESPACE, tagName ); serializer.startTag( NAMESPACE, tagName );
for ( Map.Entry<Object, Object> entry : props.entrySet() ) for ( Map.Entry<String, String> entry : props.entrySet() )
{ {
writeTag( entry.getKey().toString(), null, entry.getValue().toString(), serializer ); writeTag( entry.getKey(), null, entry.getValue(), serializer );
} }
serializer.endTag( NAMESPACE, tagName ); serializer.endTag( NAMESPACE, tagName );
} }

View File

@ -27,6 +27,7 @@ import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException; import java.util.InvalidPropertiesFormatException;
import java.util.Map; import java.util.Map;
@ -38,13 +39,13 @@ import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class WrapperProperties extends Properties class WrapperProperties extends Properties
{ {
final Supplier<Properties> getter; final Supplier<Map<String, String>> getter;
final Consumer<Properties> setter; final Consumer<Properties> setter;
public WrapperProperties( Supplier<Properties> getter, Consumer<Properties> setter ) WrapperProperties( Supplier<Map<String, String>> getter, Consumer<Properties> setter )
{ {
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
@ -53,25 +54,25 @@ public class WrapperProperties extends Properties
@Override @Override
public String getProperty( String key ) public String getProperty( String key )
{ {
return getter.get().getProperty( key ); return getter.get().get( key );
} }
@Override @Override
public String getProperty( String key, String defaultValue ) public String getProperty( String key, String defaultValue )
{ {
return getter.get().getProperty( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue );
} }
@Override @Override
public Enumeration<?> propertyNames() public Enumeration<?> propertyNames()
{ {
return getter.get().propertyNames(); return Collections.enumeration( getter.get().keySet() );
} }
@Override @Override
public Set<String> stringPropertyNames() public Set<String> stringPropertyNames()
{ {
return getter.get().stringPropertyNames(); return getter.get().keySet();
} }
@Override @Override
@ -101,19 +102,19 @@ public class WrapperProperties extends Properties
@Override @Override
public Enumeration<Object> keys() public Enumeration<Object> keys()
{ {
return getter.get().keys(); return Collections.enumeration( (Set) getter.get().keySet() );
} }
@Override @Override
public Enumeration<Object> elements() public Enumeration<Object> elements()
{ {
return getter.get().elements(); return Collections.enumeration( (Collection) getter.get().values() );
} }
@Override @Override
public boolean contains( Object value ) public boolean contains( Object value )
{ {
return getter.get().contains( value ); return getter.get().containsKey( value != null ? value.toString() : null );
} }
@Override @Override
@ -143,19 +144,19 @@ public class WrapperProperties extends Properties
@Override @Override
public Set<Object> keySet() public Set<Object> keySet()
{ {
return getter.get().keySet(); return (Set) getter.get().keySet();
} }
@Override @Override
public Collection<Object> values() public Collection<Object> values()
{ {
return getter.get().values(); return (Collection) getter.get().values();
} }
@Override @Override
public Set<Map.Entry<Object, Object>> entrySet() public Set<Map.Entry<Object, Object>> entrySet()
{ {
return getter.get().entrySet(); return (Set) getter.get().entrySet();
} }
@Override @Override
@ -177,7 +178,7 @@ public class WrapperProperties extends Properties
@Override @Override
public Object getOrDefault( Object key, Object defaultValue ) public Object getOrDefault( Object key, Object defaultValue )
{ {
return getter.get().getOrDefault( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue != null ? defaultValue.toString() : null );
} }
@Override @Override
@ -320,19 +321,25 @@ public class WrapperProperties extends Properties
@Override @Override
public void save( OutputStream out, String comments ) public void save( OutputStream out, String comments )
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.save( out, comments );
} }
@Override @Override
public void store( Writer writer, String comments ) throws IOException public void store( Writer writer, String comments ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.store( writer, comments );
} }
@Override @Override
public void store( OutputStream out, String comments ) throws IOException public void store( OutputStream out, String comments ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.store( out, comments );
} }
@Override @Override
@ -344,13 +351,17 @@ public class WrapperProperties extends Properties
@Override @Override
public void storeToXML( OutputStream os, String comment ) throws IOException public void storeToXML( OutputStream os, String comment ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment );
} }
@Override @Override
public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment, encoding );
} }
} }

View File

@ -38,7 +38,6 @@ import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Objects; import java.util.Objects;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.function.Function; import java.util.function.Function;
@ -122,10 +121,10 @@ public class ${className}
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) ); builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) );
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties src = source.get${capField}(); Map<String, String> src = source.get${capField}();
if ( !src.isEmpty() ) if ( !src.isEmpty() )
{ {
Properties tgt = target.get${capField}(); Map<String, String> tgt = target.get${capField}();
if ( tgt.isEmpty() ) if ( tgt.isEmpty() )
{ {
builder.${field.name}( src ); builder.${field.name}( src );
@ -135,7 +134,7 @@ public class ${className}
} }
else else
{ {
Properties merged = new Properties(); Map<String, String> merged = new HashMap<>();
merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() ); merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() );
merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() ); merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() );
builder.${field.name}( merged ); builder.${field.name}( merged );

View File

@ -195,13 +195,17 @@ public class ${class.name}
public void set${cap}( ${type} ${field.name} ) public void set${cap}( ${type} ${field.name} )
{ {
#if ( $field.to != "String" && $field.type == "java.util.List" && $field.multiplicity == "*" ) #if ( $field.type == "DOM" )
delegate = getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() );
#elseif( $field.type == "java.util.Properties" )
Map<String, String> map = ${field.name}.entrySet().stream()
.collect( Collectors.toMap( e -> e.getKey().toString(), e -> e.getValue().toString() ) );
delegate = getDelegate().with${cap}( map );
#elseif ( $field.to != "String" && $field.type == "java.util.List" && $field.multiplicity == "*" )
delegate = getDelegate().with${cap}( delegate = getDelegate().with${cap}(
${field.name}.stream().map( c -> c.getDelegate() ).collect( Collectors.toList() ) ); ${field.name}.stream().map( c -> c.getDelegate() ).collect( Collectors.toList() ) );
#elseif ( $field.to && $field.to != "String" ) #elseif ( $field.to && $field.to != "String" )
delegate = getDelegate().with${cap}( ${field.name}.getDelegate() ); delegate = getDelegate().with${cap}( ${field.name}.getDelegate() );
#elseif ( $field.type == "DOM" )
delegate = getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() );
#else #else
delegate = getDelegate().with${cap}( ${field.name} ); delegate = getDelegate().with${cap}( ${field.name} );
#end #end

View File

@ -39,8 +39,10 @@ import java.io.Reader;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.apache.maven.api.annotations.Generated; import org.apache.maven.api.annotations.Generated;
@ -769,7 +771,7 @@ public class ${className}
${classLcapName}.${field.name}( ${field.name} ); ${classLcapName}.${field.name}( ${field.name} );
break; break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties ${field.name} = new Properties(); Map<String, String> ${field.name} = new HashMap<>();
while ( parser.nextTag() == XmlPullParser.START_TAG ) while ( parser.nextTag() == XmlPullParser.START_TAG )
{ {
String key = parser.getName(); String key = parser.getName();

View File

@ -273,15 +273,15 @@ public class ${className}
} }
} }
private <T> void writeProperties( String tagName, Properties props, XmlSerializer serializer ) private <T> void writeProperties( String tagName, Map<String, String> props, XmlSerializer serializer )
throws IOException throws IOException
{ {
if ( props != null && !props.isEmpty() ) if ( props != null && !props.isEmpty() )
{ {
serializer.startTag( NAMESPACE, tagName ); serializer.startTag( NAMESPACE, tagName );
for ( Map.Entry<Object, Object> entry : props.entrySet() ) for ( Map.Entry<String, String> entry : props.entrySet() )
{ {
writeTag( entry.getKey().toString(), null, entry.getValue().toString(), serializer ); writeTag( entry.getKey(), null, entry.getValue(), serializer );
} }
serializer.endTag( NAMESPACE, tagName ); serializer.endTag( NAMESPACE, tagName );
} }

View File

@ -89,7 +89,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource( new StringSource( "" ) ); request.setUserToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "user_value" ); props.put( "key", "user_value" );
ToolchainModel toolchain = ToolchainModel.newBuilder() ToolchainModel toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -104,7 +104,7 @@ public class DefaultToolchainsBuilderTest
assertNotNull( result.getEffectiveToolchains() ); assertNotNull( result.getEffectiveToolchains() );
assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() ); assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() );
assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() ); assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
assertEquals( 0, result.getProblems().size() ); assertEquals( 0, result.getProblems().size() );
} }
@ -116,7 +116,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setGlobalToolchainsSource( new StringSource( "" ) ); request.setGlobalToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "global_value" ); props.put( "key", "global_value" );
ToolchainModel toolchain = ToolchainModel.newBuilder() ToolchainModel toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -131,7 +131,7 @@ public class DefaultToolchainsBuilderTest
assertNotNull( result.getEffectiveToolchains() ); assertNotNull( result.getEffectiveToolchains() );
assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() ); assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() );
assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() ); assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
assertEquals( 0, result.getProblems().size() ); assertEquals( 0, result.getProblems().size() );
} }
@ -144,7 +144,7 @@ public class DefaultToolchainsBuilderTest
request.setGlobalToolchainsSource( new StringSource( "" ) ); request.setGlobalToolchainsSource( new StringSource( "" ) );
request.setUserToolchainsSource( new StringSource( "" ) ); request.setUserToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "user_value" ); props.put( "key", "user_value" );
ToolchainModel toolchain = ToolchainModel.newBuilder() ToolchainModel toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -154,7 +154,7 @@ public class DefaultToolchainsBuilderTest
.toolchains( Collections.singletonList( toolchain ) ) .toolchains( Collections.singletonList( toolchain ) )
.build(); .build();
props = new Properties(); props = new HashMap<>();
props.put( "key", "global_value" ); props.put( "key", "global_value" );
toolchain = ToolchainModel.newBuilder() toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -170,9 +170,9 @@ public class DefaultToolchainsBuilderTest
assertNotNull( result.getEffectiveToolchains() ); assertNotNull( result.getEffectiveToolchains() );
assertEquals( 2, result.getEffectiveToolchains().getToolchains().size() ); assertEquals( 2, result.getEffectiveToolchains().getToolchains().size() );
assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() ); assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(1).getType() ); assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(1).getType() );
assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(1).getProvides().getProperty( "key" ) ); assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(1).getProvides().get( "key" ) );
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
assertEquals( 0, result.getProblems().size() ); assertEquals( 0, result.getProblems().size() );
} }
@ -222,7 +222,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource( new StringSource( "" ) ); request.setUserToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "${env.testKey}" ); props.put( "key", "${env.testKey}" );
Xpp3Dom configurationChild = new Xpp3Dom("jdkHome", "${env.testKey}", null, null, null); Xpp3Dom configurationChild = new Xpp3Dom("jdkHome", "${env.testKey}", null, null, null);
Xpp3Dom configuration = new Xpp3Dom("configuration", null, null, Collections.singletonList(configurationChild), null); Xpp3Dom configuration = new Xpp3Dom("configuration", null, null, Collections.singletonList(configurationChild), null);
@ -239,7 +239,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingResult result = toolchainBuilder.build( request ); ToolchainsBuildingResult result = toolchainBuilder.build( request );
String interpolatedValue = "testValue"; String interpolatedValue = "testValue";
assertEquals(interpolatedValue, result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals(interpolatedValue, result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
Xpp3Dom toolchainConfiguration = (Xpp3Dom) result.getEffectiveToolchains().getToolchains().get(0).getConfiguration(); Xpp3Dom toolchainConfiguration = (Xpp3Dom) result.getEffectiveToolchains().getToolchains().get(0).getConfiguration();
assertEquals(interpolatedValue, toolchainConfiguration.getChild("jdkHome").getValue()); assertEquals(interpolatedValue, toolchainConfiguration.getChild("jdkHome").getValue());
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
@ -253,7 +253,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource( new StringSource( "" ) ); request.setUserToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "${env.testNonExistingKey}" ); props.put( "key", "${env.testNonExistingKey}" );
ToolchainModel toolchain = ToolchainModel.newBuilder() ToolchainModel toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -266,7 +266,7 @@ public class DefaultToolchainsBuilderTest
doReturn(persistedToolchains).when( toolchainsReader ).read( any( InputStream.class ), ArgumentMatchers.<String, Object>anyMap()); doReturn(persistedToolchains).when( toolchainsReader ).read( any( InputStream.class ), ArgumentMatchers.<String, Object>anyMap());
ToolchainsBuildingResult result = toolchainBuilder.build( request ); ToolchainsBuildingResult result = toolchainBuilder.build( request );
assertEquals("${env.testNonExistingKey}", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals("${env.testNonExistingKey}", result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
assertEquals( 0, result.getProblems().size() ); assertEquals( 0, result.getProblems().size() );
} }
@ -278,7 +278,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest(); ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource( new StringSource( "" ) ); request.setUserToolchainsSource( new StringSource( "" ) );
Properties props = new Properties(); Map<String, String> props = new HashMap<>();
props.put( "key", "${env.testSpecialCharactersKey}" ); props.put( "key", "${env.testSpecialCharactersKey}" );
ToolchainModel toolchain = ToolchainModel.newBuilder() ToolchainModel toolchain = ToolchainModel.newBuilder()
.type( "TYPE" ) .type( "TYPE" )
@ -292,7 +292,7 @@ public class DefaultToolchainsBuilderTest
ToolchainsBuildingResult result = toolchainBuilder.build( request ); ToolchainsBuildingResult result = toolchainBuilder.build( request );
String interpolatedValue = "<test&Value>"; String interpolatedValue = "<test&Value>";
assertEquals(interpolatedValue, result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) ); assertEquals(interpolatedValue, result.getEffectiveToolchains().getToolchains().get(0).getProvides().get( "key" ) );
assertNotNull( result.getProblems() ); assertNotNull( result.getProblems() );
assertEquals( 0, result.getProblems().size() ); assertEquals( 0, result.getProblems().size() );
} }

View File

@ -27,6 +27,7 @@ import java.io.PrintWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException; import java.util.InvalidPropertiesFormatException;
import java.util.Map; import java.util.Map;
@ -38,13 +39,13 @@ import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public class WrapperProperties extends Properties class WrapperProperties extends Properties
{ {
final Supplier<Properties> getter; final Supplier<Map<String, String>> getter;
final Consumer<Properties> setter; final Consumer<Properties> setter;
public WrapperProperties( Supplier<Properties> getter, Consumer<Properties> setter ) WrapperProperties( Supplier<Map<String, String>> getter, Consumer<Properties> setter )
{ {
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
@ -53,25 +54,25 @@ public class WrapperProperties extends Properties
@Override @Override
public String getProperty( String key ) public String getProperty( String key )
{ {
return getter.get().getProperty( key ); return getter.get().get( key );
} }
@Override @Override
public String getProperty( String key, String defaultValue ) public String getProperty( String key, String defaultValue )
{ {
return getter.get().getProperty( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue );
} }
@Override @Override
public Enumeration<?> propertyNames() public Enumeration<?> propertyNames()
{ {
return getter.get().propertyNames(); return Collections.enumeration( getter.get().keySet() );
} }
@Override @Override
public Set<String> stringPropertyNames() public Set<String> stringPropertyNames()
{ {
return getter.get().stringPropertyNames(); return getter.get().keySet();
} }
@Override @Override
@ -101,19 +102,19 @@ public class WrapperProperties extends Properties
@Override @Override
public Enumeration<Object> keys() public Enumeration<Object> keys()
{ {
return getter.get().keys(); return Collections.enumeration( (Set) getter.get().keySet() );
} }
@Override @Override
public Enumeration<Object> elements() public Enumeration<Object> elements()
{ {
return getter.get().elements(); return Collections.enumeration( (Collection) getter.get().values() );
} }
@Override @Override
public boolean contains( Object value ) public boolean contains( Object value )
{ {
return getter.get().contains( value ); return getter.get().containsKey( value != null ? value.toString() : null );
} }
@Override @Override
@ -143,19 +144,19 @@ public class WrapperProperties extends Properties
@Override @Override
public Set<Object> keySet() public Set<Object> keySet()
{ {
return getter.get().keySet(); return (Set) getter.get().keySet();
} }
@Override @Override
public Collection<Object> values() public Collection<Object> values()
{ {
return getter.get().values(); return (Collection) getter.get().values();
} }
@Override @Override
public Set<Map.Entry<Object, Object>> entrySet() public Set<Map.Entry<Object, Object>> entrySet()
{ {
return getter.get().entrySet(); return (Set) getter.get().entrySet();
} }
@Override @Override
@ -177,7 +178,7 @@ public class WrapperProperties extends Properties
@Override @Override
public Object getOrDefault( Object key, Object defaultValue ) public Object getOrDefault( Object key, Object defaultValue )
{ {
return getter.get().getOrDefault( key, defaultValue ); return getter.get().getOrDefault( key, defaultValue != null ? defaultValue.toString() : null );
} }
@Override @Override
@ -320,19 +321,25 @@ public class WrapperProperties extends Properties
@Override @Override
public void save( OutputStream out, String comments ) public void save( OutputStream out, String comments )
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.save( out, comments );
} }
@Override @Override
public void store( Writer writer, String comments ) throws IOException public void store( Writer writer, String comments ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.store( writer, comments );
} }
@Override @Override
public void store( OutputStream out, String comments ) throws IOException public void store( OutputStream out, String comments ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.store( out, comments );
} }
@Override @Override
@ -344,13 +351,17 @@ public class WrapperProperties extends Properties
@Override @Override
public void storeToXML( OutputStream os, String comment ) throws IOException public void storeToXML( OutputStream os, String comment ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment );
} }
@Override @Override
public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException public void storeToXML( OutputStream os, String comment, String encoding ) throws IOException
{ {
throw new UnsupportedOperationException(); Properties props = new Properties();
props.putAll( getter.get() );
props.storeToXML( os, comment, encoding );
} }
} }

View File

@ -38,7 +38,6 @@ import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Objects; import java.util.Objects;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.function.Function; import java.util.function.Function;
@ -122,10 +121,10 @@ public class ${className}
#elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) ); builder.${field.name}( merge( target.get${capField}(), source.get${capField}(), sourceDominant, e -> e ) );
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties src = source.get${capField}(); Map<String, String> src = source.get${capField}();
if ( !src.isEmpty() ) if ( !src.isEmpty() )
{ {
Properties tgt = target.get${capField}(); Map<String, String> tgt = target.get${capField}();
if ( tgt.isEmpty() ) if ( tgt.isEmpty() )
{ {
builder.${field.name}( src ); builder.${field.name}( src );
@ -135,7 +134,7 @@ public class ${className}
} }
else else
{ {
Properties merged = new Properties(); Map<String, String> merged = new HashMap<>();
merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() ); merged.putAll( sourceDominant ? target.get${capField}() : source.get${capField}() );
merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() ); merged.putAll( sourceDominant ? source.get${capField}() : target.get${capField}() );
builder.${field.name}( merged ); builder.${field.name}( merged );

View File

@ -195,13 +195,17 @@ public class ${class.name}
public void set${cap}( ${type} ${field.name} ) public void set${cap}( ${type} ${field.name} )
{ {
#if ( $field.to != "String" && $field.type == "java.util.List" && $field.multiplicity == "*" ) #if ( $field.type == "DOM" )
delegate = getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() );
#elseif( $field.type == "java.util.Properties" )
Map<String, String> map = ${field.name}.entrySet().stream()
.collect( Collectors.toMap( e -> e.getKey().toString(), e -> e.getValue().toString() ) );
delegate = getDelegate().with${cap}( map );
#elseif ( $field.to != "String" && $field.type == "java.util.List" && $field.multiplicity == "*" )
delegate = getDelegate().with${cap}( delegate = getDelegate().with${cap}(
${field.name}.stream().map( c -> c.getDelegate() ).collect( Collectors.toList() ) ); ${field.name}.stream().map( c -> c.getDelegate() ).collect( Collectors.toList() ) );
#elseif ( $field.to && $field.to != "String" ) #elseif ( $field.to && $field.to != "String" )
delegate = getDelegate().with${cap}( ${field.name}.getDelegate() ); delegate = getDelegate().with${cap}( ${field.name}.getDelegate() );
#elseif ( $field.type == "DOM" )
delegate = getDelegate().with${cap}( ( ( Xpp3Dom ) ${field.name} ).getDom() );
#else #else
delegate = getDelegate().with${cap}( ${field.name} ); delegate = getDelegate().with${cap}( ${field.name} );
#end #end

View File

@ -39,8 +39,10 @@ import java.io.Reader;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.apache.maven.api.annotations.Generated; import org.apache.maven.api.annotations.Generated;
@ -769,7 +771,7 @@ public class ${className}
${classLcapName}.${field.name}( ${field.name} ); ${classLcapName}.${field.name}( ${field.name} );
break; break;
#elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" ) #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
Properties ${field.name} = new Properties(); Map<String, String> ${field.name} = new HashMap<>();
while ( parser.nextTag() == XmlPullParser.START_TAG ) while ( parser.nextTag() == XmlPullParser.START_TAG )
{ {
String key = parser.getName(); String key = parser.getName();

View File

@ -273,15 +273,15 @@ public class ${className}
} }
} }
private <T> void writeProperties( String tagName, Properties props, XmlSerializer serializer ) private <T> void writeProperties( String tagName, Map<String, String> props, XmlSerializer serializer )
throws IOException throws IOException
{ {
if ( props != null && !props.isEmpty() ) if ( props != null && !props.isEmpty() )
{ {
serializer.startTag( NAMESPACE, tagName ); serializer.startTag( NAMESPACE, tagName );
for ( Map.Entry<Object, Object> entry : props.entrySet() ) for ( Map.Entry<String, String> entry : props.entrySet() )
{ {
writeTag( entry.getKey().toString(), null, entry.getValue().toString(), serializer ); writeTag( entry.getKey(), null, entry.getValue(), serializer );
} }
serializer.endTag( NAMESPACE, tagName ); serializer.endTag( NAMESPACE, tagName );
} }