Feature/fix sonar warnings (#1226)

* Fixed sonar warnings

- "Cognitive Complexity"
- "Do not use replaceAll when not using a regex"
- java:S5869 - Character classes in regular expressions should not contain the same character twice
- Improved bad name
- Typos
- reduced code duplications
- Replaced hand-made wait-utility with Awaitility
- Log messages
- Duplicate code
- Typos
- Removed Thread.sleep, instead relaxed check condition
- Removed use of deprecated API
- Removed use of deprecated API
- Added supress-warnings as I do not see a better way to write the tests
- Removed Thread.sleep / redundant functionality to Awaitility
- Fixed other warnings (use isZero, isEmpty, hasToString)
- Removed/Reduced duplicate code
- Added generics
- Fixed asserts
- removed: field.setAccessible(true) actually should not be needed for public static fields!
- Too long constructor passes arguments in wrong order - how surprisingly...
- Clean-up use of varargs arguments
- Fixed regex
- Fixed typos and other minor stuff
- Making public constructors protected in abstract classes
- Swapped expected and asserted argument
- volatile not enough for syncing threads
- volatile not enough for syncing threads
- out-commented code
- Made regex not-greedy, added tests for verification
- Avoid exposure of thread-local member var

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixed Sonar warnings

* License header fix

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* License header fix #2

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixing review findings

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixing tests

- Fixed '&' usage in javadoc and typos
- Fixing some warnings

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>
This commit is contained in:
Peter Vigier
2022-01-31 21:59:46 +01:00
committed by GitHub
parent 5443b5df9c
commit 44a85f20eb
98 changed files with 2583 additions and 2702 deletions

View File

@@ -91,18 +91,18 @@ public class FileTransferHandlerStreamVariable extends AbstractFileTransferHandl
return ByteStreams.nullOutputStream();
}
// we return the outputstream so we cannot close it here
// we return the output stream - we cannot close it here
@SuppressWarnings("squid:S2095")
final PipedOutputStream outputStream = new PipedOutputStream();
PipedInputStream inputStream = null;
final PipedInputStream inputStream;
try {
inputStream = new PipedInputStream(outputStream);
publishUploadProgressEvent(fileUploadId, 0, fileSize);
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
} catch (final IOException e) {
LOG.warn("Creating piped Stream failed {}.", e);
LOG.warn("Creating piped Stream failed {}.", e.getMessage());
tryToCloseIOStream(outputStream);
tryToCloseIOStream(inputStream);
// input stream is not created in case of and IOException here
interruptUploadDueToUploadFailed();
publishUploadFailedAndFinishedEvent(fileUploadId);
return ByteStreams.nullOutputStream();

View File

@@ -54,7 +54,7 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
private final transient SoftwareModuleManagement softwareModuleManagement;
private final long maxSize;
private volatile FileUploadId fileUploadId;
private FileUploadId fileUploadId;
FileTransferHandlerVaadinUpload(final long maxSize, final SoftwareModuleManagement softwareManagement,
final ArtifactManagement artifactManagement, final VaadinMessageSource i18n, final Lock uploadLock) {
@@ -64,6 +64,11 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
this.softwareModuleManagement = softwareManagement;
}
private synchronized FileUploadId setFileUploadId(final String fileName, final SoftwareModule softwareModule) {
this.fileUploadId = new FileUploadId(fileName, softwareModule);
return fileUploadId;
}
/**
* Upload started for {@link Upload} variant.
*
@@ -75,8 +80,7 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
resetState();
final SoftwareModule softwareModule = getSelectedSoftwareModule();
this.fileUploadId = new FileUploadId(event.getFilename(), softwareModule);
final FileUploadId fupId = setFileUploadId(event.getFilename(), softwareModule);
if (getUploadState().isFileInUploadState(this.fileUploadId)) {
// actual interrupt will happen a bit late so setting the below
@@ -84,15 +88,14 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
interruptUploadDueToDuplicateFile();
event.getUpload().interruptUpload();
} else {
publishUploadStarted(fileUploadId);
publishUploadStarted(fupId);
if (RegexCharacterCollection.stringContainsCharacter(event.getFilename(), ILLEGAL_FILENAME_CHARACTERS)) {
LOG.debug("Filename contains illegal characters {} for upload {}", fileUploadId.getFilename(),
fileUploadId);
LOG.debug("Filename contains illegal characters {} for upload {}", fupId.getFilename(), fupId);
interruptUploadDueToIllegalFilename();
event.getUpload().interruptUpload();
} else if (isFileAlreadyContainedInSoftwareModule(fileUploadId, softwareModule)) {
LOG.debug("File {} already contained in Software Module {}", fileUploadId.getFilename(),
} else if (isFileAlreadyContainedInSoftwareModule(fupId, softwareModule)) {
LOG.debug("File {} already contained in Software Module {}", fupId.getFilename(),
softwareModule);
interruptUploadDueToDuplicateFile();
event.getUpload().interruptUpload();
@@ -115,7 +118,6 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
*/
@Override
public OutputStream receiveUpload(final String fileName, final String mimeType) {
if (isUploadInterrupted()) {
return ByteStreams.nullOutputStream();
}
@@ -123,15 +125,14 @@ public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler
// we return the outputstream so we cannot close it here
@SuppressWarnings("squid:S2095")
final PipedOutputStream outputStream = new PipedOutputStream();
PipedInputStream inputStream = null;
try {
inputStream = new PipedInputStream(outputStream);
PipedInputStream inputStream = new PipedInputStream(outputStream);
publishUploadProgressEvent(fileUploadId, 0, 0);
startTransferToRepositoryThread(inputStream, fileUploadId, mimeType);
} catch (final IOException e) {
LOG.warn("Creating piped Stream failed {}.", e);
LOG.warn("Creating piped Stream failed!", e);
tryToCloseIOStream(outputStream);
tryToCloseIOStream(inputStream);
// input stream is not created in case of an IOException
interruptUploadDueToUploadFailed();
publishUploadFailedAndFinishedEvent(fileUploadId);
return ByteStreams.nullOutputStream();

View File

@@ -29,7 +29,7 @@ public abstract class AbstractAddEntityWindowController<T, E, R> extends Abstrac
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractAddEntityWindowController(final CommonUiDependencies uiDependencies) {
protected AbstractAddEntityWindowController(final CommonUiDependencies uiDependencies) {
super(uiDependencies);
}

View File

@@ -30,7 +30,7 @@ public abstract class AbstractAddNamedEntityWindowController<T, E extends ProxyN
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractAddNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
protected AbstractAddNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
super(uiDependencies);
}

View File

@@ -29,7 +29,7 @@ public abstract class AbstractUpdateEntityWindowController<T, E, R> extends Abst
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractUpdateEntityWindowController(final CommonUiDependencies uiDependencies) {
protected AbstractUpdateEntityWindowController(final CommonUiDependencies uiDependencies) {
super(uiDependencies);
}

View File

@@ -30,7 +30,7 @@ public abstract class AbstractUpdateNamedEntityWindowController<T, E extends Pro
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractUpdateNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
protected AbstractUpdateNamedEntityWindowController(final CommonUiDependencies uiDependencies) {
super(uiDependencies);
}

View File

@@ -8,8 +8,10 @@
*/
package org.eclipse.hawkbit.ui.common.data.proxies;
import org.eclipse.hawkbit.repository.Identifiable;
import java.io.Serializable;
import java.util.Objects;
import org.eclipse.hawkbit.repository.Identifiable;
/**
* Proxy entity representing the {@link Identifiable} entity, fetched from
@@ -23,7 +25,7 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
/**
* Constructor to initialize the id with null
*/
public ProxyIdentifiableEntity() {
protected ProxyIdentifiableEntity() {
this.id = null;
}
@@ -32,7 +34,7 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
* @param id
* Id of entity
*/
public ProxyIdentifiableEntity(final Long id) {
protected ProxyIdentifiableEntity(final Long id) {
this.id = id;
}
@@ -64,25 +66,13 @@ public abstract class ProxyIdentifiableEntity implements Serializable {
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
public boolean equals(final Object o) {
if (this == o)
return true;
}
if (obj == null) {
if (o == null || getClass() != o.getClass())
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ProxyIdentifiableEntity other = (ProxyIdentifiableEntity) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
final ProxyIdentifiableEntity that = (ProxyIdentifiableEntity) o;
return Objects.equals(id, that.id);
}
@Override

View File

@@ -32,7 +32,7 @@ public abstract class ProxyNamedEntity extends ProxyIdentifiableEntity implement
/**
* Constructor
*/
public ProxyNamedEntity() {
protected ProxyNamedEntity() {
}
/**
@@ -41,7 +41,7 @@ public abstract class ProxyNamedEntity extends ProxyIdentifiableEntity implement
* @param id
* Id of named entity
*/
public ProxyNamedEntity(final Long id) {
protected ProxyNamedEntity(final Long id) {
super(id);
}

View File

@@ -56,7 +56,7 @@ public abstract class AbstractGridDetailsLayout<T extends ProxyNamedEntity> exte
* @param i18n
* VaadinMessageSource
*/
public AbstractGridDetailsLayout(final VaadinMessageSource i18n) {
protected AbstractGridDetailsLayout(final VaadinMessageSource i18n) {
this.i18n = i18n;
this.binder = new Binder<>();

View File

@@ -18,7 +18,7 @@ import com.vaadin.server.Sizeable.Unit;
import com.vaadin.ui.Window;
/**
* Abstract builder for Meta data window
* Abstract builder for metadata window
*
* @param <F>
* Generic type
@@ -31,7 +31,7 @@ public abstract class AbstractMetaDataWindowBuilder<F> extends AbstractEntityWin
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractMetaDataWindowBuilder(final CommonUiDependencies uiDependencies) {
protected AbstractMetaDataWindowBuilder(final CommonUiDependencies uiDependencies) {
super(uiDependencies);
}

View File

@@ -56,7 +56,7 @@ public abstract class AbstractMetaDataWindowLayout<F> extends HorizontalLayout {
* @param uiDependencies
* {@link CommonUiDependencies}
*/
public AbstractMetaDataWindowLayout(final CommonUiDependencies uiDependencies) {
protected AbstractMetaDataWindowLayout(final CommonUiDependencies uiDependencies) {
this.uiDependencies = uiDependencies;
this.i18n = uiDependencies.getI18n();
this.eventBus = uiDependencies.getEventBus();

View File

@@ -46,7 +46,7 @@ public abstract class AbstractBreadcrumbGridHeader extends AbstractGridHeader {
* @param eventBus
* UIEventBus
*/
public AbstractBreadcrumbGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected AbstractBreadcrumbGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UIEventBus eventBus) {
super(i18n, permChecker, eventBus);

View File

@@ -45,7 +45,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
* @param uiNotification
* UINotification
*/
public AbstractDetailsHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected AbstractDetailsHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UIEventBus eventBus, final UINotification uiNotification) {
super(i18n, permChecker, eventBus);
@@ -67,7 +67,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
addHeaderSupports(Arrays.asList(editDetailsHeaderSupport, metaDataDetailsHeaderSupport));
}
// can be overriden in child classes for entity-specific permission
// can be overridden in child classes for entity-specific permission
protected boolean hasEditPermission() {
return permChecker.hasUpdateRepositoryPermission();
}
@@ -76,7 +76,7 @@ public abstract class AbstractDetailsHeader<T> extends AbstractMasterAwareGridHe
return true;
}
// can be overriden in child classes for entity-specific permission
// can be overridden in child classes for entity-specific permission
protected boolean hasMetadataReadPermission() {
return permChecker.hasReadRepositoryPermission();
}

View File

@@ -68,7 +68,8 @@ public abstract class AbstractEntityGridHeader extends AbstractGridHeader {
* @param view
* EventView
*/
public AbstractEntityGridHeader(final CommonUiDependencies uiDependencies, final HidableLayoutUiState filterLayoutUiState,
protected AbstractEntityGridHeader(final CommonUiDependencies uiDependencies,
final HidableLayoutUiState filterLayoutUiState,
final GridLayoutUiState gridLayoutUiState, final EventLayout filterLayout, final EventView view) {
super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus());

View File

@@ -47,7 +47,7 @@ public abstract class AbstractFilterHeader extends AbstractGridHeader {
* @param eventBus
* UIEventBus
*/
public AbstractFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected AbstractFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UIEventBus eventBus) {
super(i18n, permChecker, eventBus);

View File

@@ -46,7 +46,7 @@ public abstract class AbstractGridHeader extends VerticalLayout {
* @param eventBus
* UIEventBus
*/
public AbstractGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected AbstractGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UIEventBus eventBus) {
this.i18n = i18n;
this.permChecker = permChecker;

View File

@@ -43,7 +43,7 @@ public abstract class AbstractMasterAwareGridHeader<T> extends AbstractGridHeade
* @param eventBus
* UIEventBus
*/
public AbstractMasterAwareGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected AbstractMasterAwareGridHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UIEventBus eventBus) {
super(i18n, permChecker, eventBus);

View File

@@ -74,7 +74,7 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
* @param rsqlValidationOracle
* RsqlValidationOracle
*/
public TargetFilterAddUpdateLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
protected TargetFilterAddUpdateLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker,
final UiProperties uiProperties, final TargetFilterDetailsLayoutUiState uiState, final UIEventBus eventBus,
final RsqlValidationOracle rsqlValidationOracle) {
super();
@@ -140,7 +140,8 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
autoCompleteComponent.addValidationListener((valid, message) -> searchButton.setEnabled(valid));
autoCompleteComponent.addTextfieldChangedListener(this::onFilterQueryTextfieldChanged);
autoCompleteComponent
.addShortcutListener(new ShortcutListener("List Filtered Targets", ShortcutAction.KeyCode.ENTER, null) {
.addShortcutListener(
new ShortcutListener("List Filtered Targets", ShortcutAction.KeyCode.ENTER, (int[]) null) {
private static final long serialVersionUID = 1L;
@Override
@@ -200,13 +201,6 @@ public class TargetFilterAddUpdateLayout extends AbstractEntityWindowLayout<Prox
});
}
/**
* Disable search button
*/
public void disableSearchButton() {
searchButton.setEnabled(false);
}
/**
* Check validity of target filter query.
*

View File

@@ -95,7 +95,7 @@ public class DeploymentAssignmentWindowController {
}
/**
* Save the given distribution sets to targets assignments
* Save the given distribution sets to target assignments
*
* @param proxyTargets
* to assign the given distribution sets to
@@ -140,7 +140,7 @@ public class DeploymentAssignmentWindowController {
EntityModifiedEventType.ENTITY_UPDATED, ProxyTarget.class, assignedTargetIds));
} catch (final MultiAssignmentIsNotEnabledException e) {
notification.displayValidationError(i18n.getMessage("message.target.ds.multiassign.error"));
LOG.error("UI allowed multiassignment although it is not enabled: {}", e);
LOG.error("UI allowed multi-assignment although it is not enabled", e);
}
}

View File

@@ -12,13 +12,14 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.vaadin.data.Binder;
import com.vaadin.ui.CustomComponent;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxySystemConfigWindow;
import org.springframework.beans.factory.InitializingBean;
import com.vaadin.data.Binder;
import com.vaadin.ui.CustomComponent;
/**
* Base class for all configuration views. This class implements the logic for
* the handling of the configurations in a consistent way.
@@ -33,7 +34,7 @@ public abstract class BaseConfigurationView<B extends ProxySystemConfigWindow> e
private final transient TenantConfigurationManagement tenantConfigurationManagement;
private final Binder<B> binder;
public BaseConfigurationView(final TenantConfigurationManagement tenantConfigurationManagement) {
protected BaseConfigurationView(final TenantConfigurationManagement tenantConfigurationManagement) {
this.tenantConfigurationManagement = tenantConfigurationManagement;
binder = new Binder<>();
}

View File

@@ -20,7 +20,6 @@ import java.util.TimeZone;
import java.util.stream.Collectors;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyNamedEntity;
import org.springframework.util.StringUtils;
import com.google.common.collect.Maps;
@@ -99,10 +98,10 @@ public final class SPDateTimeUtil {
*
* @param lastQueryDate
* Last query date
* @return String formatted date
* @return String formatted date or {@code null} when the provided {@code lastQueryDate} was {@code null}
*/
public static String getFormattedDate(final Long lastQueryDate) {
return formatDate(lastQueryDate, null);
return getFormattedDate(lastQueryDate, SPUIDefinitions.LAST_QUERY_DATE_FORMAT);
}
/**
@@ -112,67 +111,15 @@ public final class SPDateTimeUtil {
* Last query date
* @param datePattern
* pattern how to format the date (cp. {@code SimpleDateFormat})
* @return String formatted date
* @return String formatted date or {@code null} when the provided {@code lastQueryDate} was {@code null}
*/
public static String getFormattedDate(final Long lastQueryDate, final String datePattern) {
return formatDate(lastQueryDate, null, datePattern);
}
/**
* Get formatted date 'created at' by entity.
*
* @param baseEntity
* the entity
* @return String formatted date
*/
public static String formatCreatedAt(final ProxyNamedEntity baseEntity) {
if (baseEntity == null) {
return "";
}
return formatDate(baseEntity.getCreatedAt(), "");
}
/**
* Get formatted date 'last modified at' by entity.
*
* @param baseEntity
* the entity
* @return String formatted date
*/
public static String formatLastModifiedAt(final ProxyNamedEntity baseEntity) {
if (baseEntity == null) {
return "";
}
return formatDate(baseEntity.getLastModifiedAt(), "");
}
/**
* Get formatted date 'last modified at' by entity.
*
* @param baseEntity
* the entity
* @param datePattern
* pattern how to format the date (cp. {@code SimpleDateFormat})
* @return String formatted date
*/
public static String formatLastModifiedAt(final ProxyNamedEntity baseEntity, final String datePattern) {
if (baseEntity == null) {
return "";
}
return formatDate(baseEntity.getLastModifiedAt(), "", datePattern);
}
private static String formatDate(final Long lastQueryDate, final String defaultString, final String datePattern) {
if (lastQueryDate != null) {
final SimpleDateFormat format = new SimpleDateFormat(datePattern);
format.setTimeZone(getBrowserTimeZone());
return format.format(new Date(lastQueryDate));
}
return defaultString;
}
private static String formatDate(final Long lastQueryDate, final String defaultString) {
return formatDate(lastQueryDate, defaultString, SPUIDefinitions.LAST_QUERY_DATE_FORMAT);
return null;
}
/**
@@ -226,10 +173,10 @@ public final class SPDateTimeUtil {
* Get time zone of the browser client to be used as default.
*/
public static String getClientTimeZoneOffsetId() {
return getCurentZonedDateTime().getOffset().getId().replaceAll("Z", "+00:00");
return getCurrentZonedDateTime().getOffset().getId().replace("Z", "+00:00");
}
private static ZonedDateTime getCurentZonedDateTime() {
private static ZonedDateTime getCurrentZonedDateTime() {
return ZonedDateTime.now(getBrowserTimeZoneId());
}
@@ -243,7 +190,7 @@ public final class SPDateTimeUtil {
* @return Two weeks from current date and time in epoc milliseconds
*/
public static Long twoWeeksFromNowEpochMilli() {
return getCurentZonedDateTime().plusWeeks(2).toInstant().toEpochMilli();
return getCurrentZonedDateTime().plusWeeks(2).toInstant().toEpochMilli();
}
/**
@@ -252,7 +199,7 @@ public final class SPDateTimeUtil {
* @return Half an hour from current date and time in epoc milliseconds
*/
public static Long halfAnHourFromNowEpochMilli() {
return getCurentZonedDateTime().plusMinutes(30).toInstant().toEpochMilli();
return getCurrentZonedDateTime().plusMinutes(30).toInstant().toEpochMilli();
}
/**

View File

@@ -46,11 +46,11 @@ public class HawkbitCommonUtilTest {
// WHEN
final Locale currentLocale2 = HawkbitCommonUtil.getCurrentLocale();
// THEN
assertThat(Locale.GERMAN).isEqualTo(currentLocale2);
assertThat(currentLocale2).isEqualTo(Locale.GERMAN);
}
@Test
@Description("If a default locale is set in the environment, then it should take perceedence over requested browser locale")
@Description("If a default locale is set in the environment, then it should take precedence over requested browser locale")
public void getLocaleToBeUsedShouldReturnDefaultLocalIfSet() {
final UiProperties.Localization localizationProperties = Mockito.mock(UiProperties.Localization.class);
@@ -59,7 +59,7 @@ public class HawkbitCommonUtilTest {
// WHEN
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.CHINESE);
// THEN
assertThat(Locale.GERMAN).isEqualTo(localeToBeUsed);
assertThat(localeToBeUsed).isEqualTo(Locale.GERMAN);
}
@Test
@@ -74,7 +74,7 @@ public class HawkbitCommonUtilTest {
// WHEN
final Locale localeToBeUsed = HawkbitCommonUtil.getLocaleToBeUsed(localizationProperties, Locale.GERMAN);
// THEN
assertThat(Locale.GERMAN).isEqualTo(localeToBeUsed);
assertThat(localeToBeUsed).isEqualTo(Locale.GERMAN);
}
}