diff --git a/README.md b/README.md index ea5c50c3e4..356adc0f5e 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,40 @@ # Base Cube One -This is the official repository of the smart environment framework Base Cube One. +[![Dev](https://github.com/openbase/bco/actions/workflows/build-and-test.yml/badge.svg?branch=dev)](https://github.com/openbase/jul/actions/workflows/build-and-test.yml) +[![Maven Central](https://img.shields.io/maven-central/v/org.openbase/bco.svg?label=Latest%20Version)](https://search.maven.org/artifact/org.openbase/bco) -* [Documentation](https://basecubeone.org) -* [User Installation](https://basecubeone.org/user/installation.html) -* [Contribution](https://basecubeone.org/developer/contribution.html) -* [Community](https://openbase.org) +A smart environment framework featured by [openbase.org](https://openbase.org). -## How to build BCO +## Features +* Smart home Apps that can be easily installed at your rooms to apply new smart home functions. +* A revolutionary Multi-Agent-Automation approach to replace conventional Rule-Automation. + * Goal - Driven Behavior based controlling + * Priority Management +* Automated conflict resolution policies to always serve inhabitants' needs. +* Semantic representation of the smart environment +* Individual configurable access - right management -* [Please follow our developer tool chain setup guide.](https://basecubeone.org/developer/) +## Supported Third Party Frameworks +* [openHAB](https://www.openhab.org) -## Update Gradle Dependencies +## Hands on + +* [Documentation](https://basecubeone.org) +* [Installation](https://basecubeone.org/user/installation.html) + +## Contribution + +Feel free to report feature requests and discovered bugs via [github](https://github.com/openbase/bco/issues/new). +- If you want to contribute to bco, just fork the repositories, apply your changes and create a new pull request. +- For long term contribution you are welcome to apply for an openbase membership via support@openbase.org or by joining our [Discord Server](https://discord.com/invite/M48eh76f?utm_source=Discord%20Widget&utm_medium=Connect). + +## Development + +### How to build BCO + +* [Please follow our developer tool chain setup guide.](https://basecubeone.org/developer/) + +### Update Gradle Dependencies We are using a plugin called `Gradle refreshVersions` to manage all our backend dependencies. Thus, all dependencies declared within `build.gradle.kts` provide a placeholder `_` for their version while each version is maintained within diff --git a/buildSrc/src/main/kotlin/org.openbase.bco.gradle.kts b/buildSrc/src/main/kotlin/org.openbase.bco.gradle.kts index 087d4eb7f0..d96148d006 100644 --- a/buildSrc/src/main/kotlin/org.openbase.bco.gradle.kts +++ b/buildSrc/src/main/kotlin/org.openbase.bco.gradle.kts @@ -12,11 +12,11 @@ plugins { repositories { mavenLocal() + mavenCentral() + google() maven { url = uri("https://oss.sonatype.org/content/groups/public/") } - google() - mavenCentral() } group = "org.openbase" diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..ee2b041087 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.caching = true +org.gradle.daemon=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023..7454180f2a 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897b5..00e33edef6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/lib/jul b/lib/jul index 3069e4404d..c1d8c811d6 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit 3069e4404de02bfcda8096b4f8e414176cff82c1 +Subproject commit c1d8c811d6de2160a33c288ad2623a2402f7b7d6 diff --git a/module/app/util/build.gradle.kts b/module/app/util/build.gradle.kts index 3fd04a2111..6232d51a67 100644 --- a/module/app/util/build.gradle.kts +++ b/module/app/util/build.gradle.kts @@ -87,6 +87,10 @@ createAdditionalScript("bco-logger") { mainClass.set("org.openbase.bco.dal.remote.printer.BCOLogger") } +createAdditionalScript("bco-actions") { + mainClass.set("org.openbase.bco.dal.visual.action.BCOActionInspectorLauncher") +} + distributions { main { distributionBaseName.set("bco") diff --git a/module/app/util/src/main/java/org/openbase/bco/app/util/launch/BCOAdhocTrainDataGeneratorLauncher.java b/module/app/util/src/main/java/org/openbase/bco/app/util/launch/BCOAdhocTrainDataGeneratorLauncher.java index 7aff396fc6..6dc8179c57 100644 --- a/module/app/util/src/main/java/org/openbase/bco/app/util/launch/BCOAdhocTrainDataGeneratorLauncher.java +++ b/module/app/util/src/main/java/org/openbase/bco/app/util/launch/BCOAdhocTrainDataGeneratorLauncher.java @@ -23,10 +23,12 @@ */ import org.openbase.bco.authentication.lib.BCO; +import org.openbase.bco.authentication.lib.jp.JPBCOHomeDirectory; import org.openbase.bco.dal.lib.action.ActionDescriptionProcessor; import org.openbase.bco.dal.lib.jp.JPProviderControlMode; import org.openbase.bco.dal.remote.action.Actions; import org.openbase.bco.dal.remote.layer.unit.ColorableLightRemote; +import org.openbase.bco.dal.remote.layer.unit.LightSensorRemote; import org.openbase.bco.dal.remote.layer.unit.Units; import org.openbase.bco.dal.remote.layer.unit.location.LocationRemote; import org.openbase.bco.registry.remote.Registries; @@ -38,6 +40,8 @@ import org.openbase.jul.exception.CouldNotPerformException; import org.openbase.jul.exception.ExceptionProcessor; import org.openbase.jul.exception.printer.ExceptionPrinter; +import org.openbase.jul.communication.jp.JPComPort; +import org.openbase.jul.communication.jp.JPComHost; import org.openbase.type.domotic.action.ActionDescriptionType.ActionDescription; import org.openbase.type.domotic.service.ServiceTemplateType.ServiceTemplate.ServiceType; import org.openbase.type.domotic.state.IlluminanceStateType.IlluminanceState; @@ -73,26 +77,31 @@ public enum TrainCondition { /** * @param args the command line arguments */ - public static void main(final String[] args) throws JPServiceException { + public static void main(final String[] args) throws JPServiceException, CouldNotPerformException { BCO.printLogo(); + JPService.registerProperty(JPComPort.class); + JPService.registerProperty(JPComHost.class); + JPService.registerProperty(JPBCOHomeDirectory.class); JPService.registerProperty(JPProviderControlMode.class, true); JPService.registerProperty(JPDebugMode.class, false); JPService.registerProperty(JPVerbose.class, false); JPService.parse(args); - BCOLogin.getSession().autoLogin(true); - try { LOGGER.info("please make sure bco is started with the --provider-control flag, otherwise no provider services can be synthesised."); LOGGER.info("waiting for registry synchronization..."); Registries.waitUntilReady(); + LOGGER.info("authenticate..."); + BCOLogin.getSession().loginUserViaUsername("admin", "admin", true); + // init final int trainingSetCounter = 10; LOGGER.info("init simulation of {} runs with {} conditions.", trainingSetCounter, trainConditions.size()); LocationRemote location = Units.getUnit(Registries.getUnitRegistry(true).getUnitConfigByAlias("Location-Adhoc"), true, Units.LOCATION); ColorableLightRemote light = Units.getUnit(Registries.getUnitRegistry(true).getUnitConfigByAlias("ColorableLight-Adhoc"), true, Units.COLORABLE_LIGHT); + LightSensorRemote lightSensor = Units.getUnit(Registries.getUnitRegistry(true).getUnitConfigByAlias("LightSensor-Adhoc"), true, Units.LIGHT_SENSOR); final ActionDescription absentState = ActionDescriptionProcessor.generateActionDescriptionBuilder( PresenceState.newBuilder().setValue(PresenceState.State.ABSENT).build(), @@ -106,11 +115,11 @@ public static void main(final String[] args) throws JPServiceException { final ActionDescription darkState = ActionDescriptionProcessor.generateActionDescriptionBuilder( IlluminanceState.newBuilder().setValue(IlluminanceState.State.DARK).build(), ServiceType.ILLUMINANCE_STATE_SERVICE, - location).build(); + lightSensor).build(); final ActionDescription sunnyState = ActionDescriptionProcessor.generateActionDescriptionBuilder( IlluminanceState.newBuilder().setValue(IlluminanceState.State.SUNNY).build(), ServiceType.ILLUMINANCE_STATE_SERVICE, - location).build(); + lightSensor).build(); LOGGER.info("prepare setup..."); Actions.waitForExecution(location.applyAction(presentState), TIMEOUT, TimeUnit.MILLISECONDS); diff --git a/module/authentication/lib/src/main/java/org/openbase/bco/authentication/lib/future/AbstractAuthenticationFuture.java b/module/authentication/lib/src/main/java/org/openbase/bco/authentication/lib/future/AbstractAuthenticationFuture.java index fe9bc1abe7..af613afc77 100644 --- a/module/authentication/lib/src/main/java/org/openbase/bco/authentication/lib/future/AbstractAuthenticationFuture.java +++ b/module/authentication/lib/src/main/java/org/openbase/bco/authentication/lib/future/AbstractAuthenticationFuture.java @@ -25,6 +25,7 @@ import org.openbase.bco.authentication.lib.AuthenticationClientHandler; import org.openbase.bco.authentication.lib.SessionManager; import org.openbase.jul.exception.CouldNotPerformException; +import org.openbase.jul.exception.ExceptionProcessor; import org.openbase.jul.exception.NotAvailableException; import org.openbase.jul.exception.printer.ExceptionPrinter; import org.openbase.jul.iface.Shutdownable; @@ -106,7 +107,9 @@ public AbstractAuthenticationFuture(final Future internalFuture, final }, 1, 5, TimeUnit.SECONDS); Shutdownable.registerShutdownHook(() -> responseVerificationFuture.cancel(true)); } catch (CouldNotPerformException ex) { - ExceptionPrinter.printHistory("Could not initialize task which makes sure that authenticated response are verified", ex, LoggerFactory.getLogger(AbstractAuthenticationFuture.class)); + if (!ExceptionProcessor.isCausedBySystemShutdown(ex)) { + ExceptionPrinter.printHistory("Could not initialize task which makes sure that authenticated response are verified", ex, LoggerFactory.getLogger(AbstractAuthenticationFuture.class)); + } } } authenticatedFutureList.add(this); diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java index 869149c1a3..8411521316 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java @@ -464,15 +464,16 @@ public Future cancel() { updateActionStateWhileHoldingWriteLock(State.CANCELED); } + // we need to update the transaction id to inform the remote that the action was successful even when already canceled. + try { + unit.updateTransactionId(); + } catch (CouldNotPerformException ex) { + ExceptionPrinter.printHistory("Could not update transaction id", ex, LOGGER); + } + // notify transaction id change try { if (!unit.isDataBuilderWriteLockedByCurrentThread()) { - // we need to update the transaction id to inform the remote that the action was successful even when already canceled. - try { - unit.updateTransactionId(); - } catch (CouldNotPerformException ex) { - ExceptionPrinter.printHistory("Could not update transaction id", ex, LOGGER); - } unit.notifyChange(); } } catch (CouldNotPerformException ex) { @@ -507,7 +508,6 @@ public Future cancel() { } } return getActionDescription(); - }); } catch (RejectedExecutionException ex) { return FutureProcessor.canceledFuture(ActionDescription.class, new CouldNotPerformException("Could not cancel " + this, ex)); @@ -780,6 +780,11 @@ private void updateActionState(final ActionState.State state) throws Interrupted actionDescriptionBuilder.setTerminationTimestamp(TimestampProcessor.getCurrentTimestamp()); } + // make sure that state changes to finishing states, scheduled and executing always trigger a notification + if (isNotifiedActionState(state)) { + unit.notifyScheduledActionList(); + } + } finally { actionDescriptionBuilderLock.writeLock().unlock(); } @@ -788,11 +793,6 @@ private void updateActionState(final ActionState.State state) throws Interrupted synchronized (executionStateChangeSync) { executionStateChangeSync.notifyAll(); } - - // make sure that state changes to finishing states, scheduled and executing always trigger a notification - if (isNotifiedActionState(state)) { - unit.notifyScheduledActionList(); - } } private void validateStateTransition(final ActionState.State state) throws InvalidStateException { diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java index 4c8e035cb5..faf76a59bf 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java @@ -200,6 +200,7 @@ public void update(DataProvider source, UnitRegistryData data) this.addDataObserver(ServiceTempus.REQUESTED, (source, data) -> { // update requested state cache and create timeouts for (ServiceDescription serviceDescription : getUnitTemplate().getServiceDescriptionList()) { + // skip if the service is not an operation service if (serviceDescription.getPattern() != OPERATION) { continue; @@ -1121,6 +1122,16 @@ private Action reschedule(final SchedulableAction actionToSchedule) throws Could } } + public void initRescheduling() { + try { + scheduleTimeout.restart(3, TimeUnit.MILLISECONDS); + } catch (CouldNotPerformException ex) { + if (!ExceptionProcessor.isCausedBySystemShutdown(ex)) { + ExceptionPrinter.printHistory("Could not init rescheduling!", ex, logger); + } + } + } + /** * Update the action list in the data builder and notify. *

@@ -1379,7 +1390,6 @@ public void shutdown() { @Override public void applyDataUpdate(Message newState, final ServiceType serviceType) throws CouldNotPerformException { - try { if (!builderSetup.tryLockWrite(5, TimeUnit.SECONDS, this)) { throw new InvalidStateException("Unit seems to be stuck!"); diff --git a/module/dal/remote/src/main/java/org/openbase/bco/dal/remote/action/RemoteAction.java b/module/dal/remote/src/main/java/org/openbase/bco/dal/remote/action/RemoteAction.java index 7fc89db17d..67e57b2608 100644 --- a/module/dal/remote/src/main/java/org/openbase/bco/dal/remote/action/RemoteAction.java +++ b/module/dal/remote/src/main/java/org/openbase/bco/dal/remote/action/RemoteAction.java @@ -683,7 +683,7 @@ public Future cancel() { } } - // if precomputed, than we are not responsible for the cancelation + // if precomputed, then we are not responsible for the cancelation if(PRECOMPUTED_ACTION_ID.equals(actionId)) { future = FutureProcessor.completedFuture(getActionDescription()); return future; diff --git a/module/dal/test/src/main/java/org/openbase/bco/dal/test/AbstractBCODeviceManagerTest.java b/module/dal/test/src/main/java/org/openbase/bco/dal/test/AbstractBCODeviceManagerTest.java index 8d40fca4c3..a6fa22b957 100644 --- a/module/dal/test/src/main/java/org/openbase/bco/dal/test/AbstractBCODeviceManagerTest.java +++ b/module/dal/test/src/main/java/org/openbase/bco/dal/test/AbstractBCODeviceManagerTest.java @@ -24,6 +24,7 @@ import org.junit.After; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.openbase.bco.dal.control.layer.unit.device.DeviceManagerLauncher; import org.openbase.bco.dal.lib.layer.unit.UnitController; @@ -70,6 +71,7 @@ public static void tearDownClass() throws Throwable { * * @throws InterruptedException is thrown if the thread was externally interrupted */ + @Before @After public void cancelAllOngoingActions() throws InterruptedException { LOGGER.info("Cancel all ongoing actions..."); diff --git a/module/dal/visual/src/main/java/org/openbase/bco/dal/visual/action/BCOActionInspector.java b/module/dal/visual/src/main/java/org/openbase/bco/dal/visual/action/BCOActionInspector.java index ddc484f4e8..b02601c687 100644 --- a/module/dal/visual/src/main/java/org/openbase/bco/dal/visual/action/BCOActionInspector.java +++ b/module/dal/visual/src/main/java/org/openbase/bco/dal/visual/action/BCOActionInspector.java @@ -22,6 +22,9 @@ * #L% */ +import org.openbase.jps.core.JPService; +import org.openbase.jul.communication.jp.JPComHost; +import org.openbase.jul.communication.jp.JPComPort; import org.openbase.jul.visual.javafx.launch.AbstractFXMLApplication; public class BCOActionInspector extends AbstractFXMLApplication { @@ -32,6 +35,8 @@ public BCOActionInspector() { @Override protected void registerProperties() { + JPService.registerProperty(JPComPort.class); + JPService.registerProperty(JPComHost.class); } public static void main(String[] args) { diff --git a/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/TestWaitUntilReady.java b/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/TestWaitUntilReady.java index bdc788b99e..4d815ef8c1 100644 --- a/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/TestWaitUntilReady.java +++ b/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/TestWaitUntilReady.java @@ -75,7 +75,6 @@ public static void setUpClass() throws Throwable { MockRegistry.registerUnitConsistencyHandler(new ConsistencyHandler, ProtoBufMessageMap, ProtoBufRegistry>() { boolean alreadyDelayed = false; - int counter = 0; @Override public void processData(String id, IdentifiableMessage entry, ProtoBufMessageMap entryMap, ProtoBufRegistry registry) throws CouldNotPerformException, EntryModification { diff --git a/old_bco/README.md b/old_bco/README.md deleted file mode 100644 index f0c593bd58..0000000000 --- a/old_bco/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Base Cube One - -This is the official repository of the smart environment framework Base Cube One. -The project is split into different sub-module and each of these sub-module is stored in its own repository. This repository links to all sub-module repositories via ```git-modules```. The ```./workspace-prepare.sh``` script supports you to downloads the sourcecode of the sub-modules. Please checkout the documentation for more details: - -* [Documentation](https://basecubeone.org) -* [User Installation](https://basecubeone.org/user/installation.html) -* [Developer Installation](https://basecubeone.org/developer/) -* [Contribution](https://basecubeone.org/developer/contribution.html) -* [Community](https://openbase.org) diff --git a/old_bco/install.sh b/old_bco/install.sh deleted file mode 100755 index e9e1209ae8..0000000000 --- a/old_bco/install.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -all ./install.sh $@ diff --git a/old_bco/prepare.sh b/old_bco/prepare.sh deleted file mode 100755 index c19766f495..0000000000 --- a/old_bco/prepare.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -git $@ submodule init -git $@ submodule update --remote - -# link to branch -git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)' - diff --git a/old_bco/reset.sh b/reset.sh similarity index 100% rename from old_bco/reset.sh rename to reset.sh diff --git a/settings.gradle.kts b/settings.gradle.kts index 0d74c7e435..cda0ffca47 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,5 @@ rootProject.name = "bco" + include("authentication") include("registry") include("dal") @@ -97,9 +98,7 @@ project(":bco.dal.control").projectDir = file("module/dal/control") project(":bco.dal.lib").projectDir = file("module/dal/lib") project(":bco.dal.visual").projectDir = file("module/dal/visual") project(":bco.dal.test").projectDir = file("module/dal/test") - project(":bco.api.graphql").projectDir = file("module/api/graphql") - project(":bco.app.manager").projectDir = file("module/app/manager") project(":bco.app.util").projectDir = file("module/app/util") project(":bco.app.base").projectDir = file("module/app/base") @@ -110,10 +109,12 @@ project(":bco.app.test").projectDir = file("module/app/test") project(":bco.device.openhab").projectDir = file("module/device/openhab") +// includeBuild("lib/type") // not supported yet since its not a gradle project +includeBuild("lib/jul") + pluginManagement { plugins { - id("de.fayard.refreshVersions") version "0.40.0" -//// # available:"0.40.1" + id("de.fayard.refreshVersions") version "0.40.1" } } diff --git a/versions.properties b/versions.properties index 87db2c04ac..5d8f27c78f 100644 --- a/versions.properties +++ b/versions.properties @@ -1,5 +1,5 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.40.0 +#### Generated by `./gradlew refreshVersions` version 0.40.1 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -138,72 +138,72 @@ version.kotlin=1.6.10 ## # available=1.6.255-SNAPSHOT ## # available=1.7.255-SNAPSHOT -version.org.openbase..jul.communication.controller=3.0-SNAPSHOT +version.org.openbase..jul.communication.controller=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.communication.mqtt=3.0-SNAPSHOT +version.org.openbase..jul.communication.mqtt=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.exception=3.0-SNAPSHOT +version.org.openbase..jul.exception=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.extension.protobuf=3.0-SNAPSHOT +version.org.openbase..jul.extension.protobuf=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.extension.type.processing=3.0-SNAPSHOT +version.org.openbase..jul.extension.type.processing=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.extension.type.storage=3.0-SNAPSHOT +version.org.openbase..jul.extension.type.storage=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.extension.type.transform=3.0-SNAPSHOT +version.org.openbase..jul.extension.type.transform=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.extension.type.util=3.0-SNAPSHOT +version.org.openbase..jul.extension.type.util=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.pattern.launch=3.0-SNAPSHOT +version.org.openbase..jul.pattern.launch=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.pattern.trigger=3.0-SNAPSHOT +version.org.openbase..jul.pattern.trigger=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.processing=3.0-SNAPSHOT +version.org.openbase..jul.processing=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.storage=3.0-SNAPSHOT +version.org.openbase..jul.storage=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.visual.javafx=3.0-SNAPSHOT +version.org.openbase..jul.visual.javafx=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2 -version.org.openbase..jul.visual.swing=3.0-SNAPSHOT +version.org.openbase..jul.visual.swing=3.1-SNAPSHOT ## # available=3.0.0 ## # available=3.0.1 ## # available=3.0.2