001/*
002 * ============================================================================
003 *  Copyright © 2002-2022 by Thomas Thrien.
004 *  All Rights Reserved.
005 * ============================================================================
006 *  Licensed to the public under the agreements of the GNU Lesser General Public
007 *  License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *       http://www.gnu.org/licenses/lgpl.html
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 *  License for the specific language governing permissions and limitations
015 *  under the License.
016 */
017
018package org.tquadrat.foundation.config.ap.impl.specialprops;
019
020import static javax.lang.model.element.Modifier.FINAL;
021import static javax.lang.model.element.Modifier.PUBLIC;
022import static org.apiguardian.api.API.Status.STABLE;
023import static org.tquadrat.foundation.config.SpecialPropertyType.CONFIG_PROPERTY_MESSAGEPREFIX;
024import static org.tquadrat.foundation.config.ap.ConfigAnnotationProcessor.MSG_NoMessagePrefix;
025import static org.tquadrat.foundation.config.ap.PropertySpec.PropertyFlag.EXEMPT_FROM_TOSTRING;
026import static org.tquadrat.foundation.config.ap.PropertySpec.PropertyFlag.GETTER_ON_MAP;
027import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
028
029import java.util.Optional;
030import java.util.function.BiFunction;
031
032import org.apiguardian.api.API;
033import org.tquadrat.foundation.annotation.ClassVersion;
034import org.tquadrat.foundation.annotation.MountPoint;
035import org.tquadrat.foundation.ap.CodeGenerationError;
036import org.tquadrat.foundation.config.SpecialPropertyType;
037import org.tquadrat.foundation.config.ap.impl.CodeBuilder;
038import org.tquadrat.foundation.config.ap.impl.PropertySpecImpl;
039import org.tquadrat.foundation.javacomposer.FieldSpec;
040import org.tquadrat.foundation.javacomposer.MethodSpec;
041import org.tquadrat.foundation.javacomposer.TypeName;
042
043/**
044 *  The implementation of
045 *  {@link SpecialPropertySpecBase}
046 *  for
047 *  {@link SpecialPropertyType#CONFIG_PROPERTY_MESSAGEPREFIX}.
048 *
049 *  @version $Id: MessagePrefixProperty.java 1001 2022-01-29 16:42:15Z tquadrat $
050 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
051 *  @UMLGraph.link
052 *  @since 0.1.0
053 */
054@ClassVersion( sourceVersion = "$Id: MessagePrefixProperty.java 1001 2022-01-29 16:42:15Z tquadrat $" )
055@API( status = STABLE, since = "0.1.0" )
056public final class MessagePrefixProperty extends SpecialPropertySpecBase
057{
058        /*--------------*\
059    ====** Constructors **=====================================================
060        \*--------------*/
061    /**
062     *  Creates a new instance of {@code ProcessIdProperty}.
063     */
064    public MessagePrefixProperty()
065    {
066        super( CONFIG_PROPERTY_MESSAGEPREFIX, EXEMPT_FROM_TOSTRING, GETTER_ON_MAP );
067    }   //  ProcessIdProperty()
068
069        /*---------*\
070    ====** Methods **==========================================================
071        \*---------*/
072    /**
073     *  <p>{@summary The implementation of the method that composes a getter
074     *  for the given property.}</p>
075     *
076     *  @param  codeBuilder The factory for the code generation.
077     *  @param  property    The property.
078     *  @return The method specification.
079     */
080    @SuppressWarnings( {"OptionalGetWithoutIsPresent", "TypeMayBeWeakened", "UseOfConcreteClass"} )
081    private static final MethodSpec composeGetter( final CodeBuilder codeBuilder, final PropertySpecImpl property )
082    {
083        final var composer = requireNonNullArgument( codeBuilder, "codeBuilder" ).getComposer();
084
085        /*
086         * This is the value from the String constant holding the message
087         * prefix, not the name of that field!
088         */
089        final var messagePrefix = codeBuilder.getConfiguration().getMessagePrefix()
090            .orElseThrow( () -> new CodeGenerationError( MSG_NoMessagePrefix ) );
091
092        //---* Obtain the builder *--------------------------------------------
093        final var builder = property.getGetterBuilder()
094            .orElseGet( () -> composer.methodBuilder( property.getGetterMethodName().get() )
095                .addAnnotation( Override.class )
096                .addModifiers( PUBLIC )
097                .returns( property.getGetterReturnType() )
098            );
099        builder.addModifiers( FINAL )
100            .addJavadoc( composer.createInheritDocComment() );
101
102        //---* Create the body *-----------------------------------------------
103        builder.addStatement( "return $1S", messagePrefix );
104
105        //---* Create the return value *---------------------------------------
106        final var retValue = builder.build();
107
108        //---* Done *----------------------------------------------------------
109        return retValue;
110    }   //  composeGetter()
111
112    /**
113     *  {@inheritDoc}
114     */
115    @Override
116    public final Optional<TypeName> getCLIValueHandlerClass() { return Optional.empty(); }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public final Optional<BiFunction<CodeBuilder,PropertySpecImpl, FieldSpec>> getFieldComposer() { return Optional.empty(); }
123
124    /**
125     * {@inheritDoc}
126     */
127    @Override
128    @MountPoint
129    public Optional<BiFunction<CodeBuilder,PropertySpecImpl,MethodSpec>> getGetterComposer() { return Optional.of( MessagePrefixProperty::composeGetter ); }
130
131    /**
132     *  {@inheritDoc}
133     */
134    @Override
135    public final TypeName getGetterReturnType() { return getPropertyType(); }
136
137    /**
138     *  {@inheritDoc}
139     */
140    @Override
141    public final Optional<TypeName> getPrefsAccessorClass() { return Optional.empty(); }
142
143    /**
144     *  {@inheritDoc}
145     */
146    @Override
147    public final TypeName getPropertyType() { return TypeName.from( String.class ); }
148
149    /**
150     *  {@inheritDoc}
151     */
152    @Override
153    public final Optional<TypeName> getStringConverterClass() { return Optional.empty(); }
154}
155//  class MessagePrefixProperty
156
157/*
158 *  End of File
159 */