Skip to content

Commit

Permalink
(#21): adds pathway view (recipe)
Browse files Browse the repository at this point in the history
  • Loading branch information
andi-huber committed Mar 10, 2024
1 parent 22df287 commit 66c258a
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@

import lombok.RequiredArgsConstructor;

import dita.commons.services.lookup.ForeignKeyLookupService;
import dita.globodiet.dom.params.food_list.Food;
import dita.globodiet.dom.params.pathway.QuantificationMethodPathwayForFoodGroup;
import dita.globodiet.manager.services.food.FoodQuantificationHelperService;
import dita.globodiet.manager.util.QuantificationMethodPathwayKey;

/**
* With {@link QuantificationMethodPathwayForFoodGroup} a set of quantification methods is defined
Expand All @@ -53,7 +53,6 @@
@RequiredArgsConstructor
public class Food_effectiveQuantificationMethodPathways {

@Inject private ForeignKeyLookupService foreignKeyLookupService;
@Inject private FoodQuantificationHelperService foodQuantificationHelperService;

protected final Food mixee;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import dita.globodiet.dom.params.pathway.QuantificationMethodPathwayForFoodGroup.RawOrCookedAsConsumed;
import dita.globodiet.manager.editing.recipe.Recipe_addStandardUnit;
import dita.globodiet.manager.util.AsciiDocUtils;
import dita.globodiet.manager.util.QuantificationMethodPathwayKey;

/**
* @see Recipe_addStandardUnit
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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 dita.globodiet.manager.editing.recipe;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.inject.Inject;

import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.applib.annotation.CollectionLayout;
import org.apache.causeway.applib.annotation.MemberSupport;
import org.apache.causeway.applib.annotation.Where;

import lombok.RequiredArgsConstructor;

import dita.globodiet.dom.params.pathway.QuantificationMethodPathwayForRecipeGroup;
import dita.globodiet.dom.params.recipe_list.Recipe;
import dita.globodiet.manager.services.recipe.RecipeQuantificationHelperService;
import dita.globodiet.manager.util.QuantificationMethodPathwayKey;

/**
* With {@link QuantificationMethodPathwayForRecipeGroup} a set of quantification methods is defined
* for a specific recipe group.
* Optionally, for an individual recipe, only a subset of those methods can be selected.
*/
@Collection
@CollectionLayout(
hidden = Where.ALL_TABLES,
sequence = "0.2",
describedAs = "Quantification Method Pathways in effect associated with this individual recipe.\n\n"
+ "With QuantificationMethodForRecipeGroup (table QM_RCLAS) a set of methods is defined "
+ "for a specific recipe group.\n\n"
+ "Optionally, for an individual recipe, only a subset of those methods can be selected "
+ "using QuantificationMethodPathwayForRecipe (table QM_RECIP).")
@RequiredArgsConstructor
public class Recipe_effectiveQuantificationMethodPathways {

@Inject private RecipeQuantificationHelperService recipeQuantificationHelperService;

protected final Recipe mixee;

@MemberSupport
public List<QuantificationMethodPathwayForRecipeGroup> coll() {

var grouping = recipeQuantificationHelperService.effectiveGroupingUsedForQuantificationPathway(mixee);

var quantificationMethodPathwayAsDefinedByRecipeClassification = recipeQuantificationHelperService
.effectiveQuantificationMethodPathwayForRecipeClassification(grouping);

// filter by selected at food level (Dependent Quantification Method Pathway For Recipe mapped by Recipe)
var quantificationMethodPathwayForRecipe = recipeQuantificationHelperService.listQuantificationMethodPathwayForRecipe(mixee);
if(quantificationMethodPathwayForRecipe.isEmpty()) {
return quantificationMethodPathwayAsDefinedByRecipeClassification;
}
final Set<QuantificationMethodPathwayKey> selectedKeys = quantificationMethodPathwayForRecipe.stream()
.map(QuantificationMethodPathwayKey::valueOf)
.collect(Collectors.toSet());
return quantificationMethodPathwayAsDefinedByRecipeClassification.stream()
.filter(qmp->selectedKeys.contains(QuantificationMethodPathwayKey.valueOf(qmp)))
//TODO ordering?
.toList();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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 dita.globodiet.manager.editing.recipe;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.inject.Inject;

import org.apache.causeway.applib.annotation.Collection;
import org.apache.causeway.applib.annotation.CollectionLayout;
import org.apache.causeway.applib.annotation.MemberSupport;
import org.apache.causeway.applib.annotation.Where;

import lombok.RequiredArgsConstructor;

import dita.commons.services.lookup.ForeignKeyLookupService;
import dita.globodiet.dom.params.pathway.FacetDescriptorPathwayForRecipe;
import dita.globodiet.dom.params.pathway.FacetDescriptorPathwayForRecipeGroup;
import dita.globodiet.dom.params.recipe_description.RecipeDescriptor;
import dita.globodiet.dom.params.recipe_list.Recipe;
import dita.globodiet.manager.services.recipe.RecipeFacetHelperService;

/**
* With {@link FacetDescriptorPathwayForRecipeGroup} a set of facet/descriptors is defined
* for a specific food classification.
* Optionally, for an individual recipe, only a subset of those facets can be selected.
*/
@Collection
@CollectionLayout(
hidden = Where.ALL_TABLES,
sequence = "0.1",
describedAs = "Recipe Descriptors in effect associated with this individual recipe.\n\n"
+ "With FacetDescriptorPathwayForRecipeGroup (table R_GROUPFAC) a set of facet/descriptors is defined "
+ "for a specific recipe classification.\n\n"
+ "Optionally, for an individual recipe, only a subset of those facets can be selected "
+ "using FacetDescriptorPathwayForRecipe (table R_RCPFAEX).\n\n"
+ "Entries are ordered by facet-display-order and then descriptor-display-order. "
+ "(However, column facet-display-order is duplicated in FacetDescriptorPathwayForRecipe (table R_RCPFAEX),"
+ "where its yet unclear whether that is inferred from or actually overrides the one defined at group level.)")
@RequiredArgsConstructor
public class Recipe_effectiveRecipeDescriptors {

@Inject private ForeignKeyLookupService foreignKeyLookupService;
@Inject private RecipeFacetHelperService recipeFacetHelperService;

protected final Recipe mixee;

@MemberSupport
public List<RecipeDescriptor> coll() {

var recipeDescriptorsAsDefinedByRecipeClassification = recipeFacetHelperService
.effectiveFacetDescriptorPathwayForRecipeClassificationHonoringDisplayOrder(mixee)
.stream()
.map(this::recipeDescriptor)
.toList();

// filter by individual recipe's subset of facets (if any)
var facetDescriptorPathwayForRecipe = recipeFacetHelperService.listFacetDescriptorPathwayForRecipe(mixee);
if(facetDescriptorPathwayForRecipe.isEmpty()) {
return recipeDescriptorsAsDefinedByRecipeClassification;
}
final Set<String> facetCodeSubset = facetDescriptorPathwayForRecipe.stream()
.map(FacetDescriptorPathwayForRecipe::getSelectedRecipeFacetCode)
.collect(Collectors.toSet());
return recipeDescriptorsAsDefinedByRecipeClassification.stream()
.filter(recipeDescriptor->facetCodeSubset.contains(recipeDescriptor.getRecipeFacetCode()))
//TODO facetDescriptorPathwayForRecipe have their own ordering
//is this inferred from or an override of the group level?
.toList();
}

// -- HELPER

private RecipeDescriptor recipeDescriptor(final FacetDescriptorPathwayForRecipeGroup groupPathway) {
return foreignKeyLookupService.unique(new RecipeDescriptor.SecondaryKey(
groupPathway.getRecipeFacetCode(),
groupPathway.getRecipeDescriptorCode()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* 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 dita.globodiet.manager.editing.recipe;

import java.util.HashSet;

import jakarta.inject.Inject;

import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.applib.annotation.ActionLayout.Position;
import org.apache.causeway.applib.annotation.LabelPosition;
import org.apache.causeway.applib.annotation.MemberSupport;
import org.apache.causeway.applib.annotation.ObjectSupport;
import org.apache.causeway.applib.annotation.PropertyLayout;
import org.apache.causeway.applib.services.factory.FactoryService;
import org.apache.causeway.valuetypes.asciidoc.applib.value.AsciiDoc;

import lombok.RequiredArgsConstructor;

import dita.commons.services.lookup.ForeignKeyLookupService;
import dita.globodiet.dom.params.recipe_description.RecipeFacet;
import dita.globodiet.dom.params.recipe_list.Recipe;
import dita.globodiet.manager.util.AsciiDocUtils;
import dita.globodiet.manager.util.QuantificationMethodPathwayKey;

/**
* @see Recipe_addStandardUnit
*/
@Action
@ActionLayout(
fieldSetId="details",
sequence = "1",
position = Position.PANEL,
cssClass = "btn-success",
cssClassFa = "solid fa-binoculars",
describedAs = "Preview what happens during an interview when selecting this recipe.")
@RequiredArgsConstructor
public class Recipe_inspectPathway {

@Inject private FactoryService factoryService;
@Inject private ForeignKeyLookupService foreignKeyLookupService;

private final static String PHYSICAL_STATE_FACET_CODE = "02"; //TODO convert to configuration option

protected final Recipe mixee;

@MemberSupport
public PathwayView act() {

return new PathwayView(
"Pathway View for Recipe - " + mixee.title(),
AsciiDocUtils.yamlBlock("Facet/Descriptor Pathway", "Constraints: none", facetDescriptorPathwayAsYaml()),
AsciiDocUtils.yamlBlock("Quantification Pathway", "Constraints: none", quantificationPathwayAsYaml()));
}

public static record PathwayView(
String titleString,
@PropertyLayout(labelPosition = LabelPosition.NONE) AsciiDoc facetDescriptorPathway,
@PropertyLayout(labelPosition = LabelPosition.NONE) AsciiDoc quantificationPathway) {
@ObjectSupport String title() {
return titleString();
}
}

// -- HELPER

private String facetDescriptorPathwayAsYaml() {
var yaml = new StringBuilder();
yaml.append("recipe: " + mixee.title()).append("\n");

var effectiveGrouping = factoryService.mixin(Recipe_effectiveGroupingUsedForFacetDescriptorPathway.class, mixee).prop();
if(effectiveGrouping==null) {
yaml.append("effectiveGrouping: not found").append("\n");
return yaml.toString();
}
yaml.append("effectiveGrouping: ")
.append(effectiveGrouping.title())
.append("\n");

var effectiveRecipeDescriptors = factoryService.mixin(Recipe_effectiveRecipeDescriptors.class, mixee).coll();
var facetsSeenBefore = new HashSet<String>();
effectiveRecipeDescriptors.forEach(fd->{
if(facetsSeenBefore.add(fd.getRecipeFacetCode())) {
var facet = foreignKeyLookupService.unique(new RecipeFacet.SecondaryKey(fd.getRecipeFacetCode()));
yaml.append(" -facet: ").append(facet.title()).append("\n");
}
yaml.append(" -descriptor: ").append(fd.title()).append("\n");
});
return yaml.toString();
}

private String quantificationPathwayAsYaml() {
var yaml = new StringBuilder();
yaml.append("Recipe: " + mixee.title()).append("\n");

var effectiveGrouping = factoryService.mixin(Recipe_effectiveGroupingUsedForQuantificationPathway.class, mixee).prop();
if(effectiveGrouping==null) {
yaml.append("effectiveGrouping: not found").append("\n");
return yaml.toString();
}
yaml.append("effectiveGrouping: ")
.append(effectiveGrouping.title())
.append("\n");

var effectiveQuantificationMethodPathways = factoryService.mixin(Recipe_effectiveQuantificationMethodPathways.class, mixee).coll();
effectiveQuantificationMethodPathways.stream()
.forEach(qmPathway->{
yaml.append(" -quantificationMethod: ").append(qmPathway.getQuantificationMethod()).append("\n");
yaml.append(" comment: ").append(qmPathway.getComment()).append("\n");
var qmpKey = QuantificationMethodPathwayKey.valueOf(qmPathway);
if(qmpKey.quantificationMethod().isPhotoOrShape()) {
yaml.append(" photoOrShape: ").append(qmPathway.getPhotoOrShapeCode()).append("\n");
}
});

return yaml.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package dita.globodiet.manager.editing.food;
package dita.globodiet.manager.util;

import org.springframework.lang.Nullable;

Expand Down Expand Up @@ -54,13 +54,15 @@ public static QuantificationMethod valueOf(final QuantificationMethodPathwayForR
return QuantificationMethod.valueOf(qm.name());
}

boolean isPhotoOrShape() {
public boolean isPhotoOrShape() {
return this == PHOTO
|| this == SHAPE;
}

}

// -- FOOD

public static QuantificationMethodPathwayKey valueOf(final QuantificationMethodPathwayForFood qmp) {
return new QuantificationMethodPathwayKey(
QuantificationMethod.valueOf(qmp.getQuantificationMethod()),
Expand All @@ -73,4 +75,18 @@ public static QuantificationMethodPathwayKey valueOf(final QuantificationMethodP
qmp.getPhotoOrShapeCode());
}

// -- RECIPE

public static QuantificationMethodPathwayKey valueOf(final QuantificationMethodPathwayForRecipe qmp) {
return new QuantificationMethodPathwayKey(
QuantificationMethod.valueOf(qmp.getQuantificationMethod()),
qmp.getPhotoOrShapeCode());
}

public static QuantificationMethodPathwayKey valueOf(final QuantificationMethodPathwayForRecipeGroup qmp) {
return new QuantificationMethodPathwayKey(
QuantificationMethod.valueOf(qmp.getQuantificationMethod()),
qmp.getPhotoOrShapeCode());
}

}

0 comments on commit 66c258a

Please sign in to comment.