/** * Copyright 2014-2017 Linagora, Université Joseph Fourier, Floralis * * The present code is developed in the scope of the joint LINAGORA - * Université Joseph Fourier - Floralis research program and is designated * as a "Result" pursuant to the terms and conditions of the LINAGORA * - Université Joseph Fourier - Floralis research program. Each copyright * holder of Results enumerated here above fully & independently holds complete * ownership of the complete Intellectual Property rights applicable to the whole * of said Results, and may freely exploit it in any manner which does not infringe * the moral rights of the other copyright holders. * * 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. */ package net.roboconf.core.model.helpers; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Map; import java.util.logging.Logger; import net.roboconf.core.Constants; import net.roboconf.core.model.beans.Component; import net.roboconf.core.model.beans.Import; import net.roboconf.core.model.beans.ImportedVariable; import net.roboconf.core.model.beans.Instance; import net.roboconf.core.utils.Utils; /** * A set of helpers for instance imports. * @author Vincent Zurczak - Linagora */ public final class ImportHelpers { /** * Constructor. */ private ImportHelpers() { // nothing } /** * Determines whether an instance has all the imports it needs. * <p> * Master of Obvious said:<br> * By definition, optional imports are not considered to be required. * </p> * * @param instance a non-null instance * @param logger a logger (can be null) * @return true if all its (mandatory) imports are resolved, false otherwise */ public static boolean hasAllRequiredImports( Instance instance, Logger logger ) { boolean haveAllImports = true; for( String facetOrComponentName : VariableHelpers.findPrefixesForMandatoryImportedVariables( instance )) { Collection<Import> imports = instance.getImports().get( facetOrComponentName ); if( imports != null && ! imports.isEmpty()) continue; haveAllImports = false; if( logger != null ) logger.fine( InstanceHelpers.computeInstancePath( instance ) + " is still missing dependencies '" + facetOrComponentName + ".*'." ); break; } return haveAllImports; } /** * Builds an import where only the right variables are contained. * <p> * As an example, if a component imports Toto.var1 and Toto.var2, and that * Toto exports var1, var2 and var3, then the component only needs to see * var1 and var2 in its imports. No need to keep var3. * </p> * <p> * This method also deals with wild card imports. * </p> * * @param instanceThatUseTheImport the instance that will use the import * @param exportingInstancePath the path of the instance that exports variables * @param exportingInstanceComponent the component name of the instance that exports variables * @param exportedVariables the variables to add in the imports * @return a non-null import */ public static Import buildTailoredImport( Instance instanceThatUseTheImport, String exportingInstancePath, String exportingInstanceComponent, Map<String,String> exportedVariables ) { Import imp = new Import( exportingInstancePath, exportingInstanceComponent ); if( exportedVariables != null && ! exportedVariables.isEmpty()) { Component comp = instanceThatUseTheImport.getComponent(); for( ImportedVariable var : ComponentHelpers.findAllImportedVariables( comp ).values()) { String importedVariable = var.getName(); // Deal with imports if( var.getName().endsWith( "." + Constants.WILDCARD )) { String prefix = VariableHelpers.parseVariableName( importedVariable ).getKey(); for( Map.Entry<String,String> entry : exportedVariables.entrySet()) { String exportedVariable = entry.getKey(); if( Utils.isEmptyOrWhitespaces( exportedVariable )) continue; String exportedVarPrefix = VariableHelpers.parseVariableName( exportedVariable ).getKey(); if( prefix.equals( exportedVarPrefix )) imp.getExportedVars().put( entry.getKey(), entry.getValue()); } } // Deal with the usual (and most simple!) case else if( exportedVariables.containsKey( importedVariable )) imp.getExportedVars().put( importedVariable, exportedVariables.get( importedVariable )); } } return imp; } /** * Adds an import to an instance (provided this import was not already set). * @param instance the instance whose imports must be updated * @param componentOrFacetName the component or facet name associated with the import * @param imp the import to add */ public static void addImport( Instance instance, String componentOrFacetName, Import imp ) { Collection<Import> imports = instance.getImports().get( componentOrFacetName ); if(imports == null) { imports = new LinkedHashSet<Import> (); instance.getImports().put( componentOrFacetName, imports ); } if( ! imports.contains( imp )) imports.add( imp ); } /** * Updates the imports of an instance with new values. * @param instance the instance whose imports must be updated * @param variablePrefixToImports the new imports (can be null) */ public static void updateImports( Instance instance, Map<String,Collection<Import>> variablePrefixToImports ) { instance.getImports().clear(); if( variablePrefixToImports != null ) instance.getImports().putAll( variablePrefixToImports ); } /** * Finds a specific import from the path of the instance that exports it. * @param imports a collection of imports (that can be null) * @param exportingInstancePath the path of the exporting instance * @return an import, or null if none was found */ public static Import findImportByExportingInstance( Collection<Import> imports, String exportingInstancePath ) { Import result = null; if( imports != null && exportingInstancePath != null ) { for( Import imp : imports ) { if( exportingInstancePath.equals( imp.getInstancePath())) { result = imp; break; } } } return result; } }