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

io.github.jsoagger.jfxcore.engine.utils.ComponentUtils Maven / Gradle / Ivy

There is a newer version: 1.0.3
Show newest version
/*-
 * ========================LICENSE_START=================================
 * JSoagger 
 * %%
 * Copyright (C) 2019 JSOAGGER
 * %%
 * Licensed 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.
 * =========================LICENSE_END==================================
 */

package io.github.jsoagger.jfxcore.engine.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import io.github.jsoagger.core.utils.Assert;
import io.github.jsoagger.core.utils.StringUtils;
//import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;
import io.github.jsoagger.jfxcore.api.IBuildable;
import io.github.jsoagger.jfxcore.api.IComponentProcessor;
import io.github.jsoagger.jfxcore.api.IForwardEditableFieldsetsProcessor;
import io.github.jsoagger.jfxcore.api.IForwardEditor;
import io.github.jsoagger.jfxcore.api.services.Services;
import io.github.jsoagger.jfxcore.viewdefinition.json.xml.XMLConstants;
import io.github.jsoagger.jfxcore.viewdefinition.json.xml.model.VLViewComponentXML;
import io.github.jsoagger.jfxcore.viewdefinition.json.xml.model.VLViewConfigXML;
import io.github.jsoagger.jfxcore.engine.components.input.SimpleButton;
import io.github.jsoagger.jfxcore.engine.controller.AbstractViewController;
import io.github.jsoagger.jfxcore.engine.controller.main.RootStructureController;
import io.github.jsoagger.jfxcore.engine.controller.main.StandardViewController;
import io.github.jsoagger.jfxcore.engine.controller.main.layout.ViewStructure;

import javafx.scene.Node;

/**
 * @author Ramilafananana VONJISOA
 * @mailto [email protected]
 * @date 2019
 */
public class ComponentUtils {

  //protected static final Logger //LOG = LogManager.getLogger(ComponentUtils.class);
  protected static Map CACHE = new HashMap<>();
  protected static final String VALIDATOR = "Validator";


  /**
   * List passed in parameter is a list where components have not been resolved, mean id is empty, ref
   * is not empty
   *
   * @param controller
   * @param components
   * @return
   */
  public static List resolveAndGenerate(AbstractViewController controller, List components) {
    Assert.notNull(components);
    Assert.notNull(controller);

    final List resolvedComponents = resolveDefinitions(controller, components);
    return generate(controller, resolvedComponents);
  }


  /**
   *
   * Generates {@link IBuildable} from given list of components.
   *
   * @param controller
   * @param components
   * @return {@link List}
   */
  public static List generate(AbstractViewController controller, List resolved) {
    Assert.notNull(resolved);
    Assert.notNull(controller);

    List result = new ArrayList<>();
    for (VLViewComponentXML definition : resolved) {
      IBuildable buildable = generate(controller, definition);
      if (buildable != null) {
        result.add(buildable);
      }
    }

    return result;
  }


  public static IBuildable generate(AbstractViewController controller, VLViewComponentXML resolved) {
    String componentType = resolved.getPropertyValue("type");
    if (StringUtils.isNotBlank(componentType)) {
      IBuildable buildable = build(controller, resolved);
      return buildable;
    }

    return null;
  }


  /**
   * Resolve the model with the given identifier.
   *
   * @param controller
   * @param id
   * @return VLViewComponentXML
   */
  public static Optional resolveOptionalModel(AbstractViewController controller, String id) {
    VLViewComponentXML componentXML = resolveModel(controller, id);
    if (componentXML == null) {
      return Optional.empty();
    }
    return Optional.of(componentXML);
  }


  /**
   * Resolve the model with the given identifier.
   *
   * @param controller
   * @param id
   * @return VLViewComponentXML
   */
  public static VLViewComponentXML resolveModel(AbstractViewController controller, String id) {
    Assert.notNull(controller);
    Assert.notNull(id);

    ////LOG.trace(MessageFormat.format("Searching for component with identifier {0}", id));
    VLViewComponentXML result = getFromCache(id).orElse(null);

    if (result == null) {

      //LOG.trace(MessageFormat.format("Component with identifier {0} not found from cache, seraching from local config", id));

      result = getFromLocalConfig(controller, id).orElse(null);
      if (result == null) {

        //LOG.trace(MessageFormat.format("Component with identifier {0} not found from local config, searching from root structure config", id));

        if (controller.getRootStructure() != null) {
          //LOG.trace(MessageFormat.format("Root structure is {0}", controller.getRootStructure().getClass()));
          result = getFromRootStructureConfig(controller.getRootStructure(), id).orElse(null);
        }

        if (result == null) {
          //LOG.trace(MessageFormat.format("Component with identifier {0} not found from root structure config, searching from global config", id));
          result = getFromGlobalConfig(id).orElse(null);
        }
      }
    }

    if (result == null) {
      //LOG.warn(MessageFormat.format("Component with identifier {0} not found at all!!", id));
      return null;
    } else {
      String criteria = result.getCriteria();
      if (StringUtils.isNotBlank(criteria)) {
        boolean crit = controller.evaluateFilter(result);
        if (!crit) {
          return null;
        }
      }
    }

    return result;
  }


  /**
   * @param type
   * @param controller
   * @param wizardConfiguration
   * @return IBuildable
   */
  public static IBuildable build(AbstractViewController controller, VLViewComponentXML configuration) {
    String componentType = configuration.getPropertyValue("type");
    if (StringUtils.isNotBlank(componentType)) {
      IBuildable buildable = build(componentType, controller, configuration);
      return buildable;
    }

    return null;
  }


  /**
   * @param type
   * @param controller
   * @param wizardConfiguration
   * @return IBuildable
   */
  public static IBuildable build(String type, AbstractViewController controller, VLViewComponentXML configuration) {
    IBuildable buildable = (IBuildable) Services.getBean(type);
    if(buildable == null) {
      throw new RuntimeException("Buildable with type "+ type + " not provided in application context" );
    }

    buildable.buildFrom(controller, configuration);
    return buildable;
  }


  /**
   * Components are list of referenced components to resolver in this controller or parent controller.
   *
   * @param components
   * @param controller
   * @return List
   */
  public static List resolveDefinitions(final AbstractViewController controller, final List refs) {
    Assert.notNull(controller);
    Assert.notNull(refs);

    List result = new ArrayList<>();
    if (!refs.isEmpty()) {
      for(VLViewComponentXML e : refs) {
        VLViewComponentXML optional = resolveDefinition(controller, e).orElse(null);
        if (optional != null) result.add(optional);
        //else System.out.println("Not resolved configuration component -> " + e.getReference());
      }
    }

    return result;
  }


  /**
   * Resolve the model with the given identifier. Sometimes, the source {@link VLViewComponentXML}
   * holds some attributes to copied in the destination.
   *
   * @param controller
   * @param ref
   * @return VLViewComponentXML
   */
  public static Optional resolveDefinition(AbstractViewController controller, VLViewComponentXML ref) {
    Assert.notNull(controller);
    Assert.notNull(ref);

    // sometimes holds processor or controller not reference to something to
    // build
    if (StringUtils.isNotBlank(ref.getReference())) {
      Optional optional = resolveDefinition(controller, ref.getReference());
      optional.ifPresent(solved -> {
        copySourcesAttributes(ref, solved);
      });

      return optional;
    }

    return Optional.empty();
  }


  protected static void copySourcesAttributes(VLViewComponentXML referenced, VLViewComponentXML resolved) {

    if(referenced.getVisibleIf() != null)
      resolved.setVisibleIf(referenced.getVisibleIf());

    if(referenced.getCriteria() != null && resolved.getCriteria() == null)
      resolved.setCriteria(referenced.getCriteria());

    if(referenced.getSeparatorAfter() != null)
      resolved.setSeparatorAfter(referenced.getSeparatorAfter());

    if(referenced.getResponsiveOrder() != null)
      resolved.setResponsiveOrder(referenced.getResponsiveOrder());

    if(referenced.getMasterColumn() != null)
      resolved.setMasterColumn(referenced.getMasterColumn());

    if (StringUtils.isNotBlank(referenced.getDefaultButton())) {
      if(!resolved.getProperties().containsKey("default"))
        resolved.getProperties().put("default", referenced.getDefaultButton());
    }

    if (referenced.getComponentById(VALIDATOR) != null) {
      if (resolved.getComponentById(VALIDATOR) != null) {
        final Optional comp = resolved.getComponentById(VALIDATOR);
        comp.ifPresent(c -> resolved.getSubcomponents().remove(c));
      }

      final Optional d = referenced.getComponentById(VALIDATOR);
      d.ifPresent(f -> resolved.getSubcomponents().add(f));
    }
  }


  /**
   * Resolve all subcomponents from toResolveActionsCfg. These subcomponents must have not empty
   * reference. Only subcomponents with non empty reference attribute will be treated.
   *
   * @param from
   * @param rootComponent
   */
  public static List resolveReferencedSubComponents(final AbstractViewController controller, final VLViewComponentXML from) {
    Assert.notNull(controller);
    Assert.notNull(from);

    if (from.hasSubComponent()) {
      return resolveDefinitions(controller, from.getSubcomponents());
    }
    return new ArrayList<>();
  }


  /**
   * Resolve the model with the given identifier.
   *
   * @param controller
   * @param id
   * @return VLViewComponentXML
   */
  public static Optional resolveDefinition(AbstractViewController controller, String id) {
    Assert.notNull(controller);
    Assert.notNull(id);

    //LOG.trace(MessageFormat.format("Searching component with identifier {0} from local config", id));
    VLViewComponentXML result = getFromLocalConfig(controller, id).orElse(null);

    if (result == null) {
      //LOG.trace(MessageFormat.format("Component with identifier {0} not found from local config, searching from root structure config", id));

      if (controller.getRootStructure() != null) {
        //LOG.trace(MessageFormat.format("Root structure is {0}", controller.getRootStructure().getClass()));
        result = getFromRootStructureConfig(controller.getRootStructure(), id).orElse(null);
      }

      if (result == null) {
        //LOG.trace(MessageFormat.format("Searching for component with identifier {0} form cache", id));
        result = getFromCache(id).orElse(null);

        if (result == null) {
          //LOG.trace(MessageFormat.format("Component with identifier {0} not found from cache, searching from global config", id));
          result = getFromGlobalConfig(id).orElse(null);

          if (result != null) {
            if(!CACHE.containsKey(result.getId()))
              CACHE.put(result.getId(), result);
          }
        }
      }
    }

    if (result == null) {
      //LOG.warn(MessageFormat.format("Component with identifier {0} not found at all!!", id));
      //System.out.println("WARNING ---- Component with identifier (" + id +") not found at all!!");
      return Optional.empty();
    } else {
      String criteria = result.getCriteria();
      if (StringUtils.isNotBlank(criteria)) {
        boolean crit = controller.evaluateFilter(result);
        if (!crit) {
          //System.out.println(" ----> Control hide (" + id + ") by criteria : " + criteria);
          return Optional.empty();
        }
        else {
          //System.out.println(" ++++> Control show (" + id + ") by criteria : " + criteria);
        }
      }
      else {
        //System.out.println(" ******> Control without criteria (" + id + ")");
      }
    }

    return Optional.of(result);
  }


  private static Optional getFromLocalConfig(AbstractViewController controller, String id) {
    VLViewConfigXML configXML = controller.viewContext().getViewConfig();
    if (configXML.getComponentById(id).isPresent()) {
      return configXML.getComponentById(id);
    }

    if (controller.getCommonComponents() != null) {
      if (controller.getCommonComponents().getComponent(id) != null) {
        return Optional.of(controller.getCommonComponents().getComponent(id));
      }
    }

    if (controller.getParent() != null) {
      VLViewConfigXML cfg = controller.getParent().viewContext().getViewConfig();
      return cfg.getComponentById(id);
    }

    return Optional.empty();
  }


  private static Optional getFromRootStructureConfig(RootStructureController rootController, String id) {
    VLViewConfigXML configXML = rootController.viewContext().getViewConfig();
    if (configXML.getComponentById(id).isPresent()) {
      return configXML.getComponentById(id);
    }

    if (rootController.getCommonComponents() != null) {
      if (rootController.getCommonComponents().getComponent(id) != null) {
        return Optional.of(rootController.getCommonComponents().getComponent(id));
      }
    }

    return Optional.empty();
  }


  private static Optional getFromCache(String id) {
    return Optional.empty();
  }


  public static Optional getFromGlobalConfig(String id) {
    if (ViewStructure.isViewConfigOffLine()) {
      VLViewComponentXML comp =  Services.getCompFromGlobalConfig(id);
      return Optional.ofNullable(comp);
    }

    return Optional.empty();
  }


  public static boolean isAttributeMandatory(final VLViewComponentXML attrConfig) {
    final VLViewComponentXML displayConfig = attrConfig.getNullableComponentById(XMLConstants.VALIDATION_CONFIG);
    boolean mandatory = false;
    if (displayConfig != null) {
      mandatory = displayConfig.getBooleanProperty(XMLConstants.MANDATORY);
    }

    return mandatory;
  }


  public static VLViewComponentXML resolveComponent(VLViewComponentXML component, String id) {
    return component.getNullableComponentById(id);
  }


  /**
   * Generates a single material button
   *
   * @param controller
   * @param config
   * @return Null or Node
   */
  public static Node buildMaterialButton(AbstractViewController controller, VLViewComponentXML config) {
    if (config != null) {
      SimpleButton button = new SimpleButton();
      button.buildFrom(controller, config);
      button.getDisplay().getStyleClass().add("button-material");
      return button.getDisplay();
    }

    return null;
  }


  /**
   * Builds a component. If the component declares a {@link IComponentProcessor}, this processor will
   * be called.
   * 

* If the components declares a contentImpl as a {@link IBuildable}, this {@link IBuildable} will be * builded. * * @param controller * @param configuration * @return {@link Node} or Null */ public static Node buildFromProcessor(AbstractViewController controller, VLViewComponentXML configuration) { // content can be processed either from processor IComponentProcessor processor = (IComponentProcessor) Services.getBean(configuration.getProcessor()); if (processor != null) { if (controller instanceof StandardViewController) { Object element = processor.processElement(controller, configuration); ((StandardViewController) controller).processedElement(element); } Node processed = processor.process(controller, configuration); return processed; } // or given an implementation else { String contentImpl = configuration.getPropertyValue("contentImpl"); if (StringUtils.isNotBlank(contentImpl)) { IBuildable buildable = (IBuildable) Services.getBean(contentImpl); buildable.buildFrom(controller, configuration); return buildable.getDisplay(); } } return null; } /** * Builds a component. If the component declares a {@link IComponentProcessor}, this processor will * be called. *

* If the components declares a contentImpl as a {@link IBuildable}, this {@link IBuildable} will be * builded. * * @param controller * @param configuration * @return {@link Node} or Null */ public static Node buildFromProcessor(AbstractViewController controller, VLViewComponentXML configuration, IForwardEditor forwardEditor) { if (forwardEditor == null) { return buildFromProcessor(controller, configuration); } // content can be processed either from processor IComponentProcessor processor = (IComponentProcessor) Services.getBean(configuration.getProcessor()); if (processor != null && processor instanceof IForwardEditableFieldsetsProcessor) { Node processed = ((IForwardEditableFieldsetsProcessor) processor).process(controller, configuration, forwardEditor); return processed; } else if (processor != null) { Node processed = processor.process(controller, configuration); return processed; } // or given an implementation else { String contentImpl = configuration.getPropertyValue("contentImpl"); if (StringUtils.isNotBlank(contentImpl)) { IBuildable buildable = (IBuildable) Services.getBean(contentImpl); buildable.buildFrom(controller, configuration); return buildable.getDisplay(); } } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy