diff --git a/bundles/org.aposin.gem.core/META-INF/MANIFEST.MF b/bundles/org.aposin.gem.core/META-INF/MANIFEST.MF index e7629b2..7f50a19 100644 --- a/bundles/org.aposin.gem.core/META-INF/MANIFEST.MF +++ b/bundles/org.aposin.gem.core/META-INF/MANIFEST.MF @@ -37,6 +37,7 @@ Export-Package: org.aposin.gem.core;uses:="org.osgi.framework,org.slf4j", org.aposin.gem.core.impl.internal.workflow.command;x-internal:=true, org.aposin.gem.core.impl.internal.workflow.command.base;x-internal:=true, org.aposin.gem.core.impl.model.repo, + org.aposin.gem.core.impl.service, org.aposin.gem.core.impl.service.launcher, org.aposin.gem.core.utils Bundle-ClassPath: ., diff --git a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IGemSorter.java b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IGemSorter.java new file mode 100644 index 0000000..67dd82f --- /dev/null +++ b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IGemSorter.java @@ -0,0 +1,60 @@ +/** + * Copyright 2020 Association for the promotion of open-source insurance software and for the establishment of open interface standards in the insurance industry (Verein zur Foerderung quelloffener Versicherungssoftware und Etablierung offener Schnittstellenstandards in der Versicherungsbranche) + * + * 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 org.aposin.gem.core.api.service; + +import java.util.Comparator; + +import org.aposin.gem.core.api.model.IEnvironment; +import org.aposin.gem.core.api.model.IProject; + +/** + * Service to provide a sorting algorithm for several GEM objects. + *
+ * IMPORTANT: should be provided only once. + */ +public interface IGemSorter extends IGemService { + + /** + * {@inheritDoc} + */ + @Override + public default String getName() { + return getId(); + } + + /** + * {@inheritDoc} + */ + @Override + public default String getDisplayName() { + return getId(); + } + + /** + * Get the comparator for the projects. + * + * @return project comparator. + */ + public Comparator getProjectComparator(); + + /** + * Get the comparator for the environments. + * + * @return environment comparator. + */ + public Comparator getEnvironmentComparator(); + +} diff --git a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IServiceContainer.java b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IServiceContainer.java index df8eea0..9c51631 100644 --- a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IServiceContainer.java +++ b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/api/service/IServiceContainer.java @@ -18,17 +18,40 @@ import java.util.Collection; import java.util.Map; +import org.aposin.gem.core.GemException; import org.aposin.gem.core.api.IRefreshable; import org.aposin.gem.core.api.config.GemConfigurationException; import org.aposin.gem.core.api.config.IConfigurable; import org.aposin.gem.core.api.service.launcher.IEnvironmentLauncherProvider; import org.aposin.gem.core.api.service.launcher.IFeatureBranchLauncherProvider; +import org.aposin.gem.core.impl.service.DefaultGemSorter; /** * Container class for the services implemented by core and/or extensions. */ public interface IServiceContainer extends IRefreshable, IConfigurable { + /** + * Gets the configured {@link IGemSorter}. + *
+ * Default implementation checks for an optional unique gem-sorter. + * + * @return sorter. + * + * @throws GemException if more than one sorter is provided. + */ + public default IGemSorter getGemSorter() { + final Collection sorters = getGemServices(IGemSorter.class); + switch (sorters.size()) { + case 0: + return new DefaultGemSorter(); + case 1: + return sorters.iterator().next(); + default: + throw new GemException("Several gem-sorters provided"); + } + } + /** * Gets the configured default feature branch provider. * diff --git a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/config/ConfigurationImpl.java b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/config/ConfigurationImpl.java index 1773993..007c1a9 100644 --- a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/config/ConfigurationImpl.java +++ b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/config/ConfigurationImpl.java @@ -222,7 +222,7 @@ public List getProjects() { private void loadProjects() { projects = config.projects.stream() // .map(project -> new ProjectImpl(this, project)) // - .sorted() // + .sorted(getServiceContainer().getGemSorter().getProjectComparator()) // .collect(Collectors.toList()); } diff --git a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/model/ProjectImpl.java b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/model/ProjectImpl.java index f8f478d..242c3bd 100644 --- a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/model/ProjectImpl.java +++ b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/internal/model/ProjectImpl.java @@ -18,7 +18,6 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -129,7 +128,7 @@ private void loadObsoleteEnvironments() { // maybeObsoleteBranches only contain obsoleteBranches obsoleteEnvironments = maybeObsoleteBranches.stream() // .map(branch -> new ObsoleteKnownEnvironment(config, this, projectInternalBranch, branch, branchToRepos.get(branch))) // - .sorted(Comparator.reverseOrder()) // + .sorted(config.getServiceContainer().getGemSorter().getEnvironmentComparator()) // .collect(Collectors.toList()); } @@ -148,10 +147,8 @@ private void loadEnvironments() { } environments.add(new EnvironmentImpl(config, this, env)); } - // finally, sort environments (reverse order, as it is usually the version number) - // TODO - maybe it is worth to provide a configuration to short the environments - // TODO - or do it at the UI level instead of here... - environments.sort(Comparator.reverseOrder()); + // sort environments using the sorter extension + environments.sort(config.getServiceContainer().getGemSorter().getEnvironmentComparator()); } /** diff --git a/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/service/DefaultGemSorter.java b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/service/DefaultGemSorter.java new file mode 100644 index 0000000..cbc2644 --- /dev/null +++ b/bundles/org.aposin.gem.core/src/org/aposin/gem/core/impl/service/DefaultGemSorter.java @@ -0,0 +1,56 @@ +/** + * Copyright 2020 Association for the promotion of open-source insurance software and for the establishment of open interface standards in the insurance industry (Verein zur Foerderung quelloffener Versicherungssoftware und Etablierung offener Schnittstellenstandards in der Versicherungsbranche) + * + * 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 org.aposin.gem.core.impl.service; + +import java.util.Comparator; + +import org.aposin.gem.core.api.config.GemConfigurationException; +import org.aposin.gem.core.api.config.IConfiguration; +import org.aposin.gem.core.api.model.IEnvironment; +import org.aposin.gem.core.api.model.IProject; +import org.aposin.gem.core.api.service.IGemSorter; + +/** + * Default {@link IGemSorter}. + *
+ * This sorter can be extended by plug-ins and be registered as a service (only one is allowed). + */ +public class DefaultGemSorter implements IGemSorter { + + /** + * {@inheritDoc} + */ + @Override + public void setConfig(final IConfiguration config) throws GemConfigurationException { + // NO-OP + } + + /** + * {@inheritDoc} + */ + @Override + public Comparator getEnvironmentComparator() { + return Comparator.reverseOrder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Comparator getProjectComparator() { + return Comparator.naturalOrder(); + } +}