/******************************************************************************* * Copyright (c) 2015 ARM Ltd. and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * ARM Ltd and ARM Germany GmbH - Initial API and implementation *******************************************************************************/ package com.arm.cmsis.pack.rte.components; import java.util.Collection; import java.util.LinkedList; import com.arm.cmsis.pack.common.CmsisConstants; import com.arm.cmsis.pack.data.ICpComponent; import com.arm.cmsis.pack.data.ICpItem; import com.arm.cmsis.pack.data.ICpTaxonomy; import com.arm.cmsis.pack.enums.EComponentAttribute; import com.arm.cmsis.pack.enums.EEvaluationResult; import com.arm.cmsis.pack.info.ICpComponentInfo; import com.arm.cmsis.pack.rte.RteConstants; import com.arm.cmsis.pack.rte.dependencies.IRteDependency; /** * Class that represents component taxonomy level that can be selected.<br> * Contain collection of component variant items. */ public class RteComponent extends RteComponentItem implements IRteComponent { protected int fnSelected = 0; // number of selected instances protected boolean fbBootStrap = false; // flag indicating that at least one of the component variants is a bootstrap one protected boolean fbGenerated = false; // one of the component variants is generated public RteComponent(IRteComponentItem parent, String name) { super(parent, name); fComponentAttribute = EComponentAttribute.CVARIANT; } @Override public boolean isSelected() { return fnSelected > 0; } @Override public int getSelectedCount() { return fnSelected; } @Override public boolean isGenerated() { return fbGenerated; } @Override public boolean isBootStrap() { return fbBootStrap; } @Override public boolean isUseLatestVersion() { if(hasBundle()) { return getParentBundle().isUseLatestVersion(); } return super.isUseLatestVersion(); } @Override public String getEffectiveName() { String name = super.getEffectiveName(); if(name.isEmpty()) { IRteComponentGroup g = getParentGroup(); if(g != null) { name = g.getName(); } } return name; } @Override public boolean setSelected(int count) { if(fnSelected == count) { return false; } fnSelected = count; return true; } @Override public int getMaxInstanceCount() { ICpComponent c = getActiveCpComponent(); if(c != null) { return c.getMaxInstances(); } return 0; } @Override public void addComponent(ICpComponent cpComponent, int flags) { if(cpComponent.isApi()) { return; } boolean generated = cpComponent.isGenerated(); if(cpComponent instanceof ICpComponentInfo) { addComponentInfo((ICpComponentInfo)cpComponent, flags); return; } if(cpComponent.isBootStrap()) { // bootstrap component comes from a regular pack fbBootStrap = true; } // add variant, vendor and version items String variant = cpComponent.getAttribute(CmsisConstants.CVARIANT); if(isGenerated()){ if(variant.equals(getActiveVariant())) return; // do not insert a bootstrap component itself } IRteComponentItem variantItem = getChild(variant); if( variantItem == null) { variantItem = new RteComponentVariant(this, variant); addChild(variantItem); } // first try to get supplied vendor String vendor = cpComponent.getVendor(); IRteComponentItem vendorItem = variantItem.getChild(vendor); if( vendorItem == null) { vendorItem = new RteComponentVendor(variantItem, cpComponent.getVendor()); variantItem.addChild(vendorItem); } String version = cpComponent.getVersion(); IRteComponentItem versionItem = vendorItem.getChild(version); if( versionItem == null) { versionItem = new RteComponentVersion(vendorItem, cpComponent.getVersion()); vendorItem.addChild(versionItem); } // set the generated flag now if(generated) { fbGenerated = generated; setSelected(1); } versionItem.addComponent(cpComponent, flags); if(generated || (!isGenerated() && cpComponent.isDefaultVariant())) { setActiveChild(variant); } } protected void addComponentInfo(ICpComponentInfo ci, int flags) { // calculate ignore flags boolean versionFixed = (flags & RteConstants.COMPONENT_IGNORE_VERSION) == 0 && ci.isVersionFixed(); // version is fixed => variant and vendor implicitly fixed too boolean vendorFixed = versionFixed || ((flags & RteConstants.COMPONENT_IGNORE_VENDOR) == 0); String variant = ci.getAttribute(CmsisConstants.CVARIANT); boolean variantFixed = versionFixed || ((flags & RteConstants.COMPONENT_IGNORE_VARIANT) == 0 && !variant.isEmpty()); if(isGenerated()) { // in case of a generated component we do not care about bootstrap attributes versionFixed = vendorFixed = variantFixed = false; } // add variant, vendor and version items // try to get supplied variant IRteComponentItem variantItem = getChild(variant); if(isGenerated() || (variantItem == null && !variantFixed)) { variantItem = getChild(getActiveVariant()); } if( variantItem == null) { if(hasChildren()) { ci.setEvaluationResult(EEvaluationResult.MISSING_VARIANT); } else { ci.setEvaluationResult(EEvaluationResult.MISSING); } variantItem = new RteComponentVariant(this, variant); addChild(variantItem); } // try to get supplied vendor String vendor = ci.getVendor(); IRteComponentItem vendorItem = variantItem.getChild(vendor); if( isGenerated() || (vendorItem == null && !vendorFixed)) { vendorItem = variantItem.getActiveChild(); } if( vendorItem == null) { if(variantItem.hasChildren()) { // there are some vendors in the collection, but not what is needed ci.setEvaluationResult(EEvaluationResult.MISSING_VENDOR); } else { ci.setEvaluationResult(EEvaluationResult.MISSING); } vendorItem = new RteComponentVendor(variantItem, vendor); variantItem.addChild(vendorItem); } String version = null; if(versionFixed) { version = ci.getVersion(); } IRteComponentItem versionItem = vendorItem.getChild(version); if( versionItem == null) { if(vendorItem.hasChildren()) { // there are some versions in the collection, but not what is needed ci.setEvaluationResult(EEvaluationResult.MISSING_VERSION); } else { ci.setEvaluationResult(EEvaluationResult.MISSING); } versionItem = new RteComponentVersion(vendorItem, ci.getVersion()); vendorItem.addChild(versionItem); } versionItem.addComponent(ci, flags); setSelected(ci.getInstanceCount()); setActiveChild(variant); variantItem.setActiveChild(vendor); vendorItem.setActiveChild(version); } @Override public void addCpItem(ICpItem cpItem) { if(cpItem instanceof ICpComponent ) { addComponent((ICpComponent)cpItem, RteConstants.NONE); } else if (cpItem instanceof ICpTaxonomy ){ String csub = cpItem.getAttribute(CmsisConstants.CGROUP); if( csub.equals(getName())) { if(getTaxonomy() == null) { fTaxonomy = cpItem; } return; } } } @Override public void setActiveComponentInfo(ICpComponentInfo ci) { if(ci == null) { return; } addComponent(ci, RteConstants.NONE); } @Override public IRteComponent getParentComponent() { return this; } @Override public Collection<String> getVariantStrings() { return getKeys(); } @Override public String getActiveVariant() { return getActiveChildName(); } @Override public void setActiveVariant(String variant) { setActiveChild(variant); } @Override public String getActiveVendor() { if(hasBundle()) { return CmsisConstants.EMPTY_STRING; } return super.getActiveVendor(); } @Override public void setActiveVendor(String vendor) { if(hasBundle()) { return; } super.setActiveVendor(vendor); } @Override public String getActiveVersion() { if(hasBundle()) { return CmsisConstants.EMPTY_STRING; } return super.getActiveVersion(); } @Override public void setActiveVersion(String version) { if(hasBundle()) { return; } super.setActiveVersion(version); } @Override public boolean hasBundle() { IRteComponentBundle bundle = getParentBundle(); if(bundle != null && !bundle.getName().isEmpty()) { return true; } return false; } @Override public Collection<IRteComponent> getSelectedComponents( Collection<IRteComponent> components) { // is we are here => component is active if(isSelected()) { if(components == null) { components = new LinkedList<IRteComponent>(); } components.add(this); } return components; } @Override public Collection<IRteComponent> getUsedComponents(Collection<IRteComponent> components) { // is we are here => component is active ICpComponentInfo ci = getActiveCpComponentInfo(); if(ci != null) { if(components == null) { components = new LinkedList<IRteComponent>(); } components.add(this); } return components; } @Override public Collection<IRteComponent> getGeneratorComponents(String generatorId, Collection<IRteComponent> components) { // is we are here => component is active if(components == null) { components = new LinkedList<IRteComponent>(); } if(!isGenerated() && !isBootStrap()) return components; ICpComponent c = getActiveCpComponent(); if(c == null) return components; String genId = c.getGeneratorId(); if(genId != null && genId.equals(generatorId)) { components.add(this); } return components; } @Override public String getGeneratorId() { ICpComponent c = getActiveCpComponent(); if(c != null) return c.getGeneratorId(); return null; } @Override public EEvaluationResult findComponents(IRteDependency dependency) { EEvaluationResult result = super.findComponents(dependency); if(result == EEvaluationResult.SELECTABLE) { if(isSelected()) { result = EEvaluationResult.FULFILLED; } } else if (result.ordinal() >= EEvaluationResult.INSTALLED.ordinal()) { if(!isActive()) { result = EEvaluationResult.INACTIVE; } } dependency.addComponent(this, result); return result; } @Override public int getUseCount() { if(isGenerated()) return fnSelected; ICpComponentInfo ci = getActiveCpComponentInfo(); if(ci != null) { return ci.getInstanceCount(); } return 0; } }