blob: c0b221c5ef87fed581f5ac9d0de6109cba3b5a8e [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2018-2021 Robert Bosch GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.amalthea.converters083.impl;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.app4mc.amalthea.converters.common.ServiceConstants;
import org.eclipse.app4mc.amalthea.converters.common.base.ICache;
import org.eclipse.app4mc.amalthea.converters.common.base.IConverter;
import org.eclipse.app4mc.amalthea.converters.common.converter.AbstractConverter;
import org.eclipse.app4mc.amalthea.converters.common.utils.AmaltheaNamespaceRegistry;
import org.eclipse.app4mc.amalthea.converters.common.utils.HelperUtil;
import org.eclipse.app4mc.amalthea.converters.common.utils.ModelVersion;
import org.eclipse.app4mc.amalthea.converters083.utils.PeriodicStimulusCacheBuilder;
import org.eclipse.app4mc.util.sessionlog.SessionLogger;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* This class is responsible for converting the Stimulus model elements from
* 0.8.2 to 0.8.3 version format of AMALTHEA model
*
* @author zmeer
*
*/
@Component(
property = {
ServiceConstants.INPUT_MODEL_VERSION_PROPERTY + "=0.8.2",
ServiceConstants.OUTPUT_MODEL_VERSION_PROPERTY + "=0.8.3"},
service = IConverter.class)
public class StimuliConverter extends AbstractConverter {
private static final String AM = "am";
private static final String XSI = "xsi";
private static final String TYPE = "type";
private static final String HREF = "href";
private static final String ENTITY = "entity";
private static final String TASKS = "tasks";
private static final String STIMULI = "stimuli";
private static final String STIMULUS_DEVIATION = "stimulusDeviation";
@Reference
SessionLogger logger;
private PeriodicStimulusCacheBuilder cache;
@Override
@Activate
protected void activate(Map<String, Object> properties) {
super.activate(properties);
}
@Override
public void convert(File targetFile, Map<File, Document> fileDocumentMapping, List<ICache> caches) {
logger.info("Migration from 0.8.2 to 0.8.3 : Executing Stimulus model converter for model file : {0}",
targetFile.getName());
this.cache = getPeriodicStimulusCacheBuilder(caches);
if (this.cache == null) {
throw new IllegalStateException(
"PeriodicStimulusCacheBuilder is not built and Object of it is not available in Converters");
}
final Document root = fileDocumentMapping.get(targetFile);
if (root == null) {
return;
}
final Element rootElement = root.getRootElement();
migrateVariableRateStimulus(rootElement);
migrateSyntheticStimulus(rootElement);
migrateSporadicStimulus(rootElement);
migrateArrivalCurveStimulus(rootElement);
migrateSingleStimulus(rootElement);
migrateRemainingStimulusTypes(rootElement);
migratePeriodicStimulus(rootElement);
migrateStimulusReferences(rootElement);
}
/**
* This method is used to get the PeriodicStimulusCacheBuilder object
*
* @param caches The list of all caches.
* @return PeriodicStimulusCacheBuilder
*/
private PeriodicStimulusCacheBuilder getPeriodicStimulusCacheBuilder(List<ICache> caches) {
if (caches != null) {
for (ICache c : caches) {
if (c instanceof PeriodicStimulusCacheBuilder) {
return (PeriodicStimulusCacheBuilder) c;
}
}
}
return null;
}
private void migrateStimulusReferences(Element rootElement) {
// updating the references
final StringBuilder xpathBufferForReferences = new StringBuilder();
xpathBufferForReferences.append("./swModel/isrs");
xpathBufferForReferences.append("|");
xpathBufferForReferences.append("./swModel/tasks");
xpathBufferForReferences.append("|");
xpathBufferForReferences.append("./eventModel/events");
final List<Element> stimulusReferenceContainers = HelperUtil.getXpathResult(rootElement,
xpathBufferForReferences.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusReferenceContainer : stimulusReferenceContainers) {
migrateReferencesOfPeriodicStimulus(stimulusReferenceContainer);
migrateReferencesOfSporadicStimulus(stimulusReferenceContainer);
migrateReferencesOfSyntheticStimulus(stimulusReferenceContainer);
}
}
/**
* This method is used to migrate the contents of PeriodicStimulus based on the
* changes introduced as per Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migratePeriodicStimulus(Element rootElement) {
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:PeriodicStimulus\"]");
final List<Element> stimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusElement : stimulusElements) {
Element clockElement = stimulusElement.getChild("clock");
Attribute clockAttribute = stimulusElement.getAttribute("clock");
if ((clockElement == null) && (clockAttribute == null)) {
// renaming stimulusDeviation to jitter
Element stimulusDeviationElement = stimulusElement.getChild(STIMULUS_DEVIATION);
if (stimulusDeviationElement != null) {
stimulusDeviationElement.setName("jitter");
}
} else {
// changing the type of PeriodicStimulus to VariableRateStimulus
Attribute typeAttribute = stimulusElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
typeAttribute.setValue("am:VariableRateStimulus");
// renaming recurrence to step
Element recurrenceElement = stimulusElement.getChild("recurrence");
Element offsetElement = stimulusElement.getChild("offset");
/* ================Scenario Eleemnt====================== */
Element scenarioElement = new Element("scenario");
if (recurrenceElement != null) {
recurrenceElement.detach();
// Adding recurrance as a part of scenario
scenarioElement.addContent(recurrenceElement);
}
if (clockElement != null) {
clockElement.detach();
// Adding clock as a part of Clock
scenarioElement.addContent(clockElement);
} else if (clockAttribute != null) {
clockAttribute.detach();
scenarioElement.setAttribute(clockAttribute);
}
// Adding Scenario as a part of stimulus element
stimulusElement.addContent(scenarioElement);
if (offsetElement != null) {
Element customPropertiesElement = new Element("customProperties");
customPropertiesElement.setAttribute("key", "offset");
offsetElement.detach();
offsetElement.setName("value");
offsetElement.setAttribute(TYPE, "am:TimeObject",
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
customPropertiesElement.addContent(offsetElement);
scenarioElement.addContent(customPropertiesElement);
}
/* ================Scenario Eleemnt====================== */
stimulusElement.removeChild("offset");
stimulusElement.removeChild(STIMULUS_DEVIATION);
}
}
}
/**
* This method is used to verify if a PeriodicStimulus type be changed to
* VariableRateStimulus (as it consists of Clock definition. Based on 0.8.3 ->
* such PeriodicStimulus elements type are changed)
*
* @param elementName href (e.g: "amlt:/#Timer_10MS?type=PeriodicStimulus ")
* @return boolean ("true" - if PeriodicStimulus is containing Clock reference,
* else "false")
*/
private boolean canPeriodicStimulusTypeBeChangedForHref(String href) {
/*
* Example: <stimuli xsi:type="am:PeriodicStimulus"
* href="amlt:/#Timer_10MS?type=PeriodicStimulus"/>
*
* parameter : "href" -> contains amlt:/#Timer_10MS?type=PeriodicStimulus
*/
int start = href.indexOf('#');
int end = href.lastIndexOf('?');
if (start != -1 && end != -1) {
String elementName = href.substring(start + 1, end);
return isPeriodicStimulusPresentInCache(elementName);
}
return false;
}
/**
* This method is used to verify if a PeriodicStimulus is avaialble in Cache
* (Note: Storage in cache is done only if Clock is referred inside
* PeriodicStimulus element)
*
* @param elementName String (e.g: "testStimulus")
* @return boolean ("true" - if PeriodicStimulus is containing Clock reference,
* else "false")
*/
private boolean isPeriodicStimulusPresentInCache(String elementName) {
Map<File, Map<String, Object>> cacheMap = this.cache.getCacheMap();
if (cacheMap != null) {
Set<File> keySet = cacheMap.keySet();
for (File file : keySet) {
Map<String, Object> map = cacheMap.get(file);
if (map != null) {
Object object = map.get(PeriodicStimulusCacheBuilder.CACHE_KEY);
if (object != null) {
@SuppressWarnings("unchecked")
final List<String> periodicStimulus_with_clock = (List<String>) object;
if (periodicStimulus_with_clock.contains(elementName)) {
return true;
}
}
}
}
}
return false;
}
/**
* This method is used to check and update the reference of PeriodicStimulus.
* Note: 1. If PeriodicStimulus consists of clock, then type of it should be
* changed to VariableRateStimulus 2. If PeriodicStimulus doesn't contain clock
* definition -> type should remain as PeriodicStimulus
*
* @param reference String (e.g: "ss1?type=SporadicStimulus")
* @return String - Updated string with type info (only if PeriodicStimulus
* element consists of clock )
*/
private String checkAndUpdatePeriodicStimulusReference(String reference) {
/*
* Example: <tasks name="t3" stimuli="ss1?type=SporadicStimulus"
* multipleTaskActivationLimit="0"/>
*
* parameter : "reference" -> contains ss1?type=SporadicStimulus
*/
int index = reference.lastIndexOf('?');
if (index != -1) {
String elementName = reference.substring(0, index);
boolean result = isPeriodicStimulusPresentInCache(elementName);
if (result) {
elementName = reference.replace("?type=PeriodicStimulus", "?type=VariableRateStimulus");
return elementName;
}
}
return reference;
}
/**
* This method is used to migrate the contents of CustomStimulus,
* InterProcessStimulus, EventStimulus based on the changes introduced as per
* Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migrateRemainingStimulusTypes(Element rootElement) {
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append(
"./stimuliModel/stimuli[@xsi:type=\"am:CustomStimulus\" or @xsi:type=\"am:InterProcessStimulus\" or @xsi:type=\"am:EventStimulus\"]");
final List<Element> stimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusElement : stimulusElements) {
// removing stimulusDeviation
stimulusElement.removeChild(STIMULUS_DEVIATION);
}
}
/**
* This method is used to migrate the contents of SingleStimulus based on the
* changes introduced as per Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migrateSingleStimulus(Element rootElement) {
// Step 1: changing the type from SyntheticStimulus to PeriodicSyntheticStimulus
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:SingleStimulus\"]");
final List<Element> stimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusElement : stimulusElements) {
// removing stimulusDeviation
stimulusElement.removeChild(STIMULUS_DEVIATION);
// changing the activation tag name to occurrence
Element activationElement = stimulusElement.getChild("activation");
if (activationElement != null) {
activationElement.setName("occurrence");
}
}
}
/**
* This method is used to migrate the contents of ArrivalCurveStimulus based on
* the changes introduced as per Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migrateArrivalCurveStimulus(Element rootElement) {
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:ArrivalCurveStimulus\"]");
final List<Element> stimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusElement : stimulusElements) {
// removing stimulusDeviation
stimulusElement.removeChild(STIMULUS_DEVIATION);
// changing the attribute name from numberOfEvents to numberOfOccurences
List<Element> entriesElements = stimulusElement.getChildren("entries");
for (Element entriesElement : entriesElements) {
Attribute attribute = entriesElement.getAttribute("numberOfEvents");
if (attribute != null) {
attribute.setName("numberOfOccurrences");
}
}
}
}
/**
* This method is used to migrate the contents of SporadicStimulus based on the
* changes introduced as per Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migrateSporadicStimulus(Element rootElement) {
// Step 1: changing the type from SporadicStimulus to RelativePeriodicStimulus
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:SporadicStimulus\"]");
final List<Element> sporadicStimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element sporadicStimulusElement : sporadicStimulusElements) {
Attribute typeAttribute = sporadicStimulusElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
typeAttribute.setValue("am:RelativePeriodicStimulus");
sporadicStimulusElement.removeAttribute("description");
// changing of stimulusDeviation to nextOccurrence
Element stimulusDeviationElement = sporadicStimulusElement.getChild(STIMULUS_DEVIATION);
if (stimulusDeviationElement != null) {
stimulusDeviationElement.setName("nextOccurrence");
}
}
}
/**
* This method is used to migrate the contents of VariableRateStimulus based on
* the changes introduced as per Bug 529831
*
* @param rootElement Amalthea root element
*/
private void migrateVariableRateStimulus(Element rootElement) {
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:VariableRateStimulus\"]");
final List<Element> stimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element stimulusElement : stimulusElements) {
stimulusElement.removeChild(STIMULUS_DEVIATION);
}
}
/**
* This method is used to migrate the contents of SyntheticStimulus based on the
* changes introduced as per Bug 529831
*
*
* @param rootElement Amalthea root element
*/
private void migrateSyntheticStimulus(Element rootElement) {
// Step 1: changing the type from SyntheticStimulus to PeriodicSyntheticStimulus
final StringBuilder xpathBufferForDefinition = new StringBuilder();
xpathBufferForDefinition.append("./stimuliModel/stimuli[@xsi:type=\"am:SyntheticStimulus\"]");
final List<Element> syntheticStimulusElements = HelperUtil.getXpathResult(rootElement,
xpathBufferForDefinition.toString(), Element.class,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element syntheticStimulusElement : syntheticStimulusElements) {
Attribute typeAttribute = syntheticStimulusElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
typeAttribute.setValue("am:PeriodicSyntheticStimulus");
// deletion of stimulusDeviation
syntheticStimulusElement.removeChild(STIMULUS_DEVIATION);
Element periodElement = syntheticStimulusElement.getChild("period");
if (periodElement != null) {
periodElement.setName("recurrence");
}
Element triggerTimesElement = syntheticStimulusElement.getChild("triggerTimes");
if (triggerTimesElement != null) {
final List<Element> timeStampsElements = HelperUtil.getXpathResult(triggerTimesElement, ".//timestamps",
Element.class, AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));
for (Element timeStampsElement : timeStampsElements) {
timeStampsElement.setName("occurrenceTimes");
timeStampsElement.detach();
syntheticStimulusElement.addContent(timeStampsElement);
}
// removing element triggerTimesElement
syntheticStimulusElement.removeContent(triggerTimesElement);
}
}
}
/**
* This method is used to migrate the references of SporadicStimulus elements
*
* @param stimulusReferenceContainer (e.g: tasks, isrs, events)
*/
private void migrateReferencesOfSporadicStimulus(Element stimulusReferenceContainer) {
String containerTagName = stimulusReferenceContainer.getName();
if (containerTagName.equals("isrs") || containerTagName.equals(TASKS)) {
List<Element> stimuliElements = stimulusReferenceContainer.getChildren(STIMULI);
Attribute stimuliAttribute = stimulusReferenceContainer.getAttribute(STIMULI);
for (Element stimuliElement : stimuliElements) {
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null) {
if (typeAttribute.getValue().equals("am:SporadicStimulus")) {
typeAttribute.setValue("am:RelativePeriodicStimulus");
}
}
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String value = hrefAttribute.getValue();
value = value.replace("?type=SporadicStimulus", "?type=RelativePeriodicStimulus");
hrefAttribute.setValue(value);
}
}
}
if (stimuliAttribute != null) {
String value = stimuliAttribute.getValue();
value = value.replace("?type=SporadicStimulus", "?type=RelativePeriodicStimulus");
stimuliAttribute.setValue(value);
}
} else if (containerTagName.equals("events")) {
// case of events
Element stimuliElement = stimulusReferenceContainer.getChild(ENTITY);
Attribute stimuliAttribute = stimulusReferenceContainer.getAttribute(ENTITY);
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null) {
if (typeAttribute.getValue().equals("am:SporadicStimulus")) {
typeAttribute.setValue("am:RelativePeriodicStimulus");
}
}
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String value = hrefAttribute.getValue();
value = value.replace("?type=SporadicStimulus", "?type=RelativePeriodicStimulus");
hrefAttribute.setValue(value);
}
} else if (stimuliAttribute != null) {
String value = stimuliAttribute.getValue();
value = value.replace("?type=SporadicStimulus", "?type=RelativePeriodicStimulus");
stimuliAttribute.setValue(value);
}
}
}
/**
* This method is used to migrate the references of Synthetic Stimulus
* references
*
* @param syntheticStimulusReferenceContainer (e.g: tasks, isrs, events)
*/
private void migrateReferencesOfSyntheticStimulus(Element syntheticStimulusReferenceContainer) {
String containerTagName = syntheticStimulusReferenceContainer.getName();
if (containerTagName.equals("isrs") || containerTagName.equals(TASKS)) {
List<Element> stimuliElements = syntheticStimulusReferenceContainer.getChildren(STIMULI);
Attribute stimuliAttribute = syntheticStimulusReferenceContainer.getAttribute(STIMULI);
for (Element stimuliElement : stimuliElements) {
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null) {
if (typeAttribute.getValue().equals("am:SyntheticStimulus")) {
typeAttribute.setValue("am:PeriodicSyntheticStimulus");
}
}
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String value = hrefAttribute.getValue();
value = value.replace("?type=SyntheticStimulus", "?type=PeriodicSyntheticStimulus");
hrefAttribute.setValue(value);
}
}
}
if (stimuliAttribute != null) {
String value = stimuliAttribute.getValue();
value = value.replace("?type=SyntheticStimulus", "?type=PeriodicSyntheticStimulus");
stimuliAttribute.setValue(value);
}
} else if (containerTagName.equals("events")) {
// case of events
Element stimuliElement = syntheticStimulusReferenceContainer.getChild(ENTITY);
Attribute stimuliAttribute = syntheticStimulusReferenceContainer.getAttribute(ENTITY);
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE, AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null && "am:SyntheticStimulus".equals(typeAttribute.getValue())) {
typeAttribute.setValue("am:PeriodicSyntheticStimulus");
}
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String value = hrefAttribute.getValue();
value = value.replace("?type=SyntheticStimulus", "?type=PeriodicSyntheticStimulus");
hrefAttribute.setValue(value);
}
} else if (stimuliAttribute != null) {
String value = stimuliAttribute.getValue();
value = value.replace("?type=SyntheticStimulus", "?type=PeriodicSyntheticStimulus");
stimuliAttribute.setValue(value);
}
}
}
/**
* This method is used to migrate the references of PeriodicStimulus elements
*
* @param stimulusReferenceContainer (e.g: tasks, isrs, events)
*/
private void migrateReferencesOfPeriodicStimulus(Element stimulusReferenceContainer) {
String containerTagName = stimulusReferenceContainer.getName();
if (containerTagName.equals("isrs") || containerTagName.equals(TASKS)) {
List<Element> stimuliElements = stimulusReferenceContainer.getChildren(STIMULI);
Attribute stimuliAttribute = stimulusReferenceContainer.getAttribute(STIMULI);
for (Element stimuliElement : stimuliElements) {
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null && "am:PeriodicStimulus".equals(typeAttribute.getValue())) {
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String hrefValue = hrefAttribute.getValue();
// <stimuli xsi:type="am:PeriodicStimulus"
// href="amlt:/#Timer_10MS?type=PeriodicStimulus"/>
if (canPeriodicStimulusTypeBeChangedForHref(hrefValue)) {
// setting type
typeAttribute.setValue("am:VariableRateStimulus");
hrefValue = hrefValue.replace("?type=PeriodicStimulus", "?type=VariableRateStimulus");
hrefAttribute.setValue(hrefValue);
}
}
}
}
}
if (stimuliAttribute != null) {
String value = stimuliAttribute.getValue();
String[] split = value.split("\\s+");
StringBuilder updatedRefsBuffer = new StringBuilder();
for (String reference : split) {
if (reference.contains("?type=PeriodicStimulus")) {
updatedRefsBuffer.append(checkAndUpdatePeriodicStimulusReference(reference) + " ");
} else {
updatedRefsBuffer.append(reference + " ");
}
}
value = updatedRefsBuffer.toString().trim();
stimuliAttribute.setValue(value);
}
} else if (containerTagName.equals("events")) {
// case of events
Element stimuliElement = stimulusReferenceContainer.getChild(ENTITY);
Attribute stimuliAttribute = stimulusReferenceContainer.getAttribute(ENTITY);
if (stimuliElement != null) {
Attribute typeAttribute = stimuliElement.getAttribute(TYPE,
AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
if (typeAttribute != null) {
if (typeAttribute.getValue().equals("am:PeriodicStimulus")) {
Attribute hrefAttribute = stimuliElement.getAttribute(HREF);
if (hrefAttribute != null) {
String hrefValue = hrefAttribute.getValue();
// <stimuli xsi:type="am:PeriodicStimulus"
// href="amlt:/#Timer_10MS?type=PeriodicStimulus"/>
if (canPeriodicStimulusTypeBeChangedForHref(hrefValue)) {
// setting type
typeAttribute.setValue("am:VariableRateStimulus");
hrefValue = hrefValue.replace("?type=PeriodicStimulus", "?type=VariableRateStimulus");
hrefAttribute.setValue(hrefValue);
}
}
}
}
} else if (stimuliAttribute != null) {
String reference = stimuliAttribute.getValue();
if (reference.contains("?type=PeriodicStimulus")) {
reference = (checkAndUpdatePeriodicStimulusReference(reference));
}
stimuliAttribute.setValue(reference);
}
}
}
}