All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.vorburger.xtendbeans.XtendBeanGenerator Maven / Gradle / Ivy

There is a newer version: 1.3.2
Show newest version
/**
 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package ch.vorburger.xtendbeans;

import ch.vorburger.xtendbeans.CharSequenceExtensions;
import ch.vorburger.xtendbeans.ReflectUtils;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.eclipse.xtend.lib.annotations.AccessorType;
import org.eclipse.xtend.lib.annotations.Accessors;
import org.eclipse.xtend.lib.annotations.ToString;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.MapExtensions;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.eclipse.xtext.xbase.lib.util.ToStringBuilder;
import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import org.objenesis.instantiator.ObjectInstantiator;

/**
 * Xtend new (Java Bean) object code generates.
 * 
 * Generates highly readable Java Bean object initialization code
 * based on the 
 * Xtend With Operator.  This syntax is very well suited e.g. to capture expected objects in test code.
 * 
 * 

Xtend is a cool JVM language which itself * transpiles to Java source code. There are plugins * for Eclipse and IntelliJ IDEA to work with Xtend available. It is also possible * to use Gradle's Continuous Build mode on the Command Line to get Xtend translated to Java on the fly. * (It would even be imaginable to use Xtend's runtime interpreter to allow reading *.xtend files and create * objects from them, similar to a JSON or XML unmarshalling library, without any code generation.) * *

PS: This implementation is currently written with performance characteristics intended for * manually dumping objects when writing tests. In particular, no Java Reflection results are * cached so far. It is thus not suitable for serializing objects in production. * * @author Michael Vorburger */ @SuppressWarnings("all") public class XtendBeanGenerator { @ToString @Accessors(AccessorType.PUBLIC_GETTER) protected static class Property { private final String name; private final boolean isWriteable; private final Class type; private final Supplier valueFunction; private final Object defaultValue; public Property(final String name, final boolean isWriteable, final Class type, final Function0 valueFunction, final Object defaultValue) { this.name = Preconditions.checkNotNull(name, "name"); this.isWriteable = isWriteable; this.type = Preconditions.>checkNotNull(type, "type"); this.valueFunction = Preconditions.>checkNotNull(new Supplier() { public Object get() { return valueFunction.apply(); } }, "valueFunction"); this.defaultValue = defaultValue; } public boolean hasDefaultValue() { final Object value = this.valueFunction.get(); boolean _xifexpression = false; if (((value == null) && (this.defaultValue == null))) { _xifexpression = true; } else { boolean _xifexpression_1 = false; if (((value != null) && (this.defaultValue != null))) { boolean _xifexpression_2 = false; boolean _isArray = this.type.isArray(); boolean _not = (!_isArray); if (_not) { _xifexpression_2 = Objects.equal(value, this.defaultValue); } else { boolean _switchResult = false; final Object defaultValue = this.defaultValue; boolean _matched = false; if (defaultValue instanceof byte[]) { _matched=true; _switchResult = Arrays.equals(((byte[]) value), ((byte[])this.defaultValue)); } if (!_matched) { if (defaultValue instanceof boolean[]) { _matched=true; _switchResult = Arrays.equals(((boolean[]) value), ((boolean[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof char[]) { _matched=true; _switchResult = Arrays.equals(((char[]) value), ((char[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof double[]) { _matched=true; _switchResult = Arrays.equals(((double[]) value), ((double[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof float[]) { _matched=true; _switchResult = Arrays.equals(((float[]) value), ((float[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof int[]) { _matched=true; _switchResult = Arrays.equals(((int[]) value), ((int[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof long[]) { _matched=true; _switchResult = Arrays.equals(((long[]) value), ((long[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof short[]) { _matched=true; _switchResult = Arrays.equals(((short[]) value), ((short[])this.defaultValue)); } } if (!_matched) { if (defaultValue instanceof Object[]) { _matched=true; _switchResult = Arrays.deepEquals(((Object[]) value), ((Object[])this.defaultValue)); } } if (!_matched) { _switchResult = value.equals(this.defaultValue); } _xifexpression_2 = _switchResult; } _xifexpression_1 = _xifexpression_2; } else { boolean _xifexpression_3 = false; if (((value == null) || (this.defaultValue == null))) { _xifexpression_3 = false; } _xifexpression_1 = _xifexpression_3; } _xifexpression = _xifexpression_1; } return _xifexpression; } @Override @Pure public String toString() { ToStringBuilder b = new ToStringBuilder(this); b.add("name", this.name); b.add("isWriteable", this.isWriteable); b.add("type", this.type); b.add("valueFunction", this.valueFunction); b.add("defaultValue", this.defaultValue); return b.toString(); } @Pure public String getName() { return this.name; } @Pure public boolean isWriteable() { return this.isWriteable; } @Pure public Class getType() { return this.type; } @Pure public Supplier getValueFunction() { return this.valueFunction; } @Pure public Object getDefaultValue() { return this.defaultValue; } } private final Objenesis objenesis = new ObjenesisStd(); private final ReflectUtils reflectUtils = new ReflectUtils(); public void print(final Object bean) { StringConcatenation _builder = new StringConcatenation(); _builder.append("// Code auto. generated by Michael Vorburger\'s "); String _name = this.getClass().getName(); _builder.append(_name); System.out.println(_builder); System.out.println(this.getExpression(bean)); } public String getExpression(final Object bean) { return this.stringify(bean).toString(); } protected CharSequence getNewBeanExpression(final Object bean) { CharSequence _xblockexpression = null; { final Class builderClass = this.getBuilderClass(bean); _xblockexpression = this.getNewBeanExpression(bean, builderClass); } return _xblockexpression; } protected CharSequence getNewBeanExpression(final Object bean, final Class builderClass) { CharSequence _xblockexpression = null; { final boolean isUsingBuilder = this.isUsingBuilder(bean, builderClass); final Map propertiesByName = this.getBeanProperties(bean, builderClass); final Function> _function = new Function>() { @Override public Class apply(final XtendBeanGenerator.Property p) { return p.type; } }; final ImmutableListMultimap, XtendBeanGenerator.Property> propertiesByType = Multimaps., XtendBeanGenerator.Property>index(propertiesByName.values(), _function); final CharSequence constructorArguments = this.constructorArguments(bean, builderClass, propertiesByName, propertiesByType); final Function2 _function_1 = new Function2() { @Override public Boolean apply(final String name, final XtendBeanGenerator.Property property) { return Boolean.valueOf(((property.isWriteable || XtendBeanGenerator.this.isList(property)) && (!property.hasDefaultValue()))); } }; final Iterable filteredRemainingProperties = this.filter(MapExtensions.filter(propertiesByName, _function_1).values()); StringConcatenation _builder = new StringConcatenation(); { if (isUsingBuilder) { _builder.append("("); } } _builder.append("new "); String _shortClassName = this.shortClassName(builderClass); _builder.append(_shortClassName); _builder.append(constructorArguments); { boolean _isEmpty = IterableExtensions.isEmpty(filteredRemainingProperties); boolean _not = (!_isEmpty); if (_not) { _builder.append(" "); String _operator = this.getOperator(bean, builderClass); _builder.append(_operator); _builder.append(" ["); } } _builder.newLineIfNotEmpty(); _builder.append(" "); CharSequence _propertiesListExpression = this.getPropertiesListExpression(filteredRemainingProperties); _builder.append(_propertiesListExpression, " "); _builder.newLineIfNotEmpty(); _builder.append(" "); CharSequence _propertiesListExpression_1 = this.getPropertiesListExpression(this.getAdditionalSpecialProperties(bean, builderClass)); _builder.append(_propertiesListExpression_1, " "); _builder.newLineIfNotEmpty(); _builder.append(" "); CharSequence _additionalInitializationExpression = this.getAdditionalInitializationExpression(bean, builderClass); _builder.append(_additionalInitializationExpression, " "); _builder.newLineIfNotEmpty(); { boolean _isEmpty_1 = IterableExtensions.isEmpty(filteredRemainingProperties); boolean _not_1 = (!_isEmpty_1); if (_not_1) { _builder.append("]"); } } { if (isUsingBuilder) { _builder.append(").build()"); } } _xblockexpression = CharSequenceExtensions.chomp(_builder); } return _xblockexpression; } protected String shortClassName(final Class clazz) { String _xblockexpression = null; { String name = clazz.getSimpleName(); boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(name); if (_isNullOrEmpty) { name = this.longClassName(clazz); } boolean _isNullOrEmpty_1 = StringExtensions.isNullOrEmpty(name); if (_isNullOrEmpty_1) { name = clazz.getName(); } _xblockexpression = name; } return _xblockexpression; } protected String longClassName(final Class clazz) { return clazz.getName(); } protected Iterable filter(final Iterable properties) { return properties; } protected Iterable getAdditionalSpecialProperties(final Object bean, final Class builderClass) { return Collections.emptyList(); } protected CharSequence getPropertiesListExpression(final Iterable properties) { StringConcatenation _builder = new StringConcatenation(); { for(final XtendBeanGenerator.Property property : properties) { _builder.append(property.name); _builder.append(" "); { if ((this.isList(property) && (!property.isWriteable))) { _builder.append("+="); } else { _builder.append("="); } } _builder.append(" "); CharSequence _stringify = this.stringify(property.valueFunction.get()); _builder.append(_stringify); _builder.newLineIfNotEmpty(); } } return _builder; } protected CharSequence getAdditionalInitializationExpression(final Object bean, final Class builderClass) { return ""; } protected boolean isUsingBuilder(final Object bean, final Class builderClass) { boolean _equals = builderClass.equals(bean.getClass()); return (!_equals); } protected String getOperator(final Object bean, final Class builderClass) { return "=>"; } protected boolean isList(final XtendBeanGenerator.Property property) { return property.type.isAssignableFrom(List.class); } protected Class getBuilderClass(final Object bean) { Class _xblockexpression = null; { final Class beanClass = bean.getClass(); Optional> _xifexpression = null; Class _enclosingClass = beanClass.getEnclosingClass(); String _shortClassName = null; if (_enclosingClass!=null) { _shortClassName=this.shortClassName(_enclosingClass); } boolean _endsWith = false; if (_shortClassName!=null) { _endsWith=_shortClassName.endsWith("Builder"); } if (_endsWith) { _xifexpression = Optional.>of(beanClass.getEnclosingClass()); } else { _xifexpression = this.getOptionalBuilderClassByAppendingBuilderToClassName(beanClass); } final Optional> optBuilderClass = _xifexpression; final Predicate> _function = new Predicate>() { @Override public boolean test(final Class builderClass) { return XtendBeanGenerator.this.isBuilder(builderClass); } }; _xblockexpression = optBuilderClass.filter(_function).orElse(beanClass); } return _xblockexpression; } protected boolean isBuilder(final Class builderClass) { return ((builderClass.getConstructors().length > 0) && this.atLeastOneNonStatic(builderClass.getMethods())); } private boolean atLeastOneNonStatic(final Method[] methods) { for (final Method method : methods) { if (((!Modifier.isStatic(method.getModifiers())) && (!method.getDeclaringClass().equals(Object.class)))) { return true; } } return false; } protected Optional> getOptionalBuilderClassByAppendingBuilderToClassName(final Class klass) { Optional> _xblockexpression = null; { final ClassLoader classLoader = klass.getClassLoader(); String _name = klass.getName(); final String buildClassName = (_name + "Builder"); Optional> _xtrycatchfinallyexpression = null; try { _xtrycatchfinallyexpression = Optional.>of(Class.forName(buildClassName, false, classLoader)); } catch (final Throwable _t) { if (_t instanceof ClassNotFoundException) { final ClassNotFoundException e = (ClassNotFoundException)_t; _xtrycatchfinallyexpression = Optional.>empty(); } else { throw Exceptions.sneakyThrow(_t); } } _xblockexpression = _xtrycatchfinallyexpression; } return _xblockexpression; } protected CharSequence constructorArguments(final Object bean, final Class builderClass, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { CharSequence _xblockexpression = null; { final Constructor[] constructors = builderClass.getConstructors(); CharSequence _xifexpression = null; boolean _isEmpty = ((List>)Conversions.doWrapArray(constructors)).isEmpty(); if (_isEmpty) { StringConcatenation _builder = new StringConcatenation(); _xifexpression = _builder; } else { CharSequence _xblockexpression_1 = null; { final Constructor constructor = this.findSuitableConstructor(builderClass, constructors, propertiesByName, propertiesByType); CharSequence _xifexpression_1 = null; if ((constructor == null)) { StringConcatenation _builder_1 = new StringConcatenation(); _xifexpression_1 = _builder_1; } else { CharSequence _xblockexpression_2 = null; { final Parameter[] parameters = constructor.getParameters(); StringConcatenation _builder_2 = new StringConcatenation(); { boolean _hasElements = false; for(final Parameter parameter : parameters) { if (!_hasElements) { _hasElements = true; _builder_2.append("("); } else { _builder_2.appendImmediate(", ", ""); } CharSequence _constructorParameterValue = this.getConstructorParameterValue(parameter, propertiesByName, propertiesByType); _builder_2.append(_constructorParameterValue); } if (_hasElements) { _builder_2.append(")"); } } _xblockexpression_2 = _builder_2; } _xifexpression_1 = _xblockexpression_2; } _xblockexpression_1 = _xifexpression_1; } _xifexpression = _xblockexpression_1; } _xblockexpression = _xifexpression; } return _xblockexpression; } protected Constructor findSuitableConstructor(final Class builderClass, final Constructor[] constructors, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { try { final List> possibleConstructors = this.findAllPossibleConstructors(constructors, propertiesByName, propertiesByType, true); return this.findSuitableConstructorINTERNAL(builderClass, possibleConstructors, propertiesByName, propertiesByType); } catch (final Throwable _t) { if (_t instanceof IllegalStateException) { final IllegalStateException e = (IllegalStateException)_t; final List> possibleConstructorsWithDefaultValues = this.findAllPossibleConstructors(constructors, propertiesByName, propertiesByType, false); return this.findSuitableConstructorINTERNAL(builderClass, possibleConstructorsWithDefaultValues, propertiesByName, propertiesByType); } else { throw Exceptions.sneakyThrow(_t); } } } private Constructor findSuitableConstructorINTERNAL(final Class builderClass, final List> possibleConstructors, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { try { Constructor _xblockexpression = null; { final Set propertyNames = propertiesByName.keySet(); boolean _isEmpty = possibleConstructors.isEmpty(); if (_isEmpty) { String _name = builderClass.getName(); String _plus = ("No suitable constructor found on " + _name); String _plus_1 = (_plus + ", write a *Builder to help, as none of these match: "); String _plus_2 = (_plus_1 + possibleConstructors); String _plus_3 = (_plus_2 + "; for: "); String _plus_4 = (_plus_3 + propertyNames); throw new IllegalStateException(_plus_4); } final Function1, Integer> _function = new Function1, Integer>() { @Override public Integer apply(final Constructor it) { return Integer.valueOf(it.getParameterCount()); } }; final Constructor randomMaxParametersConstructor = IterableExtensions., Integer>maxBy(possibleConstructors, _function); final Function1, Boolean> _function_1 = new Function1, Boolean>() { @Override public Boolean apply(final Constructor it) { int _parameterCount = it.getParameterCount(); int _parameterCount_1 = randomMaxParametersConstructor.getParameterCount(); return Boolean.valueOf((_parameterCount == _parameterCount_1)); } }; final Iterable> retainedConstructors = IterableExtensions.>filter(possibleConstructors, _function_1); Constructor _xifexpression = null; int _size = IterableExtensions.size(retainedConstructors); boolean _equals = (_size == 1); if (_equals) { _xifexpression = IterableExtensions.>head(retainedConstructors); } else { Constructor _xifexpression_1 = null; boolean _isEmpty_1 = IterableExtensions.isEmpty(retainedConstructors); if (_isEmpty_1) { throw new IllegalStateException( ((("No suitable constructor found, write a *Builder to help, as none of these match: " + possibleConstructors) + "; for: ") + propertyNames)); } else { final Supplier _function_2 = new Supplier() { @Override public IllegalStateException get() { return new IllegalStateException( ((("More than 1 suitable constructor found; remove one or write a *Builder to help instead: " + retainedConstructors) + "; for: ") + propertyNames)); } }; _xifexpression_1 = this.resolveAmbiguousConstructorChoice(((Constructor[])Conversions.unwrapArray(retainedConstructors, Constructor.class)), propertiesByName, propertiesByType).orElseThrow(_function_2); } _xifexpression = _xifexpression_1; } _xblockexpression = _xifexpression; } return _xblockexpression; } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } protected List> findAllPossibleConstructors(final Constructor[] constructors, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType, final boolean considerDefault) { final ArrayList> possibleParameterByNameAndTypeMatchingConstructors = CollectionLiterals.>newArrayList(); final ArrayList> possibleParameterOnlyByTypeMatchingConstructors = CollectionLiterals.>newArrayList(); for (final Constructor constructor : constructors) { boolean _isSuitableConstructorByName = this.isSuitableConstructorByName(constructor, propertiesByName, considerDefault); if (_isSuitableConstructorByName) { possibleParameterByNameAndTypeMatchingConstructors.add(constructor); } else { boolean _isSuitableConstructorByType = this.isSuitableConstructorByType(constructor, propertiesByType, considerDefault); if (_isSuitableConstructorByType) { possibleParameterOnlyByTypeMatchingConstructors.add(constructor); } } } ArrayList> _xifexpression = null; boolean _isEmpty = possibleParameterByNameAndTypeMatchingConstructors.isEmpty(); boolean _not = (!_isEmpty); if (_not) { _xifexpression = possibleParameterByNameAndTypeMatchingConstructors; } else { _xifexpression = possibleParameterOnlyByTypeMatchingConstructors; } return _xifexpression; } protected Optional> resolveAmbiguousConstructorChoice(final Constructor[] constructors, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { return this.chooseUnionConstructor(constructors, propertiesByName, propertiesByType); } /** * If there are exactly 2 constructors with each 1 argument, and one of them takes a String and the other doesn't, then pick the other. */ protected Optional> chooseUnionConstructor(final Constructor[] constructors, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { Optional> _xblockexpression = null; { int _length = constructors.length; boolean _equals = (_length == 2); if (_equals) { final Parameter[] constructor1Params = constructors[0].getParameters(); final Parameter[] constructor2Params = constructors[1].getParameters(); if (((constructor1Params.length == 1) && (constructor2Params.length == 1))) { if (((!this.isLikeString(constructor1Params[0].getType())) && this.isLikeString(constructor2Params[0].getType()))) { return Optional.>of(constructors[0]); } if ((this.isLikeString(constructor1Params[0].getType()) && (!this.isLikeString(constructor2Params[0].getType())))) { return Optional.>of(constructors[1]); } } } _xblockexpression = Optional.>empty(); } return _xblockexpression; } protected boolean isLikeString(final Class type) { try { boolean _xblockexpression = false; { final Class charArrayClass = Class.forName("[C"); _xblockexpression = (type.equals(String.class) || type.equals(charArrayClass)); } return _xblockexpression; } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } protected boolean isSuitableConstructorByName(final Constructor constructor, final Map propertiesByName, final boolean considerDefault) { boolean _xblockexpression = false; { boolean suitableConstructor = true; Parameter[] _parameters = constructor.getParameters(); for (final Parameter parameter : _parameters) { { final String parameterName = this.getParameterName(parameter); boolean _containsKey = propertiesByName.containsKey(parameterName); boolean _not = (!_containsKey); if (_not) { suitableConstructor = false; } else { final XtendBeanGenerator.Property property = propertiesByName.get(parameterName); suitableConstructor = this.isParameterSuitableForProperty(parameter, property, considerDefault); } } } _xblockexpression = suitableConstructor; } return _xblockexpression; } protected boolean isSuitableConstructorByType(final Constructor constructor, final Multimap, XtendBeanGenerator.Property> propertiesByType, final boolean considerDefault) { boolean _xblockexpression = false; { boolean suitableConstructor = true; Parameter[] _parameters = constructor.getParameters(); for (final Parameter parameter : _parameters) { { final Collection matchingProperties = propertiesByType.get(parameter.getType()); int _size = matchingProperties.size(); boolean _notEquals = (_size != 1); if (_notEquals) { suitableConstructor = false; } else { final XtendBeanGenerator.Property property = IterableExtensions.head(matchingProperties); suitableConstructor = this.isParameterSuitableForProperty(parameter, property, considerDefault); } } } _xblockexpression = suitableConstructor; } return _xblockexpression; } protected boolean isParameterSuitableForProperty(final Parameter parameter, final XtendBeanGenerator.Property property, final boolean considerDefault) { boolean _equals = parameter.getType().equals(property.type); boolean _not = (!_equals); if (_not) { return false; } else { if ((considerDefault && property.hasDefaultValue())) { return false; } else { return true; } } } protected CharSequence getConstructorParameterValue(final Parameter parameter, final Map propertiesByName, final Multimap, XtendBeanGenerator.Property> propertiesByType) { final String constructorParameterName = this.getParameterName(parameter); final XtendBeanGenerator.Property propertyByName = propertiesByName.get(constructorParameterName); if ((propertyByName != null)) { propertiesByName.remove(propertyByName.name); return this.stringify(propertyByName.valueFunction.get()); } else { final Collection matchingProperties = propertiesByType.get(parameter.getType()); int _size = matchingProperties.size(); boolean _equals = (_size == 1); if (_equals) { final XtendBeanGenerator.Property propertyByType = IterableExtensions.head(matchingProperties); propertiesByName.remove(propertyByType.name); return this.stringify(propertyByType.valueFunction.get()); } else { int _size_1 = matchingProperties.size(); boolean _greaterThan = (_size_1 > 1); if (_greaterThan) { Executable _declaringExecutable = parameter.getDeclaringExecutable(); String _plus = ((("Constructor parameter \'" + constructorParameterName) + "\' of ") + _declaringExecutable); String _plus_1 = (_plus + " matches no property by name, "); String _plus_2 = (_plus_1 + "but more than 1 property by type: "); String _plus_3 = (_plus_2 + matchingProperties); String _plus_4 = (_plus_3 + ", consider writing a *Builder; all bean\'s properties: "); Set _keySet = propertiesByName.keySet(); String _plus_5 = (_plus_4 + _keySet); throw new IllegalStateException(_plus_5); } else { Executable _declaringExecutable_1 = parameter.getDeclaringExecutable(); String _plus_6 = ((("Constructor parameter \'" + constructorParameterName) + "\' of ") + _declaringExecutable_1); String _plus_7 = (_plus_6 + " not matching by name or type, "); String _plus_8 = (_plus_7 + "consider writing a *Builder; bean\'s properties: "); Set _keySet_1 = propertiesByName.keySet(); String _plus_9 = (_plus_8 + _keySet_1); throw new IllegalStateException(_plus_9); } } } } protected String getParameterName(final Parameter parameter) { String _xblockexpression = null; { boolean _isNamePresent = parameter.isNamePresent(); boolean _not = (!_isNamePresent); if (_not) { Executable _declaringExecutable = parameter.getDeclaringExecutable(); String _plus = (("Needs javac -parameters; or, in Eclipse: \'Store information about method parameters (usable via " + "reflection)\' in Window -> Preferences -> Java -> Compiler, for: ") + _declaringExecutable); throw new IllegalStateException(_plus); } _xblockexpression = parameter.getName(); } return _xblockexpression; } protected CharSequence stringify(final Object object) { CharSequence _switchResult = null; boolean _matched = false; if (Objects.equal(object, null)) { _matched=true; _switchResult = "null"; } if (!_matched) { boolean _isArray = object.getClass().isArray(); if (_isArray) { _matched=true; _switchResult = this.stringifyArray(object); } } if (!_matched) { if (object instanceof Set) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#{"); _builder.newLine(); { boolean _hasElements = false; for(final Object element : ((Set)object)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(element); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("}"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Iterable) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final Object element : ((Iterable)object)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(element); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Map) { _matched=true; _switchResult = this.stringify(((Map)object).entrySet()); } } if (!_matched) { if (object instanceof Map.Entry) { _matched=true; StringConcatenation _builder = new StringConcatenation(); CharSequence _stringify = this.stringify(((Map.Entry)object).getKey()); _builder.append(_stringify); _builder.append(" -> "); CharSequence _stringify_1 = this.stringify(((Map.Entry)object).getValue()); _builder.append(_stringify_1); _switchResult = _builder; } } if (!_matched) { if (object instanceof String) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("\""); _builder.append(((String)object)); _builder.append("\""); _switchResult = _builder; } } if (!_matched) { if (object instanceof Integer) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Integer)object)); _switchResult = _builder; } } if (!_matched) { if (object instanceof Long) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Long)object)); _builder.append("L"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Boolean) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Boolean)object)); _switchResult = _builder; } } if (!_matched) { if (object instanceof Byte) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Byte)object)); _switchResult = _builder; } } if (!_matched) { if (object instanceof Character) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("\'"); _builder.append(((Character)object)); _builder.append("\'"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Double) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Double)object)); _builder.append("d"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Float) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Float)object)); _builder.append("f"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Short) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((Short)object)); _builder.append(" as short"); _switchResult = _builder; } } if (!_matched) { if (object instanceof BigInteger) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append(((BigInteger)object)); _builder.append("bi"); _switchResult = _builder; } } if (!_matched) { if (object instanceof Enum) { _matched=true; StringConcatenation _builder = new StringConcatenation(); String _shortClassName = this.shortClassName(((Enum)object).getDeclaringClass()); _builder.append(_shortClassName); _builder.append("."); String _name = ((Enum)object).name(); _builder.append(_name); _switchResult = _builder; } } if (!_matched) { if (object instanceof Class) { _matched=true; _switchResult = this.stringify(((Class)object)); } } if (!_matched) { StringConcatenation _builder = new StringConcatenation(); CharSequence _newBeanExpression = this.getNewBeanExpression(object); _builder.append(_newBeanExpression); _switchResult = _builder; } return _switchResult; } protected String stringify(final Class aClass) { return this.longClassName(aClass); } protected CharSequence stringifyArray(final Object array) { CharSequence _switchResult = null; boolean _matched = false; if (array instanceof byte[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final byte e : ((byte[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Byte.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } if (!_matched) { if (array instanceof boolean[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final boolean e : ((boolean[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Boolean.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof char[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final char e : ((char[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Character.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof double[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final double e : ((double[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Double.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof float[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final float e : ((float[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Float.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof int[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final int e : ((int[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Integer.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof long[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final long e : ((long[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Long.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof short[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final short e : ((short[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(Short.valueOf(e)); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } if (!_matched) { if (array instanceof Object[]) { _matched=true; StringConcatenation _builder = new StringConcatenation(); _builder.append("#["); _builder.newLine(); { boolean _hasElements = false; for(final Object e : ((Object[])array)) { if (!_hasElements) { _hasElements = true; } else { _builder.appendImmediate(",", " "); } _builder.append(" "); CharSequence _stringify = this.stringify(e); _builder.append(_stringify, " "); _builder.newLineIfNotEmpty(); } } _builder.append("]"); _switchResult = _builder; } } return _switchResult; } protected Map getBeanProperties(final Object bean, final Class builderClass) { final Object defaultValuesBean = this.newEmptyBeanForDefaultValues(builderClass); final ReflectUtils.BeanProperty[] properties = this.reflectUtils.getProperties(builderClass); final LinkedHashMap propertiesMap = CollectionLiterals.newLinkedHashMap(); for (final ReflectUtils.BeanProperty property : properties) { boolean _isPropertyConsidered = this.isPropertyConsidered(builderClass, property.name, property.type); if (_isPropertyConsidered) { final Function0 _function = new Function0() { @Override public Object apply() { return property.invokeGetter(bean); } }; Object _invokeGetter = property.invokeGetter(defaultValuesBean); XtendBeanGenerator.Property _property = new XtendBeanGenerator.Property( property.name, property.isWriteable, property.type, _function, _invokeGetter); propertiesMap.put(property.name, _property); } } return propertiesMap; } protected boolean isPropertyConsidered(final Class builderClass, final String propertyName, final Class type) { return true; } protected Object newEmptyBeanForDefaultValues(final Class builderClass) { try { Object _xtrycatchfinallyexpression = null; try { _xtrycatchfinallyexpression = builderClass.newInstance(); } catch (final Throwable _t) { if (_t instanceof InstantiationException) { final InstantiationException e = (InstantiationException)_t; Object _xblockexpression = null; { final ObjectInstantiator builderClassInstantiator = this.objenesis.getInstantiatorOf(builderClass); _xblockexpression = builderClassInstantiator.newInstance(); } _xtrycatchfinallyexpression = _xblockexpression; } else { throw Exceptions.sneakyThrow(_t); } } return _xtrycatchfinallyexpression; } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } }