group components;

/*
 * 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.
 */

component(componentInfo) ::= <<
// ---------- Attention: Generated code, please do not modify! -----------

/*
 * 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.
 */

package <componentInfo.packageName>;

<componentInfo.imports:import(); separator="\n">
import org.apache.myfaces.tobago.internal.util.ArrayUtils;
import org.apache.myfaces.tobago.internal.util.StringUtils;
import org.apache.myfaces.tobago.internal.util.Deprecation;
import org.apache.myfaces.tobago.component.Tags;
import jakarta.annotation.Generated;
import jakarta.el.ELException;
import jakarta.faces.FacesException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jakarta.el.MethodExpression;
import jakarta.el.ValueExpression;

/**
 <if(componentInfo.description)>
 <componentInfo.description>
 <endif>
  * UIComponent class, generated from template {@code component.stg} with class
  * {@link <componentInfo.sourceClass>}.
   <if(componentInfo.deprecated)>
   @deprecated
   <endif>
 */
<if(componentInfo.deprecated)>
@Deprecated

<endif>
@Generated("component.stg")
public class <componentInfo.className>
    extends <componentInfo.superClassName> <first(componentInfo.interfaces):{ n | implements <n>}><rest(componentInfo.interfaces):{ n |, <n>}> {

  private static final Tags TAG = Tags.<componentInfo.tagName>;

  public static final String COMPONENT_TYPE = TAG.componentType();

  <if(componentInfo.componentFamily)>
  public static final String COMPONENT_FAMILY = "<componentInfo.componentFamily>";

  <endif>
  <if(componentInfo.behaviors)>
  private static final Collection\<String\> EVENT_NAMES = Arrays.asList(<first(componentInfo.behaviors):{ it | "<it>"}><rest(componentInfo.behaviors):{ it |, "<it>"}>);

  @Override
  public Collection\<String\> getEventNames() {
    return EVENT_NAMES;
  }

  <endif>
  <if(componentInfo.defaultBehavior)>
  @Override
  public String getDefaultEventName() {
    return "<componentInfo.defaultBehavior>";
  }

  <endif>
  <componentInfo.transientProperties:field(); separator="\n">

  <if(componentInfo.properties)>
  enum PropertyKeys {
    <componentInfo.nonTransientProperties:enumName(); separator="\n">
  }
  <endif>

  <if(componentInfo.componentFamily)>
  public String getFamily() {
    return COMPONENT_FAMILY;
  }

  <endif>
  <componentInfo.properties:{ p | <p:(p.propertyTemplate)()>}; separator="\n">

  <if(componentInfo.transientProperties)>
  public Object saveState(FacesContext context) {
    <componentInfo.transientProperties:{ p | <p:resetField()>}; separator="\n">
    return super.saveState(context);
  }
  <endif>

  @Override
  public void restoreState(FacesContext context, Object state) {
    // FIXME HACK for mojarra SystemEventListener state restoring bug
    pushComponentToEL(context, this);
    super.restoreState(context, state);
    popComponentFromEL(context);
  }

}
>>

import() ::= <<
import <it>;
>>

createDescription(property) ::= <<
<if(property.description)>
/**
<property.description>
<if(property.defaultValue)>
\<br\>Default: \<code\><property.defaultValue>\</code\>
<endif>
<if(property.allowedValues)>
\<br\>Allowed Values: \<code\><property.allowedValues:allowedValue(); separator=",">\</code\>
<endif>

<if(property.deprecated)>
@deprecated
<endif>
*/
<endif>
>>

checkDeprecated(property) ::= <<
<if(property.deprecated)>
@Deprecated
<endif>
>>

logDeprecated(property) ::= <<
<if(property.deprecated)>
  Deprecation.LOG.error("The attribute '<property.propertyName>' of '<componentInfo.className>' is deprecated. "
      + "Please refer the documentation for further information.");
<endif>
>>

allowedValue() ::= <<
<it>
>>

IntegerProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Number value  = (Number) getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (value != null) {
    return value.intValue();
  }
  <endif>
  <if(property.defaultCode)>
  return <property.defaultCode>;
  <else>
  return null;
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

ObjectProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  return getStateHelper().eval(PropertyKeys.<property.propertyName>);
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

StringArrayProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public String[] get<property.upperCamelCaseName>() {
  Object strArray = getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (strArray != null) {
    if (strArray instanceof String[]) {
      return (String[]) strArray;
    } else if (strArray instanceof String) {
      String[] strings = StringUtils.split((String) strArray, ", ");
      List\<String\> result = new ArrayList\<String\>(strings.length);
      for (String string : strings) {
        if (string.trim().length() != 0) {
          result.add(string.trim());
        }
      }
      return result.toArray(new String[result.size()]);
    } else if (strArray == null) {
      return org.apache.myfaces.tobago.internal.util.ArrayUtils.EMPTY_STRING_ARRAY;
    } else {
      return new String[]{strArray.toString()};
    }
  }
  return org.apache.myfaces.tobago.internal.util.ArrayUtils.EMPTY_STRING_ARRAY;
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(String[] <property.propertyName>) {
  <logDeprecated(property)>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
}
>>

booleanProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public boolean is<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Boolean bool = (Boolean) getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (bool != null) {
    return bool;
  }
  <endif>
  <if(property.defaultCode)>
  return <property.defaultCode>;
  <else>
  return false;
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(boolean <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

BooleanProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public Boolean get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Boolean bool = (Boolean) getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (bool != null) {
    return bool;
  }
  <endif>
  <if(property.defaultCode)>
  return <property.defaultCode>;
  <else>
  return null;
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(Boolean <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

SeverityProperty(property) ::= <<
<NormalProperty(property)>
>>

TextAlignProperty(property) ::= <<
<NormalProperty(property)>
>>

SegmentJustifyProperty(property) ::= <<
<NormalProperty(property)>
>>

VerticalAlignProperty(property) ::= <<
<NormalProperty(property)>
>>

SuggestFilterProperty(property) ::= <<
<NormalProperty(property)>
>>

DisplayProperty(property) ::= <<
<NormalProperty(property)>
>>

OrientationProperty(property) ::= <<
<NormalProperty(property)>
>>

PositionProperty(property) ::= <<
<NormalProperty(property)>
>>

OverflowProperty(property) ::= <<
<NormalProperty(property)>
>>

SanitizeModeProperty(property) ::= <<
<NormalProperty(property)>
>>

CollapseModeProperty(property) ::= <<
<NormalProperty(property)>
>>

ShowPositionProperty(property) ::= <<
<NormalProperty(property)>
>>

StyleProperty(property) ::= <<
<NormalProperty(property)>
>>

CustomClassProperty(property) ::= <<
<NormalProperty(property)>
>>

OrderByProperty(property) ::= <<
<NormalProperty(property)>
>>

SelectableProperty(property) ::= <<
<NormalProperty(property)>
>>

AlignItemsProperty(property) ::= <<
<NormalProperty(property)>
>>

PlacementProperty(property) ::= <<
<NormalProperty(property)>
>>

LocalDateProperty(property) ::= <<
<NormalProperty(property)>
>>

JustifyContentProperty(property) ::= <<
<NormalProperty(property)>
>>

DateTypeProperty(property) ::= <<
<NormalProperty(property)>
>>

SwitchTypeProperty(property) ::= <<
<NormalProperty(property)>
>>

StringProperty(property) ::= <<
<NormalProperty(property)>
>>

CharacterProperty(property) ::= <<
<NormalProperty(property)>
>>

LabelLayoutProperty(property) ::= <<
<NormalProperty(property)>
>>

DecorationPositionProperty(property) ::= <<
<NormalProperty(property)>
>>

ClientBehaviorsProperty(property) ::= <<
<NormalProperty(property)>
>>

GridSpanProperty(property) ::= <<
<NormalProperty(property)>
>>

DoubleProperty(property) ::= <<
<NormalProperty(property)>
>>

NumberProperty(property) ::= <<
<NormalProperty(property)>
>>

FloatProperty(property) ::= <<
<NormalProperty(property)>
>>

MethodExpressionProperty(property) ::= <<

public <property.type> get<property.upperCamelCaseName>Expression() {
  return (<property.type>) getStateHelper().eval(PropertyKeys.<property.propertyName>);
}

public void set<property.upperCamelCaseName>Expression(<property.type> <property.propertyName>) {
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
}

>>

NormalProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  <if(property.defaultCode)>
  <property.type> <property.propertyName> = (<property.type>) getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  return (<property.type>) getStateHelper().eval(PropertyKeys.<property.propertyName>);
  <endif>
  <endif>
  <if(property.defaultCode)>
  return <property.defaultCode>;
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

MeasureProperty(property) ::= <<

<createDescription(property)>
<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Object object = getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (object != null) {
     return Measure.valueOf(object);
  }
  <endif>
  <if(property.defaultCode)>
  return <property.defaultCode>;
  <else>
  return null;
  <endif>
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

MeasureListProperty(property) ::= <<
<NormalProperty(property)>
>>

SegmentMeasureListProperty(property) ::= <<
<NormalProperty(property)>
>>

MarkupProperty(property) ::= <<

<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Object object = getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (object != null) {
    return Markup.valueOf(object);
  }
  <endif>
  return null;
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

CssProperty(property) ::= <<

<checkDeprecated(property)>
public <property.type> get<property.upperCamelCaseName>() {
  <if(property.transient)>
  if (<property.propertyName> != null) {
    return <property.propertyName>;
  }
  <else>
  Object object = getStateHelper().eval(PropertyKeys.<property.propertyName>);
  if (object != null) {
    return Css.valueOf(object);
  }
  <endif>
  return null;
}

<checkDeprecated(property)>
public void set<property.upperCamelCaseName>(<property.type> <property.propertyName>) {
  <logDeprecated(property)>
  <if(property.transient)>
  this.<property.propertyName> = <property.propertyName>;
  <else>
  getStateHelper().put(PropertyKeys.<property.propertyName>, <property.propertyName>);
  <endif>
}
>>

enumName() ::= <<
<it.propertyName>,
>>

strings() ::= <<
<it.propertyName>,
>>

field() ::= <<
private <it.internalType> <it.propertyName>;
>>

resetField() ::= <<
<it.propertyName> = null;
>>
