001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.core.model; 007 008import java.util.Collection; 009import java.util.List; 010import java.util.function.Predicate; 011import java.util.stream.Collectors; 012import java.util.stream.Stream; 013 014import dev.metaschema.core.qname.IEnhancedQName; 015import dev.metaschema.core.util.ObjectUtils; 016import edu.umd.cs.findbugs.annotations.NonNull; 017import edu.umd.cs.findbugs.annotations.Nullable; 018 019/** 020 * The API for accessing information about a given Metaschema module. 021 * <p> 022 * A Metaschem module may import another Metaschema module. This import graph 023 * can be accessed using {@link #getImportedModules()}. 024 * <p> 025 * Global scoped Metaschema definitions can be accessed using 026 * {@link #getScopedAssemblyDefinitionByName(Integer)}, 027 * {@link #getScopedFieldDefinitionByName(Integer)}, and 028 * {@link #getScopedFlagDefinitionByName(IEnhancedQName)}. These methods take 029 * into consideration the import order to provide the global definitions that 030 * are in scope within the given Metschema module. 031 * <p> 032 * Global scoped definitions exported by this Metaschema module, available for 033 * use by importing Metaschema modules, can be accessed using 034 * {@link #getExportedAssemblyDefinitions()}, 035 * {@link #getExportedFieldDefinitions()}, and 036 * {@link #getExportedFlagDefinitions()}. 037 * <p> 038 * Global scoped definitions defined directly within the given Metaschema module 039 * can be accessed using {@link #getAssemblyDefinitions()}, 040 * {@link #getFieldDefinitions()}, and {@link #getFlagDefinitions()}, along with 041 * similarly named access methods. 042 * 043 * @param <M> 044 * the imported module Java type 045 * @param <D> 046 * the model definition Java type 047 * @param <FL> 048 * the flag definition Java type 049 * @param <FI> 050 * the field definition Java type 051 * @param <A> 052 * the assembly definition Java type 053 */ 054public interface IModuleExtended< 055 M extends IModuleExtended<M, D, FL, FI, A>, 056 D extends IModelDefinition, 057 FL extends IFlagDefinition, 058 FI extends IFieldDefinition, 059 A extends IAssemblyDefinition> extends IModule { 060 061 /** 062 * Get a filter that will match all definitions that are not locally defined. 063 * 064 * @param <DEF> 065 * the type of definition 066 * @return a predicate implementing the filter 067 */ 068 static <DEF extends IDefinition> Predicate<DEF> allNonLocalDefinitions() { 069 return definition -> definition.getModuleScope() == IDefinition.ModuleScope.PUBLIC 070 || definition.getModelType() == ModelType.ASSEMBLY 071 && ((IAssemblyDefinition) definition).isRoot(); 072 } 073 074 /** 075 * Get a filter that will match all definitions that are root assemblies. 076 * 077 * @param <DEF> 078 * the type of definition 079 * @return a predicate implementing the filter 080 */ 081 static <DEF extends IDefinition> Predicate<DEF> allRootAssemblyDefinitions() { 082 return definition -> definition.getModelType() == ModelType.ASSEMBLY 083 && ((IAssemblyDefinition) definition).isRoot(); 084 } 085 086 @Override 087 @NonNull 088 List<? extends M> getImportedModules(); 089 090 @Override 091 @Nullable 092 M getImportedModuleByShortName(String name); 093 094 @Override 095 @NonNull 096 Collection<FL> getFlagDefinitions(); 097 098 @Override 099 @Nullable 100 FL getFlagDefinitionByName(@NonNull IEnhancedQName name); 101 102 @Override 103 @NonNull 104 Collection<A> getAssemblyDefinitions(); 105 106 @Override 107 @Nullable 108 A getAssemblyDefinitionByName(@NonNull Integer name); 109 110 @Override 111 @NonNull 112 Collection<FI> getFieldDefinitions(); 113 114 @Override 115 @Nullable 116 FI getFieldDefinitionByName(@NonNull Integer name); 117 118 @Override 119 @SuppressWarnings("unchecked") 120 @NonNull 121 default List<D> getAssemblyAndFieldDefinitions() { 122 return ObjectUtils.notNull( 123 Stream.concat( 124 (Stream<D>) getAssemblyDefinitions().stream(), 125 (Stream<D>) getFieldDefinitions().stream()) 126 .collect(Collectors.toList())); 127 } 128 129 @Override 130 @Nullable 131 default A getScopedAssemblyDefinitionByName(@NonNull Integer name) { 132 // first try local/global top-level definitions from current metaschema module 133 A retval = getAssemblyDefinitionByName(name); 134 if (retval == null) { 135 // try global definitions from imported Metaschema modules 136 retval = getExportedAssemblyDefinitionByName(name); 137 } 138 return retval; 139 } 140 141 @Override 142 @Nullable 143 default FI getScopedFieldDefinitionByName(@NonNull Integer name) { 144 // first try local/global top-level definitions from current metaschema module 145 FI retval = getFieldDefinitionByName(name); 146 if (retval == null) { 147 // try global definitions from imported metaschema modules 148 retval = getExportedFieldDefinitionByName(name); 149 } 150 return retval; 151 } 152 153 @Override 154 @Nullable 155 default FL getScopedFlagDefinitionByName(@NonNull IEnhancedQName name) { 156 // first try local/global top-level definitions from current metaschema module 157 FL retval = getFlagDefinitionByName(name); 158 if (retval == null) { 159 // try global definitions from imported metaschema modules 160 retval = getExportedFlagDefinitionByName(name); 161 } 162 return retval; 163 } 164 165 @Override 166 @NonNull 167 default Collection<? extends A> getExportedRootAssemblyDefinitions() { 168 return ObjectUtils.notNull(getExportedAssemblyDefinitions().stream() 169 .filter(allRootAssemblyDefinitions()) 170 .collect(Collectors.toList())); 171 } 172 173 @Override 174 @NonNull 175 default Collection<? extends A> getRootAssemblyDefinitions() { 176 return ObjectUtils.notNull(getAssemblyDefinitions().stream() 177 .filter(allRootAssemblyDefinitions()) 178 .collect(Collectors.toList())); 179 } 180 181 @Override 182 @NonNull 183 Collection<? extends FL> getExportedFlagDefinitions(); 184 185 @Override 186 @Nullable 187 FL getExportedFlagDefinitionByName(IEnhancedQName name); 188 189 @Override 190 @NonNull 191 Collection<? extends FI> getExportedFieldDefinitions(); 192 193 @Override 194 @Nullable 195 FI getExportedFieldDefinitionByName(Integer name); 196 197 @Override 198 @NonNull 199 Collection<? extends A> getExportedAssemblyDefinitions(); 200 201 @Override 202 @Nullable 203 A getExportedAssemblyDefinitionByName(Integer name); 204}