diff --git a/.classpath b/.classpath index 08850775..12a87fb0 100644 --- a/.classpath +++ b/.classpath @@ -4,7 +4,8 @@ - + + @@ -20,7 +21,6 @@ - @@ -71,10 +71,9 @@ - + - diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 00000000..8c0539ae --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,31 @@ +# This workflow will build a Java project with Gradle + +name: Java CI with Gradle + +# Triggers the workflow on push events (on every branch) +on: + push: + branches: + - '*' +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Set up JDK 17 + uses: actions/setup-java@v1 + with: + java-version: 17 + + - name: Set up Arangodb + uses: xinova/arangodb-action@v1 + with: + arangodb version: 'latest' # See https://hub.docker.com/_/arangodb for available versions + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build WebOCD Service + run: ./gradlew build \ No newline at end of file diff --git a/.project b/.project index eff6925b..7f273d7a 100644 --- a/.project +++ b/.project @@ -20,4 +20,15 @@ org.eclipse.jdt.core.javanature org.eclipse.buildship.core.gradleprojectnature + + + 1643825602746 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/Dockerfile b/Dockerfile index 24e966c7..1d46f6f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:14-alpine +FROM openjdk:17-alpine COPY . /usr/src/webocd WORKDIR /usr/src/webocd RUN apk update && apk add bash \ @@ -8,8 +8,22 @@ RUN apk update && apk add bash \ ghostscript-fonts \ build-base # Fetch fitting gradle version manually because so far no os container has both jdk14 and a high enough gradle package version -RUN mkdir ../gradleFolder && wget https://services.gradle.org/distributions/gradle-6.8.3-bin.zip -P ../gradleFolder \ - && unzip -d ../gradleFolder ../gradleFolder/gradle-6.8.3-bin.zip && rm -R ../gradleFolder/gradle-6.8.3-bin.zip -RUN ../gradleFolder/gradle-6.8.3/bin/gradle build +RUN mkdir ../gradleFolder && wget https://services.gradle.org/distributions/gradle-7.3.2-bin.zip -P ../gradleFolder \ + && unzip -d ../gradleFolder ../gradleFolder/gradle-7.3.2-bin.zip && rm -R ../gradleFolder/gradle-7.3.2-bin.zip + +# Replace HOST for database configuration (standard & for testing) with the db container name +RUN sed -i "s/^HOST.*/HOST=arangodb/" ocd/arangoDB/config_test.properties +RUN sed -i "s/^HOST.*/HOST=arangodb/" ocd/arangoDB/standard_config.properties + + +# This is to clean the previously generated agents and avoid error in case WebOCD was built before image creation +RUN ../gradleFolder/gradle-7.3.2/bin/gradle clean + +# Execute gradle build and tests excluding db tests +RUN ../gradleFolder/gradle-7.3.2/bin/gradle build -x test +RUN ../gradleFolder/gradle-7.3.2/bin/gradle testWithoutDB + +# Add a loop that waits for arangodb to run, before webocd service starts when start_network.sh is used +RUN sed -i '2 i while ! nc -z arangodb 8529; do sleep 10; done' bin/start_network.sh RUN chmod +x bin/start_network.sh -CMD ["bin/start_network.sh"] +CMD ["bin/start_network.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 98ee89c8..5ba9bea3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # OCD Service - WebOCD -This is a RESTful web service offering various overlapping community detection algorithms(OCDA) and centrality measures/simulations. The service is developed with the Eclipse IDE and IntelliJ, so we recommend you to use one of these tools to work on the project.
+This is a RESTful web service offering various overlapping community detection algorithms(OCDA) and centrality measures/simulations. The service is developed with the IntelliJ IDE, so we recommend you to use this tool to work on the project.
**WebOCD works best with its corresponding [web client](https://github.com/rwth-acis/OCD-Web-Client)**. A running instance of WebOCD can be found at http://webocd.dbis.rwth-aachen.de/OCDWebClient/. @@ -9,3 +9,20 @@ For any information on the service itself please refer to the [project wiki](htt ### Additional Notes This service is based on the LAS2peer Template Project and its underlying LAS2peer framework. For any information on these please refer to https://github.com/rwth-acis/LAS2peer-Template-Project and https://github.com/rwth-acis/LAS2peer + +# Building & Running WebOCD Service + +WebOCD Service requires a running arangodb instance, which has to be [installed separately](https://www.arangodb.com/docs/stable/installation.html). In order for WebOCD to access the database, the configuration files, located under [ocd/arangoDB](/ocd/arangoDB) should be adjusted accordingly. + +The service can be built using the gradle build task. Afterwards, it can be run using start_network.sh/start_network.bat scripts located in the [bin](/bin) directory (Consider changing the java heap size in the file with the ```-Xmx``` parameter to avoid storage allocation issues). + +Alternatively, Docker can be used, as explained below, to run the WebOCD service and database in one line. + +# Quickstart Docker +To build and run WebOCD Service using Docker, you can navigate to the REST-OCD-Service directory and execute +``` +docker compose up +``` +This will build and run containers for WebOCD service and arangodb, which is required for the service to run properly. + +You can adjust the database container default password by modifying docker-compose.yml. Keep in mind to also change the config file [config.properties](ocd/arangoDB/config.properties), so that WebOCD tests as well as the service can use the database. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..72a7a501 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3' +services: + arangodb: + image: arangodb + container_name: webocd-arangodb + ports: + - "127.0.0.1:8529:8529" + environment: + - ARANGO_ROOT_PASSWORD=password + webocd-service: + container_name: webocd-service + stdin_open: true # docker run -i + tty: true # docker run -t + restart: on-failure + depends_on: + - arangodb + build: + context: . + dockerfile: ./Dockerfile + links: + - arangodb + ports: + - "127.0.0.1:8080:8080" \ No newline at end of file diff --git a/docs/pages/index.md b/docs/pages/index.md index 555a8103..ce6c1e12 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -28,10 +28,10 @@ The OCD Service is publicly accessible via this [link](http://webocd.dbis.rwth-a Along with the service we provide a web client which also has its own [project](https://github.com/rwth-acis/OCD-Web-Client). The client can only be used with a valid Learning Layers account. We recommend to use the service along with the web client. -We additionally provide a brief [Integration Tutorial](/integration/) that shows you the usage of the most important requests so that you can get started with the OCD Service more quickly. +We additionally provide a brief [Integration Tutorial](/REST-OCD-Services/pages/wiki/integration/) that shows you the usage of the most important requests so that you can get started with the OCD Service more quickly. A more detailed usage examples of WebOCD Service, using the WebOCD webclient can be found here [link](/REST-OCD-Services/pages/tutorials/login). ## The OCD Service -The service is developed using the Eclipse IDE, so we recommend you to stick to that tool for any work on this project. +The service is developed using the IntelliJ IDEA, so we recommend you to stick to that tool for any work on this project. Please refer to the following pages in order to obtain more information about the OCD Service. @@ -41,9 +41,10 @@ Please refer to the following pages in order to obtain more information about th + [User Management and Authentication](/REST-OCD-Services/pages/wiki/user-management-and-authentication) + [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) + [Database Configuration](/REST-OCD-Services/pages/wiki/database-configuration) ++ [Tutorials using WebOCD Service and Webclient](/REST-OCD-Services/pages/tutorials/login) ### Important -The OCD Service is largely based on the commercial **yFiles** library. You will only be able to run it yourself if you have access to the archive _y.jar_. The Chair i5 of RWTH Aachen University has a license for that library. If you are affiliated with that institute, please contact somebody to obtain the library. Also, keep in mind that the archive mentioned above must under no circumstances be publicly deployed or otherwise made publicly available. Please refer to [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) for more information. +The WebOCD Service uses **ArangoDB** database, which has to be separately installed on the machine where the service runs. Alternatively, docker can be used to build the WebOCD Service together with the database. To build and run WebOCD Service with Docker, refer to [link](/REST-OCD-Services/pages/wiki/running#docker). -The service also currently requires **Java JDK 14** to be built and most likely also to run it. However, there also exists an older version for JDK 8 (tag [1.0.0](https://github.com/rwth-acis/REST-OCD-Services/tree/1.0.0)) which is still functional in case you need it. +The service also currently requires **Java JDK 17** to be built and most likely also to run it. However, there also exists an older version for JDK 8 (tag [1.0.0](https://github.com/rwth-acis/REST-OCD-Services/tree/1.0.0)) which is still functional in case you need it. diff --git a/docs/pages/wiki/build-process.md b/docs/pages/wiki/build-process.md index 5b031fc3..38733e95 100644 --- a/docs/pages/wiki/build-process.md +++ b/docs/pages/wiki/build-process.md @@ -4,59 +4,27 @@ title: Build Process --- # Introduction -The OCD Service is built via Gradle. We recommend a version similar to 6.8, yet others may also work. The project has mostly been developed with the Eclipse IDE using the gradle buildship plugin (most eclipse IDEs already include this), yet IDEs like IntelliJ are actively used as well. Finally note that you will likely need Java version 14 for the build to work without problems. - -There also exists an older version using Apache Ant which is described at the bottom. Here, there are two build files, _build.xml_, and _ocd_build.xml_. Please do only use the _ocd_build.xml_. Note that Eclipse might illustrate errors for the build file because apparently it is not able to resolve the external target dependencies to the second build file correctly. This should not cause an issue. It is highly recommended that you build the project with Eclipse (To use Java 8 for the older version you may have to go with the Eclipse IDE for Java EE Developers variant) as this is the environment used during development and therefore the best tested one. +The OCD Service is built via Gradle. We recommend a version similar to 7.3, yet newer versions may also work. The project has mostly been developed with the IntelliJ IDEA. You can import the project into IntelliJ as a Gradle project. Finally note that you will likely need Java version 17 for the build to work without problems. # Executing the Build Process ## First Build -When you are going to run the build process the very first time, you will need two manually obtain two libraries: -+ _y.jar_ forms part of the commercial yFiles library by yWorks which is not publicly available. Therefore you will have to add it manually to the project. The Chair i5 of RWTH Aachen University has a license for the library, so please contact somebody to obtain access. This will obviously only be possible if you are somehow affiliated with the Chair. -+ _ysvg.jar_ is an SVG writer for yFiles Graph2D objects that makes it possible to add useful features to generated SVG diagrams. The library is used for the visualization of graphs and covers. -Both libraries then have to be placed into the _yFiles_ folder. - -Now, you just have to import the project as a gradle project via eclipse or simply open in via IntelliJ. After the first build, eclipse might still give you errors saying the yFiles jars are missing. To fix this, simply refresh the gradle project via the option you get from right clicking the folder. +When you are going to run the build process the very first time, you just have to import the project as a gradle project IntelliJ and execute the gradle *build* task. Make sure to adapt the database configuration _ocd/arangoDB/config.properties_ to fit your running ArangoDB instance. After the build, you can then either start the _start_network.bat_ or _start_network.sh_ files in the bin folder to get the service running, see [Running the OCD Service](/REST-OCD-Services/pages/wiki/running) for more information. ## General Build -There are numerous targets which can be run. This summarizes the most important ones: +There are numerous gradle tasks which can be executed. This summarizes the most important ones: + _jar_: Generates the service jar in the _service_ and a copy in the _rest\_ocd\_services/export/jars_ directory. This archive is required for running the service. + _test_: Runs all jUnit tests . The test reports are stored in _rest\_ocd\_services/export/test_reports_. -+ _yguard_: Generates an obfuscated service jar in the _rest\_ocd\_services/export/obfuscated_ directory. This is required for public service deployment. Please refer to [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) for more information. A log file of the obfuscation process is stored under _ocd/yGuard/log.xml_. + _build_: The target you'll likely be running most of the time. This executes the build process and generates a jar as well as the executables. ++ _startscripts:_ Generates startscripts into the bin folder that are used to start the service. ++ _generateAgents_: Generates the user and service agents as specified in _build.gradle_. The users will be loaded when the service (or more precisely the underlying LAS2peer node) is launched. ++ _clean_: Clean up files generated from the build. This should be executed before rebuilding. -# Potential Issues - -Currently, the build might fail if a version of Java not equal to 14 (or 8 for the older version of the service) is used, even with eclipse in compliance mode for that version, and running the service with a version other than this one is also likely to cause errors. - -## Linux Users -The system was mainly tested on Windows so far. For Linux, there is still a small issue with the old Ant Build. In case you receive an exception that the database (_db_) could not be created, please do manually remove the directory _db_ from the _ocd_ directory before the build. - - -# Executing the Old Ant Build Process - -## First Build -When you are going to run the build process the very first time, please make sure to run the target _get_deps_ in order to obtain all dependencies. - -Due to the yFiles library being commercial, there are three dependencies which will be missing and must be added manually to the _lib_ folder: -+ _y.jar_ forms part of the commercial yFiles library by yWorks which is not publicly available. Therefore you will have to add it manually to the project. The Chair i5 of RWTH Aachen University has a license for the library, so please contact somebody to obtain access. This will obviously only be possible if you are somehow affiliated with the Chair. -+ _yguard.jar_ is a free obfuscation tool by yWorks which is only required for public deployment of the service. Anybody can download it from this [link](https://www.yworks.com/downloads#yGuard). Refer to [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) for more information. You can probably do without it. -+ _ysvg.jar_ is an SVG writer for yFiles Graph2D objects that makes it possible to add useful features to generated SVG diagrams. The library is used for the visualization of graphs and covers. -## Linux Users -Please make sure that the program _ocd/lfr/LfrBenchmarkLinux_ is executable (via `chmod +x `). +# Potential Issues +Currently, the build might fail if a version of Java not equal to 17 is used. -## General Build -There are numerous targets which can be run. This summarizes the most important ones: -+ _jar_: Generates the service jar in the _service_ and a copy in the _export/jars_ directory. This archive is required for running the service. -+ _generate_configs_: Generates the user and service agents as specified in _etc/ant_configuration_. The users will be loaded when the service (or more precisely the underlying LAS2peer node) is launched. -+ _junit_: Runs all jUnit tests (except _src/test/i5/las2peer/services/ocd/DatabaseInitializer.java_, take look at the target _setup_database_ for more information). The test reports are stored in _export/test_reports_. -+ _startscripts:_ Generates startscripts into the bin folder that are used to start the service. -+ _obfuscate_: Generates an obfuscated service jar in the _export/obfuscated_ directory. This is required for public service deployment. Please refer to [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) for more information. A log file of the obfuscation process is stored under _ocd/yGuard/log.xml_. -+ _setup_database_: This is intended for automatically populating the database for presentation or debugging purposes. It is not required in any way to actually make the database work. The database is set up by running _src/test/i5/las2peer/services/ocd/DatabaseInitializer.java_ as a jUnit test. You can adapt the code in any way that suits your needs. -+ _all_: Runs all of the above except _setup_database_. +Running WebOCD Service might cause *AgentAccessDeniedException* if the *build* task was performed multiple times without having performed the *clean* task inbetween. If this occurs, simply do the *clean* task followed by the *build* task and the issue should be solved. -## Building with IntelliJ -For IntelliJ, you can follow the above guide as well. For correct indexing in the IDE you however need to add the lib folder as a library via right click. You might also want to double check that build.xml isn't selected as an ant build file instead of ocd_build.xml diff --git a/docs/pages/wiki/database-configuration.md b/docs/pages/wiki/database-configuration.md index 8607f2c5..8e16a67c 100644 --- a/docs/pages/wiki/database-configuration.md +++ b/docs/pages/wiki/database-configuration.md @@ -3,11 +3,8 @@ layout: page title: Database Configurations --- -# JPA and persistence.xml -The service makes use of the Java Persistence API (JPA) specification to simplify database access. The JPA implementation that is being used is EclipseLink. If you want to use the service with another database or change some aspects of the database configuration you must adapt the following files accordingly. -+ _rest\_ocd\_services/src/main/java/META-INF/persistence.xml_: This database configuration is used for the actual execution of the service through the service jar (e.g. when running _bin/start_network.bat_) -+ _rest\_ocd\_services/src/main/java/META-INF/testing/persistence.xml_: This database configuration is used during jUnit testing. +# ArangoDB +The service makes use of ArangoDB database. A database instance should be running before executing the build process. Otherwise, the database related tests will fail. +Database instance details that WebOCD Service uses can be configured by changing the _ocd/arangoDB/config.properties_ file. -The file locations are different in the old ant build: -+ _ocd/eclipselink/persistence.xml_ for the execution -+ _src/META-INF/persistence.xml_ for testing \ No newline at end of file +If the database is not available on the machine where WebOCD Service should run, it is possible to use Docker, without installing/running the database first. For this refer to [Running the OCD Service](/REST-OCD-Services/pages/wiki/running#docker). diff --git a/docs/pages/wiki/integration.md b/docs/pages/wiki/integration.md index f52dade5..8fd3f4e6 100644 --- a/docs/pages/wiki/integration.md +++ b/docs/pages/wiki/integration.md @@ -4,13 +4,15 @@ title: Integration --- # Introduction -This tutorial will give you a brief explanation about how to handle the OCD Service. It explains a few basic requests for e.g. uploading a graph, retrieving the saved graphs, creating a cover from a graph, ... +This tutorial will give you a brief explanation about how to handle the OCD Service. It explains a few basic requests for e.g. uploading a graph, retrieving the saved graphs, creating a cover from a graph etc. -However this is only a fraction of what the service actually allows. Other functionalities include for instance the execution of metrics to determine the quality of the calculated covers or the computation of benchmark graphs and covers for the generation of standardized testing data. +However, this is only a fraction of what the service actually allows. Other functionalities include for instance the execution of metrics to determine the quality of the calculated covers or the computation of benchmark graphs and covers for the generation of standardized testing data. At the bottom, an overview of all possible requests is given. For a more detailed description of the requests you should refer to the OCD Service's source code. All responses other than actual graph and cover data (which has the specified output format), as well as JSON visualization data are sent in XML format. +For more detailed information about using WebOCD Service, refer to the [tutorials](/REST-OCD-Services/pages/tutorials/login), which explains usage of WebOCD Service with the [WebClient](https://github.com/rwth-acis/OCD-Web-Client) + # Graphs ## List Available Graphs @@ -115,7 +117,7 @@ After that, make a post request to run the algorithm with the following paramete + _name_: Email_Cover + _algorithm_: _SPEAKER_LISTENER_LABEL_PROPAGATION_ALGORITHM_ + _body_: `` -`memorySize100probabilityThreshold0.15` + `memorySize100probabilityThreshold0.15` + _contentWeighting_: false + _componentNodeCountFilter_: 0 diff --git a/docs/pages/wiki/project-structure.md b/docs/pages/wiki/project-structure.md index 020df142..cc7096e9 100644 --- a/docs/pages/wiki/project-structure.md +++ b/docs/pages/wiki/project-structure.md @@ -7,19 +7,18 @@ title: Project Structure This page gives you an overview over the file structure of the OCD Service Project. The focus will be set on the _ocd_ directory where most service specific files are located (aside from the source code). Some other files will be discussed as well. For more information on the remaining files you may refer to the LAS2peer Template Project or LAS2peer documentation. # Source Code -The actual source code of the service is located under _rest\_ocd\_services/src/main/java_. The most important class here is probably the _i5/las2peer/services/ocd/ServiceClass.java_ which contains the entire Service API. You will also find the _META-INF_ directory with the persistence.xml files. For more information on this aspect take a look at [Database Configuration](/REST-OCD-Services/pages/wiki/database-configuration). +The actual source code of the service is located under _rest\_ocd\_services/src/main/java_. The most important class here is probably the _i5/las2peer/services/ocd/ServiceClass.java_ which contains the entire Service API. -The source code for the jUnit tests is in _rest\_ocd\_services/src/test_. This directory includes also the _src/test/i5/las2peer/services/ocd/DatabaseInitializer.java_ which can be used for database initialisation. For more information please refer to [Build Process](/REST-OCD-Services/pages/wiki/build-process). +The source code for the jUnit tests is in _rest\_ocd\_services/src/test_. + +ArangoDB database configuration file *config.properties* is located in *ocd/arangoDB* directory. This file can be modified to adjust database used for WebOCD Service as well as tests. For more information please refer to [Build Process](/REST-OCD-Services/pages/wiki/database-configuration). # OCD Directory The _ocd_ directory contains most files apart from the source code which are specific to the OCD Service. You will find the following subdirectories. -+ _db_: Contains the database of the JPA provider. ++ _arangoDB_: Contains the database configuration file. + _eclipselink_: Any log files for database creation or dropping created by the EclipseLink JPA persitence provider will be stored here. -+ _lfr_: Provides an application from Lancichinetti for calculating the LFR benchmarks he introduced (for directed and weighted graphs). It is compiled once for each Linux and Windows. + _test_: Contains a folder with data files for jUnit test input. An additional folder for test output files may be created during the build. -+ _yGuard_: Any log files of the obfuscation process will be stored here. Please refer to [Deploying the OCD Service](Deploying the OCD Service) for more information. -+ (_ivy_ if using the old ant build: Contains an _ocd_ivy.xml_ file to load the service's dependencies via Ivy. Note that there is an additional _ivy.xml_ and _ivy.settings_ file for dependencies required by LAS2peer under _etc/ivy_ from the root directory.) # Other Important Resources + _bin_: Comprises scripts for launching the service and generating Agents. @@ -27,6 +26,3 @@ The _ocd_ directory contains most files apart from the source code which are spe + _service_: This directory contains the service jar. Please refer to [Build Process](/REST-OCD-Services/pages/wiki/build-process) for more information. + _bin/start_network.bat_ and _bin/start_network.sh_: Skripts for launching the OCD Service. Please refer to [Running the OCD Service](/REST-OCD-Services/pages/wiki/running) for more information. + _etc/startup/passphrases.txt_: Password storage for preinstalled users. Please refer to [User Management and Authentication](/REST-OCD-Services/pages/wiki/user-management-and-authentication) for more information. -+ (_ocd_build.xml_ if using the old ant build: The build file for the OCD Service. Please do only make use of this build file. Please refer to [Build Process](/REST-OCD-Services/pages/wiki/build-process) for more information.) -+ (_ocd.conf_ if using the old ant build: Upstart script for the OCD Service. Please refer to [Deploying the OCD Service](/REST-OCD-Services/pages/wiki/service-deployment) for more information.) -+ (_etc/ant_configuration/user.properties_ if using the old ant build: Ant property file for user agent generation. Please refer to [User Management and Authentication](/REST-OCD-Services/pages/wiki/user-management-and-authentication) for more information.) \ No newline at end of file diff --git a/docs/pages/wiki/running.md b/docs/pages/wiki/running.md index b105fe31..6408fd35 100644 --- a/docs/pages/wiki/running.md +++ b/docs/pages/wiki/running.md @@ -11,12 +11,20 @@ Before you start the service you might want to configure the _start_network.bat_ Use `chmod +x ` to allow the execution of the scripts. # Running the Service -Once the database is accessible, you can launch the service on a single node LAS2peer network with the scripts _start_network.bat_ or _start_network.sh_ which are located in the _bin_ directory. The service should be running within a few seconds and be available as a REST service under the basepath _`http://127.0.0.1:8080/ocd/`_ (Note that your browser will display a 404 if you type in this adress, to see if the service is running check the address without the _`/ocd`_ part instead). You can terminate the process by either typing _exit_ in the interactive console or of course also by any other common means. +Once the arangoDB instance is accessible, you can launch the service on a single node LAS2peer network with the scripts _start_network.bat_ or _start_network.sh_ which are located in the _bin_ directory. The service should be running within a few seconds and be available as a REST service under the basepath _`http://127.0.0.1:8080/ocd/`_ (Note that your browser will display a 404 if you type in this address, to see if the service is running check the address without the _`/ocd`_ part instead). You can terminate the process by either typing _exit_ in the interactive console or of course also by any other common means. It is recommended that you use the OCD Service in combination with the web client at https://github.com/rwth-acis/OCD-Web-Client, which will take care of formulating the right requests and especially the login process for you as well as provide JSON visualization. +# Docker +To build and run WebOCD Service using Docker, you can navigate to the REST-OCD-Service directory and execute +``` +docker compose up +``` +This will build and run containers for WebOCD service and ArangoDB database, which is required for the service to run properly. + +You can adjust the database container default password by modifying *docker-compose.yml*. Keep in mind to also change the config file *ocd/arangoDB/config.properties*, so that WebOCD tests as well as the service can use the database. # Potential Issues -Your service might run into the _java.lang.outOfMemoryError_, this indicates that the heap size of the program is most likely to small. You can increase the maximum size by adding the -Xmx parameter in the _start_network_ files. For information on how to use it, please refer to the official Documentation [here](https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html). +Your service might run into the _java.lang.outOfMemoryError_, this indicates that the heap size of the program is most likely to small. You can increase the maximum size by adding the -Xmx parameter in the _start_network_ files. For information on how to use it, please refer to the official Documentation (https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html) If you are getting a warning about encryption problems then you most likely have to change the Security Policy Files of your JRE. This can also happen after a JRE update. Please refer to the Las2Peer Template Project for more information. \ No newline at end of file diff --git a/docs/pages/wiki/service-deployment.md b/docs/pages/wiki/service-deployment.md index 435cd0fb..6050e9bb 100644 --- a/docs/pages/wiki/service-deployment.md +++ b/docs/pages/wiki/service-deployment.md @@ -4,10 +4,7 @@ title: Service Deployment --- # Building -If you want to deploy the OCD Service to a server, the service must first be build. There are two basic alternatives. Either you directly build the project on the machine where it should be deployed, or you build it on some other machine and then move the files to their designated location. You will have to execute the _jar_ target in order to create the service jar. Please refer to [Build Process](Build Process) for more information. Make sure you also generate the user agents for any required user accounts through the target by altering the gradle build file accordingly and running the _jar_ target, if needed. - -# Public Deployment: Obfuscation -The OCD Service makes heavy use of the archive _y.jar_ which is part of the commercial yFiles framework by yWorks. The Chair i5 of RWTH Aachen University has a license allowing the usage of this software. However, it is not allowed to make this library publicly accessible to others. Therefore, if you intend to deploy the OCD Service on a public machine (accessible to people which are not affiliated with the chair) you must obfuscate that library. For this purpose you will require the archive _yguard.jar_ which is offered for free by yWorks. The _yguard_ target will help you with the obfuscation. Please refer to [Build Process](Build Process) for more information. For the obfuscation requirements concerning yFiles and more information on yGuard please refer to the corresponding documentation by yWorks. Also make sure that the yGuard log file under _ocd/yGuard/log.xml_ is not being deployed. +If you want to deploy the OCD Service to a server, the service must first be build. There are two basic alternatives. Either you directly build the project on the machine where it should be deployed, or you build it on some other machine and then move the files to their designated location. You will have to execute the _jar_ target in order to create the service jar. Please refer to [Build Process](/REST-OCD-Services/pages/wiki/build-process) for more information. Make sure you also generate the user agents for any required user accounts through the target by altering the gradle build file accordingly and running the _jar_ target, if needed. # Additional Aspects There are a few additional aspects that should be taken under consideration. First of all, there are several project folders which do not need to be deployed. After completing the build, only the following resources are relevant for the service execution, any others may be removed. @@ -23,8 +20,7 @@ There are a few additional aspects that should be taken under consideration. Fir + README.md + (ocd.conf in the old and build) -Please keep in mind again that in the case of a public deployment the yGuard log file must not be deployed. -Also, when deploying on a Linux system, make sure with `chmod +x ` that the execution of all relevant scripts and programs is allowed. Besides the scripts to launch the service and the database this includes also the LFR Benchmark Application. Please refer to [Project Structure](Project Structure) for more information. +Also, when deploying on a Linux system, make sure with `chmod +x ` that the execution of all relevant scripts and programs is allowed. Please refer to [Project Structure](/REST-OCD-Services/pages/wiki/project-structure/) for more information. Remember also that the Security Policy Files of the JRE being used on the server will in some cases have to be changed, please refer to the LAS2peer Template Project for more information. \ No newline at end of file diff --git a/docs/pages/wiki/user-management-and-authentication.md b/docs/pages/wiki/user-management-and-authentication.md index 69d497e9..1655b3a4 100644 --- a/docs/pages/wiki/user-management-and-authentication.md +++ b/docs/pages/wiki/user-management-and-authentication.md @@ -9,7 +9,7 @@ This part deals with manually adding users which should not be necessary if you # User Management -You can preinstall up to three users via the Ant build target _generate_configs_. For that purpose the users must be defined in the Ant property file _etc/ant_configuration/user.properties_ and the corresponding password in _etc/startup/passphrases.txt_. For preinstalling more users you will have to adapt the _build.xml_ in the root directory accordingly. +You can preinstall up to three users via the gradle task _generateAgents_. For that purpose the users must be defined in the *gradle.properties* file. It is also possible to manually add LAS2peer user agents to an existing network. Please refer to the LAS2peer Template Project and LAS2peer for more information. diff --git a/etc/userLimitInformation.json b/etc/userLimitInformation.json new file mode 100644 index 00000000..88fc0edc --- /dev/null +++ b/etc/userLimitInformation.json @@ -0,0 +1,16 @@ +[ + { + "username": "default", + "allowedInactiveDays": "30", + "graphSize": "1000", + "graphCount": "10", + "coverCount": "15" + }, + { + "username": "user1", + "allowedInactiveDays": "5", + "graphSize": "1000", + "graphCount": "5", + "coverCount": "10" + } +] \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3c07660e..a78c7581 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ -core.version=1.1.1 +core.version=1.2.2 service.name=i5.las2peer.services.ocd service.class=ServiceClass service.version=1.0.0 -java.version=14 +java.version=17 las2peer_user1.name=alice las2peer_user1.password=pwalice diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 442d9132..d2880ba8 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-6.8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/ocd/arangoDB/config.properties b/ocd/arangoDB/config.properties new file mode 100644 index 00000000..f7ecc4ae --- /dev/null +++ b/ocd/arangoDB/config.properties @@ -0,0 +1,6 @@ +PORT=8529 +PASSWORD=password +DATABASENAME=ocdDB +TESTDATABASENAME=testDB +HOST=127.0.0.1 +USER=root diff --git a/ocd/eclipselink/serviceCreateDDL.jdbc b/ocd/eclipselink/serviceCreateDDL.jdbc index 3ae4a39b..adce6aa5 100644 --- a/ocd/eclipselink/serviceCreateDDL.jdbc +++ b/ocd/eclipselink/serviceCreateDDL.jdbc @@ -1,4 +1,4 @@ -CREATE TABLE SIMULATIONSERIESGROUP (ID BIGINT NOT NULL, COOPERATIVIATY REAL, NAME VARCHAR(255), USERID BIGINT, WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, graphId BIGINT, username VARCHAR(255), PRIMARY KEY (ID)) +CREATE TABLE SIMULATIONSERIESGROUP (ID BIGINT NOT NULL, COOPERATIVIATY REAL, NAME VARCHAR(255), USERID VARCHAR(255), WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, graphId BIGINT, username VARCHAR(255), PRIMARY KEY (ID)) CREATE TABLE COVER (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, NAME VARCHAR(255), SIMILARITYCOSTS REAL, CREATION_METHOD BIGINT, GRAPH_ID BIGINT NOT NULL, USER_NAME VARCHAR(255) NOT NULL, PRIMARY KEY (ID, GRAPH_ID, USER_NAME)) CREATE TABLE AGENTDATA (ID BIGINT NOT NULL, COOPERATIVITY REAL, FINALPAYOFF REAL, FINALSTRATEGY BOOLEAN, WEALTH REAL, DATASET_ID BIGINT, AGENTDATA_ID BIGINT, PRIMARY KEY (ID)) CREATE TABLE CENTRALITYMAP (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, MAP LONGVARBINARY, NAME VARCHAR(255), CREATION_METHOD BIGINT, GRAPH_ID BIGINT NOT NULL, USER_NAME VARCHAR(255) NOT NULL, PRIMARY KEY (ID, GRAPH_ID, USER_NAME)) @@ -6,13 +6,13 @@ CREATE TABLE CUSTOMNODE (INDEX INTEGER GENERATED BY DEFAULT AS IDENTITY (START W CREATE TABLE CUSTOMGRAPH (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, USER_NAME VARCHAR(255) NOT NULL, NAME VARCHAR(255), INDEX_PATH VARCHAR(255), CREATION_METHOD BIGINT, PRIMARY KEY (ID, USER_NAME)) CREATE TABLE COVERCREATIONLOG (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, STATUS INTEGER, TYPE INTEGER, PRIMARY KEY (ID)) CREATE TABLE GRAPHCREATIONLOG (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, STATUS INTEGER, TYPE INTEGER, PRIMARY KEY (ID)) -CREATE TABLE SIMULATIONSERIES (ID BIGINT NOT NULL, COOPERATIVIATY REAL, GENERATIONS INTEGER, NAME VARCHAR(255), USERID BIGINT, WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, CONDITION VARCHAR(255), DYNAMIC VARCHAR(255), DYNAMICVALUE REAL, GAME VARCHAR(255), graphId BIGINT, GRAPHNAME VARCHAR(255), ITERATIONS INTEGER, MAXITERATIONS INTEGER, MINITERATIONS INTEGER, PAYOFFCC REAL, PAYOFFCD REAL, PAYOFFDC REAL, PAYOFFDD REAL, SIMULATIONNAME VARCHAR(255), THRESHOLD INTEGER, TIMEWINDOW INTEGER, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, username VARCHAR(255), PRIMARY KEY (ID)) +CREATE TABLE SIMULATIONSERIES (ID BIGINT NOT NULL, COOPERATIVIATY REAL, GENERATIONS INTEGER, NAME VARCHAR(255), USERID VARCHAR(255), WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, CONDITION VARCHAR(255), DYNAMIC VARCHAR(255), DYNAMICVALUE REAL, GAME VARCHAR(255), graphId BIGINT, GRAPHNAME VARCHAR(255), ITERATIONS INTEGER, MAXITERATIONS INTEGER, MINITERATIONS INTEGER, PAYOFFCC REAL, PAYOFFCD REAL, PAYOFFDC REAL, PAYOFFDD REAL, SIMULATIONNAME VARCHAR(255), THRESHOLD INTEGER, TIMEWINDOW INTEGER, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, username VARCHAR(255), PRIMARY KEY (ID)) CREATE TABLE CENTRALITYCREATIONLOG (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, CENTRALITY_TYPE INTEGER, CREATION_TYPE INTEGER, EXECUTION_TIME BIGINT, STATUS INTEGER, PRIMARY KEY (ID)) CREATE TABLE COMMUNITY (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, COLOR INTEGER, NAME VARCHAR(255), GRAPH_ID BIGINT NOT NULL, USER_NAME VARCHAR(255) NOT NULL, COVER_ID BIGINT NOT NULL, PRIMARY KEY (ID, GRAPH_ID, USER_NAME, COVER_ID)) CREATE TABLE GROUPPARAMETERS (DYNAMIC VARCHAR(255), GAME VARCHAR(255), GRAPHID BIGINT, SCALING INTEGER, SIMULATIONS_ID BIGINT NOT NULL, PRIMARY KEY (SIMULATIONS_ID)) CREATE TABLE CUSTOMEDGE (ID INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, WEIGHT REAL, GRAPH_ID BIGINT NOT NULL, USER_NAME VARCHAR(255) NOT NULL, SOURCE_INDEX INTEGER, TARGET_INDEX INTEGER, RUNTIME_ID INTEGER, PRIMARY KEY (ID, GRAPH_ID, USER_NAME)) CREATE TABLE OCDMETRICLOG (ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1 INCREMENT BY 1) NOT NULL, STATUS INTEGER, TYPE INTEGER, VALUE REAL, GRAPH_ID BIGINT NOT NULL, USER_NAME VARCHAR(255) NOT NULL, COVER_ID BIGINT NOT NULL, PRIMARY KEY (ID, GRAPH_ID, USER_NAME, COVER_ID)) -CREATE TABLE SIMULATIONDATASET (ID BIGINT NOT NULL, COOPERATIVIATY REAL, FINALCOOPERATIONVALUE REAL, FINALPAYOFFVALUE REAL, ITERATIONS REAL, NAME VARCHAR(255), USERID BIGINT, WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, graphId BIGINT, username VARCHAR(255), simulationSeries BIGINT, SIMULATIONDATASETS_ID BIGINT, PRIMARY KEY (ID)) +CREATE TABLE SIMULATIONDATASET (ID BIGINT NOT NULL, COOPERATIVIATY REAL, FINALCOOPERATIONVALUE REAL, FINALPAYOFFVALUE REAL, ITERATIONS REAL, NAME VARCHAR(255), USERID VARCHAR(255), WEALTH REAL, AVERAGE REAL, DEVIATION REAL, MAXIMUM REAL, MINIMUM REAL, VARIANCE REAL, payoffAverage REAL, payoffdeviation REAL, payoffmaximum REAL, payoffminimum REAL, payoffvariance REAL, graphId BIGINT, username VARCHAR(255), simulationSeries BIGINT, SIMULATIONDATASETS_ID BIGINT, PRIMARY KEY (ID)) CREATE TABLE SIMULATIONSERIESGROUP_SIMULATIONSERIES (SimulationSeriesGroup_ID BIGINT NOT NULL, seriesList_ID BIGINT NOT NULL, PRIMARY KEY (SimulationSeriesGroup_ID, seriesList_ID)) CREATE TABLE CustomGraph_PROPERTIES (ID BIGINT, USER_NAME VARCHAR(255), PROPERTIES REAL) CREATE TABLE CustomGraph_TYPES (ID BIGINT, USER_NAME VARCHAR(255), TYPES INTEGER) @@ -66,3 +66,5 @@ ALTER TABLE SimulationDataset_COOPERATIONVALUES ADD CONSTRAINT SmlationDatasetCO ALTER TABLE SimulationDataset_PAYOFFVALUES ADD CONSTRAINT SimulationDataset_PAYOFFVALUESSimulationDataset_ID FOREIGN KEY (SimulationDataset_ID) REFERENCES SIMULATIONDATASET (ID) CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT NUMERIC(38), PRIMARY KEY (SEQ_NAME)) INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0) +CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT NUMERIC(38), PRIMARY KEY (SEQ_NAME)) +INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0) diff --git a/ocd/test/input/SawmillGraphMl.xml b/ocd/test/input/SawmillGraphMl.xml index 8f35352b..40c30da1 100644 --- a/ocd/test/input/SawmillGraphMl.xml +++ b/ocd/test/input/SawmillGraphMl.xml @@ -1,1815 +1,652 @@ - - - - - - + + 0.0 - + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + - - - - - - - - - - + + 2.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + 1.0 - - - - - - - - + - - - diff --git a/rest_ocd_services/.project b/rest_ocd_services/.project index 314c2344..b47460c9 100644 --- a/rest_ocd_services/.project +++ b/rest_ocd_services/.project @@ -20,4 +20,15 @@ org.eclipse.jdt.core.javanature org.eclipse.buildship.core.gradleprojectnature + + + 1643825602774 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/rest_ocd_services/build.gradle b/rest_ocd_services/build.gradle index f625a58b..4a6bff11 100644 --- a/rest_ocd_services/build.gradle +++ b/rest_ocd_services/build.gradle @@ -8,9 +8,10 @@ plugins { // Apply the application plugin to add support for building a CLI application in Java. id 'application' id 'eclipse' // only required when using Eclipse + id 'java-library' } -def yFiles = "$rootDir/yFiles" + def export = "$projectDir/export" def ocd = "$rootDir/ocd" @@ -25,21 +26,20 @@ repositories { } dependencies { - //yGuard - compileOnly 'com.yworks:yguard:3.0.0' + // Use JUnit test framework. testImplementation 'junit:junit:4.13' // las2peer bundle which is not necessary in the runtime path // compileOnly will be moved into the lib dir afterwards - compileOnly "i5:las2peer-bundle:${project.property('core.version')}" + api "i5:las2peer-bundle:${project.property('core.version')}" //ocd service deps - compileOnly "org.apache.commons:commons-exec:1.3" + implementation "org.apache.commons:commons-exec:1.3" compileOnly "com.google.guava:guava:31.0.1-jre" - compileOnly "org.la4j:la4j:0.4.9" - compileOnly "org.eclipse.persistence:eclipselink:2.7.9" + implementation "org.la4j:la4j:0.4.9" + implementation "org.eclipse.persistence:eclipselink:2.7.9" compileOnly "org.apache.geronimo.specs:geronimo-jpa_2.0_spec:1.1" compileOnly("commons-jxpath:commons-jxpath:1.3") { exclude group: 'xml-apis', module: 'xml-apis' @@ -51,34 +51,41 @@ dependencies { compileOnly "net.minidev:json-smart:2.4.7" compileOnly "com.googlecode.json-simple:json-simple:1.1.1" compileOnly "org.apache.commons:commons-pool2:2.11.1" - compileOnly "org.apache.commons:commons-dbcp2:2.9.0" + implementation "org.apache.commons:commons-dbcp2:2.9.0" + implementation 'org.apache.commons:commons-lang3:3.12.0' compileOnly "org.apache.commons:commons-math3:3.6.1" compileOnly "org.apache.geronimo.specs:geronimo-jpa_2.0_spec:1.1" - compileOnly "org.apache.lucene:lucene-core:8.9.1" - compileOnly "org.apache.lucene:lucene-analyzers-common:8.11.1" + implementation "org.apache.lucene:lucene-core:8.9.1" + implementation "org.apache.lucene:lucene-analyzers-common:8.11.1" compileOnly "org.apache.poi:poi:5.1.0" - compileOnly "org.apache.poi:poi-ooxml:5.1.0" + implementation "org.apache.poi:poi-ooxml:5.1.0" compileOnly "org.apache.jena:jena-core:4.3.2" //Exclude jackson modules as they are already included by las2peer and newer versions may break things like swagger - compileOnly ("org.apache.jena:jena-arq:4.3.2") { + implementation ("org.apache.jena:jena-arq:4.3.2") { exclude group: "com.fasterxml.jackson.core", module: "jackson-core" exclude group: "com.fasterxml.jackson.core", module: "jackson-databind" } compileOnly "org.ejml:ejml-core:0.41" - compileOnly "org.hsqldb:hsqldb:2.6.1" + implementation "org.hsqldb:hsqldb:2.6.1" compileOnly "org.apache.xmlgraphics:batik-svggen:1.14" compileOnly("org.apache.xmlgraphics:batik-bridge:1.14") { exclude group: 'xml-apis', module: 'xml-apis' } - compileOnly "org.mockito:mockito-all:1.9.5" - compileOnly "fr.irit.smac.thirdparty.edu.gmu.cs:mason:19" - compileOnly "org.ojalgo:ojalgo:50.0.0" + implementation "org.mockito:mockito-all:1.9.5" + implementation "fr.irit.smac.thirdparty.edu.gmu.cs:mason:19" + implementation "org.ojalgo:ojalgo:50.0.0" compileOnly "net.sbbi:sbbi-upnplib:1.0.4" + implementation "org.graphstream:gs-core:2.0" - //yFiles - compileOnly fileTree(dir: "${yFiles}", include: '*.jar') + //gs-algo version that includes HopcroftTarjanBiconnectedComponents + implementation "org.graphstream:gs-algo:2.0.ACIS" + implementation 'com.googlecode.json-simple:json-simple:1.1.1' + + //arangoDB Java driver + implementation "com.arangodb:arangodb-java-driver:6.18.0" + implementation "com.arangodb:jackson-dataformat-velocypack:3.0.1" } configurations { @@ -93,10 +100,14 @@ jar { attributes "Library-SymbolicName": "${project.property('service.name')}" } - from { (configurations.runtimeClasspath).collect { it.isDirectory() ? it : zipTree(it) } } { + from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }} { // Exclude signatures to be able to natively bundle signed jars exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' } + duplicatesStrategy = 'include' // this is needed due to duplicate error in gradle 7.0 which seems to be a bug + + + } application { @@ -106,11 +117,11 @@ application { // put all .jar files into export/jars folder tasks.withType(Jar) { - destinationDir = file("$projectDir/export/jars") + getDestinationDirectory().set(file("$projectDir/export/jars")) } javadoc { - destinationDir = file("$projectDir/export/doc") + setDestinationDir(file("$projectDir/export/doc")) } build.dependsOn "javadoc" @@ -157,7 +168,7 @@ task startscripts { # this script is autogenerated by 'gradle startscripts' # it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project # pls execute it from the root folder of your deployment, e. g. ./bin/start_network.sh -java -cp "lib/*:service/*" i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService\\(\\'${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}\\'\\) startWebConnector interactive +java -cp "lib/*:service/*" --add-opens java.base/java.lang=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService\\(\\'${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}\\'\\) startWebConnector interactive """ new File("$rootDir/bin", "start_network.bat").text = """:: this script is autogenerated by 'gradle startscripts' :: it starts a las2peer node providing the service '${project.property('service.name')}.${project.property('service.class')}' of this project @@ -167,7 +178,7 @@ cd %~p0 cd .. set BASE=%CD% set CLASSPATH="%BASE%/lib/*;%BASE%/service/*;" -java -cp %CLASSPATH% i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService('${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}') startWebConnector interactive +java -cp %CLASSPATH% --add-opens java.base/java.lang=ALL-UNNAMED i5.las2peer.tools.L2pNodeLauncher --port 9011 --service-directory service uploadStartupDirectory startService('${project.property('service.name')}.${project.property('service.class')}@${project.property('service.version')}') startWebConnector interactive pause """ } @@ -254,7 +265,7 @@ build.dependsOn "generateAgents" clean.doLast { file("$ocd/db").deleteDir() file("$ocd/indexes").deleteDir() - file("$ocd/yGuard").deleteDir() + file("$rootDir/tmp").deleteDir() file("$rootDir/lib").deleteDir() @@ -278,55 +289,17 @@ test { workingDir = file("$rootDir") } -task yguard { - group 'yGuard' - description 'Obfuscates and shrinks the java archive.' - - mkdir "${export}/obfuscated" - mkdir "$ocd/yGuard" - - doLast { - ant.taskdef( - name: 'yguard', - classname: 'com.yworks.yguard.YGuardTask', - classpath: '../lib/yGuard-3.0.0.jar' - ) - - ant.yguard { - // see the yGuard task documentation for information about the yGuard element - // Obfuscate the yFiles Jar. - inoutpair(in: "${yFiles}/y.jar", out: "./export/obfuscated/y.jar") - inoutpair(in: "${yFiles}/ysvg.jar", out: "./export/obfuscated/ysvg.jar") - // While obfuscating, adjust the names of yFiles features in the - // application's Jar file. - inoutpair(in: "${export}/jars/rest_ocd_services.jar", out: "${export}/obfuscated/rest_ocd_services.jar") - - externalclasses { - //pathelement(location: configurations.compileOnly.asPath) - fileset(dir: "${rootDir}/lib") { - include(name: '**/*.jar') - } - } - // ...using the yGuard 'rename' task. - rename(logfile: "${rootDir}/ocd/yGuard/log.xml", replaceClassNameStrings: "true") { - property(name: "obfuscation-prefix", value: "yguard") - keep { - 'class'(classes: "private", methods: "private", fields: "private") { - patternset { - //< !--define classes / methods / fields not to be renamed-- > - include(name: "i5.**") - //< !--exlude custom classes extending / implementing yFiles classes--> - exclude(name: "i5.las2peer.services.ocd.graphs.CustomGraph") - exclude(name: "i5.las2peer.services.ocd.graphs.CustomGraphListener") - } - } - //< keep custom field names required for persistence - field('class': "i5.las2peer.services.ocd.graphs.CustomGraph", name: "id") - field('class': "i5.las2peer.services.ocd.graphs.CustomGraph", name: "userName") - field('class': "i5.las2peer.services.ocd.graphs.CustomGraph", name: "creationMethod") - } - } - } +// Executes WebOCD tests without database tests. This task is used for github actions. +task testWithoutDB(type: Test) { + workingDir = file("$rootDir") + filter { + excludeTestsMatching '**.ServiceDatabaseTest' + excludeTestsMatching '**.ServiceTest' + excludeTestsMatching '**.SimulationPersistenceTest' + excludeTestsMatching '**.CoverDatabaseTest' + excludeTestsMatching '**.CustomGraphDatabaseTest' + excludeTestsMatching '**.DatabaseMethodTest' + excludeTestsMatching '**.DatabaseTest' } } @@ -349,4 +322,4 @@ eclipse { } } } -} \ No newline at end of file +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/ServiceClass.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/ServiceClass.java index 79731a59..bb022935 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/ServiceClass.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/ServiceClass.java @@ -3,8 +3,7 @@ import java.io.*; import java.net.HttpURLConnection; import java.net.URLDecoder; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -17,7 +16,7 @@ import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; -import javax.persistence.TypedQuery; +import javax.persistence.Query; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; @@ -32,10 +31,14 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import i5.las2peer.services.ocd.centrality.data.*; +import i5.las2peer.services.ocd.graphs.*; import i5.las2peer.services.ocd.utils.*; import i5.las2peer.services.ocd.utils.Error; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.math3.linear.RealMatrix; +import org.graphstream.algorithm.ConnectedComponents; +import org.json.simple.JSONObject; import org.la4j.matrix.sparse.CCSMatrix; import i5.las2peer.api.Context; @@ -73,7 +76,6 @@ import i5.las2peer.services.ocd.centrality.utils.CentralitySimulation; import i5.las2peer.services.ocd.centrality.utils.CentralitySimulationFactory; import i5.las2peer.services.ocd.centrality.utils.MatrixOperations; -import i5.las2peer.services.ocd.cooperation.data.SimulationEntityHandler; import i5.las2peer.services.ocd.cooperation.data.mapping.MappingFactory; import i5.las2peer.services.ocd.cooperation.data.mapping.SimulationGroupSetMapping; import i5.las2peer.services.ocd.cooperation.data.mapping.SimulationSeriesSetMapping; @@ -124,8 +126,7 @@ import io.swagger.annotations.Info; import io.swagger.annotations.License; import io.swagger.annotations.SwaggerDefinition; -import y.algo.GraphChecker; -import y.base.Graph; + /** * @@ -154,12 +155,16 @@ protected void initResources() { public ServiceClass() { + database = new Database(false); setFieldValues(); + // instantiate inactivityHandler to regularly remove content of inactive users. + inactivityHandler = new InactivityHandler(database, threadHandler, this); //TODO inactivity handler muss sich auf db beziehens + // instantiate UserLimitHandler to limit content for various users. + userLimitsHandler = new UserLimitsHandler(database); - // instantiate inactivityHandler to regularly remove content of inactive users. - inactivityHandler = new InactivityHandler(entityHandler, threadHandler, this); } + /////////////////////////////////////////////////////////// ///// ATTRIBUTES /////////////////////////////////////////////////////////// @@ -167,7 +172,8 @@ public ServiceClass() { /** * l2p logger */ - private final static L2pLogger logger = L2pLogger.getInstance(ServiceClass.class.getName()); + private final static GeneralLogger generalLogger = new GeneralLogger(); + /** * The thread handler used for algorithm, benchmark and metric execution. */ @@ -181,7 +187,7 @@ public ServiceClass() { /** * The entity handler used for access stored entities. */ - private final static SimulationEntityHandler entityHandler = new SimulationEntityHandler(); + private static Database database; /** * The factory used for creating benchmarks. @@ -220,14 +226,11 @@ public ServiceClass() { /** - * Number of days of inactivity allowed, before user content gets removed. + * User limit handler for inactive days allowed and size of user content allowed. */ - private int maxInactiveDays; + private static UserLimitsHandler userLimitsHandler; + - /** - * Password to be used to adjust number of days before inactive user content is removed. - */ - private String inactivityHandlerPassword; ////////////////////////////////////////////////////////////////// ///////// Utility Methods @@ -241,17 +244,7 @@ public static String getUserId() { return Context.getCurrent().getMainAgent().getIdentifier(); } - public int getMaxInactiveDays() { return this.maxInactiveDays; } - public String getInactivityHandlerPassword(){return this.inactivityHandlerPassword;} - - /** - * This method is used to set fresh field values, in case modifications were made in - * i5.las2peer.services.ocd.ServiceClass.properties file - */ - public void setFreshFieldValues() { - setFieldValues(); - } ////////////////////////////////////////////////////////////////// @@ -291,7 +284,8 @@ public static class RootResource { public Response validateLogin() { try { // update user inactivity info when user logs in. - inactivityHandler.refreshUserInactivityData(getUserName()); + inactivityHandler.getAndUpdateUserInactivityData(getUserName(), true); + generalLogger.getLogger().log(Level.INFO, "user " + getUserName() + " logged in."); return Response.ok(requestHandler.writeConfirmationXml()).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -300,61 +294,26 @@ public Response validateLogin() { } /** - * This method can be used to adjust number of days before content of inactive users is removed. This is an - * alternative to directly modifying the value in i5.las2peer.services.ocd.ServiceClass.properties file. - * - * @param contentStr XML with new inactivity days to set and the access code that allows modifications to take place. - * @return Newly set value of inactive days allowed before content deletion, or Error XML. + * Returns xml that stores user's content deletion date and the number of days before content deletion + * @param usernameStr + * @return */ - @POST - @Path("allowedInactivity") + @GET @Produces(MediaType.TEXT_PLAIN) - public Response adjustAllowedInactivity(String contentStr) { - - Map parameters; - String inactivityPassword; - int allowedInactivityDays; - + @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), + @ApiResponse(code = 401, message = "Unauthorized") }) + @Path("inactivity/{username}") + @ApiOperation(tags = {"show"}, value = "Content deletion date", notes = "Returns content deletion date of a user") + public Response getContentDeletionDate(@PathParam("username") String usernameStr) { try { - parameters = requestHandler.parseParameters(contentStr); - if (parameters.get("AccessCode") == null) { - return requestHandler.writeError(Error.PARAMETER_INVALID, "Access code is required to modify allowed inactivity."); - } - String accessCode = parameters.get("AccessCode"); - - // read most recent password for inactivityHandler - service.setFreshFieldValues(); - inactivityPassword = service.getInactivityHandlerPassword(); - if(!accessCode.equals(inactivityPassword)){ - return requestHandler.writeError(Error.INTERNAL, "Access code is invalid."); - } - - - String allowedInactivityDaysString = parameters.get("AllowedInactivityDays"); - if ((allowedInactivityDaysString == null) || (Integer.parseInt(allowedInactivityDaysString) < 0)) { - return requestHandler.writeError(Error.PARAMETER_INVALID, "AllowedInactivityDays parameter needs to be provided and be a positive integer."); - } - allowedInactivityDays = Integer.parseInt(allowedInactivityDaysString); - + LocalDate deletionDate = inactivityHandler.getAndUpdateUserInactivityData(usernameStr, false); + //generalLogger.getLogger().log(Level.INFO, "user " + getUserName() + ": content deletion date is " + deletionDate.toString()); + return Response.ok(requestHandler.writeDeletionDate(usernameStr, deletionDate)).build(); } catch (Exception e) { - requestHandler.log(Level.WARNING, "", e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid parameters provided."); - - } - - // write new allowed inactivity value to ServiceClass properties file - try { - BufferedWriter writer = new BufferedWriter(new FileWriter("etc/i5.las2peer.services.ocd.ServiceClass.properties")); - writer.write("maxInactiveDays=" + allowedInactivityDays); - writer.newLine(); - writer.write("inactivityHandlerPassword=" + inactivityPassword ); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); + requestHandler.log(Level.SEVERE, "", e); + return requestHandler.writeError(Error.INTERNAL, "Internal system error."); } - return Response.ok(allowedInactivityDays).build(); - } ////////////////////////////////////////////////////////////////////////// @@ -392,7 +351,7 @@ public Response adjustAllowedInactivity(String contentStr) { * The graph input. * @return A graph id xml. Or an error xml. */ - @POST + @POST @Path("graphs") @Produces(MediaType.TEXT_XML) @Consumes(MediaType.TEXT_PLAIN) @@ -412,6 +371,15 @@ public Response createGraph(@DefaultValue("unnamed") @QueryParam("name") String String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); + /* + Check if user has a limit regarding number of graph throw an error if the limit is violated. + */ + + if (userLimitsHandler.reachedGraphCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached graph count limit."); + return requestHandler.writeError(Error.INTERNAL, "Graph count limit reached. Delete a graph before generating a new one, or contact administrator to adjust limits."); + } + GraphInputFormat format; CustomGraph graph; try { @@ -487,6 +455,7 @@ public Response createGraph(@DefaultValue("unnamed") @QueryParam("name") String graph.setCreationMethod(log); GraphProcessor processor = new GraphProcessor(); processor.determineGraphTypes(graph); + graph.setNodeEdgeCountColumnFields(); // before persisting the graph, update node/edge count information if (doMakeUndirected) { Set graphTypes = graph.getTypes(); if (graphTypes.remove(GraphType.DIRECTED)) { @@ -494,7 +463,8 @@ public Response createGraph(@DefaultValue("unnamed") @QueryParam("name") String } } try { - entityHandler.storeGraph(graph); + database.storeGraph(graph); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": import graph " + graph.getKey() + " in format " + graphInputFormatStr); } catch (Exception e) { return requestHandler.writeError(Error.INTERNAL, "Could not store graph"); } @@ -523,6 +493,15 @@ public Response createGraph(@DefaultValue("unnamed") @QueryParam("name") String @ApiOperation(tags = {"special"}, value = "Big Graph Import", notes = "Stores a graph step by step.") public Response storeGraph(@DefaultValue("unnamed") @QueryParam("name") String nameStr, String contentStr) { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); + /* + Check if user has a limit regarding number of graph or covers and throw an error if the limit is violated. + */ + + if (userLimitsHandler.reachedGraphCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached graph count limit."); + return requestHandler.writeError(Error.INTERNAL, "Graph count limit reached. Delete a graph before generating a new one, or contact administrator to adjust limits."); + } + File graphDir = new File("tmp" + File.separator + username); if (!graphDir.exists()) { graphDir.mkdirs(); @@ -640,12 +619,12 @@ public Response processStoredGraph(@DefaultValue("unnamed") @QueryParam("name") @ApiResponse(code = 401, message = "Unauthorized") }) @ApiOperation(tags = {"show"}, value = "Get Graphs Info", notes = "Returns the ids or meta information of multiple graphs.") public Response getGraphs(@DefaultValue("0") @QueryParam("firstIndex") String firstIndexStr, - @DefaultValue("0") @QueryParam("length") String lengthStr, + @DefaultValue("") @QueryParam("length") String lengthStr, @DefaultValue("FALSE") @QueryParam("includeMeta") String includeMetaStr, @DefaultValue("") @QueryParam("executionStatuses") String executionStatusesStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - List queryResults; + List queryResults; List executionStatusIds = new ArrayList(); if (!executionStatusesStr.equals("")) { try { @@ -687,17 +666,20 @@ public Response getGraphs(@DefaultValue("0") @QueryParam("firstIndex") String fi if (!lengthStr.equals("")) { length = Integer.parseInt(lengthStr); } + else { + length = Integer.MAX_VALUE; + } } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Length is not valid."); } - queryResults = entityHandler.getGraphs(username, firstIndex, length, executionStatusIds); + queryResults = database.getGraphMetaDataEfficiently(username, firstIndex, length, executionStatusIds); String responseStr; if (includeMeta) { - responseStr = requestHandler.writeGraphMetas(queryResults); + responseStr = requestHandler.writeGraphMetasEfficiently(queryResults); } else { - responseStr = requestHandler.writeGraphIds(queryResults); + responseStr = requestHandler.writeGraphIdsEfficiently(queryResults); } return Response.ok(responseStr).build(); } catch (Exception e) { @@ -724,28 +706,25 @@ public Response getGraphs(@DefaultValue("0") @QueryParam("firstIndex") String fi public Response getGraph(@DefaultValue("GRAPH_ML") @QueryParam("outputFormat") String graphOutputFormatStr, @PathParam("graphId") String graphIdStr) { try { - long graphId; + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); GraphOutputFormat format; try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - try { + format = GraphOutputFormat.valueOf(graphOutputFormatStr); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Specified graph output format does not exist."); } - - CustomGraph graph = entityHandler.getGraph(username, graphId); + + CustomGraph graph = database.getGraph(username, graphIdStr); //done + if (graph == null) return requestHandler.writeError(Error.PARAMETER_INVALID, - "Graph does not exist: graph id " + graphId); + "Graph does not exist: graph key " + graphIdStr); //done + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get cover " + graphIdStr + " in format " + graphOutputFormatStr ); return Response.ok(requestHandler.writeGraph(graph, format)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -759,10 +738,10 @@ public Response getGraph(@DefaultValue("GRAPH_ML") @QueryParam("outputFormat") S * If a benchmark is currently calculating the graph the execution is * terminated. If an algorithm is currently calculating a cover based on * the graph it is terminated. If a metric is currently running on a - * cover based on the grap it is terminated. + * cover based on the graph it is terminated. * * @param graphIdStr - * The graph id. + * The graph key. * @return A confirmation xml. Or an error xml. */ @DELETE @@ -773,17 +752,10 @@ public Response getGraph(@DefaultValue("GRAPH_ML") @QueryParam("outputFormat") S @ApiOperation(tags = {"delete"}, value = "Delete Graph", notes = "Deletes a graph.") public Response deleteGraph(@PathParam("graphId") String graphIdStr) { try { - long graphId; - String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); try { - entityHandler.deleteGraph(username, graphId, threadHandler); + database.deleteGraph(username, graphIdStr, threadHandler); //done } catch (Exception e) { if(e.getMessage() != null) { @@ -791,7 +763,7 @@ public Response deleteGraph(@PathParam("graphId") String graphIdStr) { } requestHandler.writeError(Error.INTERNAL, "Graph not found"); } - + generalLogger.getLogger().log(Level.INFO, "user " + username + ": delete graph " + graphIdStr); return Response.ok(requestHandler.writeConfirmationXml()).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -832,13 +804,15 @@ public Response createCover(@PathParam("graphId") String graphIdStr, String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); + + /* + Check if user has a limit regarding covers and throw an error if the limit is violated. + */ + if (userLimitsHandler.reachedCoverCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached cover count limit."); + return requestHandler.writeError(Error.INTERNAL, "Cover count limit reached. Delete a cover before generating a new one, or contact administrator to adjust limits."); } + CoverInputFormat format; try { format = CoverInputFormat.valueOf(coverInputFormatStr); @@ -864,38 +838,28 @@ public Response createCover(@PathParam("graphId") String graphIdStr, } CoverCreationLog log = new CoverCreationLog(algorithmType, new HashMap(), graphTypes); log.setStatus(ExecutionStatus.COMPLETED); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + Cover cover; + CustomGraph graph; try { - CustomGraph graph; - try { - graph = entityHandler.getGraph(username, graphId); - } catch (Exception e) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Graph does not exist: graph id " + graphId); - } - try { - cover = requestHandler.parseCover(contentStr, graph, format); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Input cover does not correspond to the specified format."); - } - cover.setCreationMethod(log); - cover.setName(URLDecoder.decode(nameStr, "UTF-8")); - tx.begin(); - em.persist(cover); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; + graph = database.getGraph(username, graphIdStr); + } catch (Exception e) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Graph does not exist: graph id " + graphIdStr); } - em.close(); + try { + cover = requestHandler.parseCover(contentStr, graph, format); + } catch (Exception e) { + requestHandler.log(Level.WARNING, "user: " + username, e); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Input cover does not correspond to the specified format."); + } + cover.setCreationMethod(log); + cover.setName(URLDecoder.decode(nameStr, "UTF-8")); + database.storeCover(cover); //done + generalLogger.getLogger().log(Level.INFO, "user " + username + ": import cover " + cover.getKey() + " in format " + coverInputFormatStr); return Response.ok(requestHandler.writeId(cover)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -950,15 +914,8 @@ public Response getCovers( { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId = 0; - if (!graphIdStr.equals("")) { - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - } + int length; + int firstIndex; List executionStatusIds = new ArrayList(); if (!executionStatusesStr.equals("")) { try { @@ -993,40 +950,20 @@ public Response getCovers( "Specified metric execution status does not exist."); } } - List queryResults; - EntityManager em = entityHandler.getEntityManager(); - /* - * Query - */ - String queryStr = "SELECT c from Cover c" + " JOIN c." + Cover.GRAPH_FIELD_NAME + " g" + " JOIN c." - + Cover.CREATION_METHOD_FIELD_NAME + " a"; - if (!metricExecutionStatusesStr.equals("")) { - queryStr += " JOIN c." + Cover.METRICS_FIELD_NAME + " m"; - } - queryStr += " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username" + " AND a." - + CoverCreationLog.STATUS_ID_FIELD_NAME + " IN :execStatusIds"; - if (!metricExecutionStatusesStr.equals("")) { - queryStr += " AND m." + OcdMetricLog.STATUS_ID_FIELD_NAME + " IN :metricExecStatusIds"; - } - if (!graphIdStr.equals("")) { - queryStr += " AND g." + CustomGraph.ID_FIELD_NAME + " = " + graphId; - } - /* - * Gets each cover only once. - */ - queryStr += " GROUP BY c"; - TypedQuery query = em.createQuery(queryStr, Cover.class); + + List queryResults; try { - int firstIndex = Integer.parseInt(firstIndexStr); - query.setFirstResult(firstIndex); + firstIndex = Integer.parseInt(firstIndexStr); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "First index is not valid."); } try { if (!lengthStr.equals("")) { - int length = Integer.parseInt(lengthStr); - query.setMaxResults(length); + length = Integer.parseInt(lengthStr); + } + else { + length = Integer.MAX_VALUE; } } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); @@ -1039,18 +976,13 @@ public Response getCovers( requestHandler.log(Level.WARNING, "", e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Include meta is not a boolean value."); } - query.setParameter("username", username); - query.setParameter("execStatusIds", executionStatusIds); - if (!metricExecutionStatusesStr.equals("")) { - query.setParameter("metricExecStatusIds", metricExecutionStatusIds); - } - queryResults = query.getResultList(); - em.close(); + + queryResults = database.getCoverMetaDataEfficiently(username, graphIdStr, executionStatusIds, metricExecutionStatusIds, firstIndex, length); String responseStr; if (includeMeta) { - responseStr = requestHandler.writeCoverMetas(queryResults); + responseStr = requestHandler.writeCoverMetasEfficiently(queryResults); } else { - responseStr = requestHandler.writeCoverIds(queryResults); + responseStr = requestHandler.writeCoverIdsEfficiently(queryResults); } return Response.ok(responseStr).build(); } catch (Exception e) { @@ -1080,20 +1012,7 @@ public Response getCover(@PathParam("graphId") String graphIdStr, @PathParam("co @DefaultValue("LABELED_MEMBERSHIP_MATRIX") @QueryParam("outputFormat") String coverOutputFormatStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } + CoverOutputFormat format; try { format = CoverOutputFormat.valueOf(coverOutputFormatStr); @@ -1105,7 +1024,7 @@ public Response getCover(@PathParam("graphId") String graphIdStr, @PathParam("co Cover cover = null; try { - cover = entityHandler.getCover(username, graphId, coverId); + cover = database.getCover(username, graphIdStr, coverIdStr); //done // Paint cover if not yet done when requested type is default XML if(format == CoverOutputFormat.DEFAULT_XML && !cover.isPainted()) { @@ -1116,10 +1035,11 @@ public Response getCover(@PathParam("graphId") String graphIdStr, @PathParam("co } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username + ", " + "Cover does not exist: cover id " - + coverId + ", graph id " + graphId); + + coverIdStr + ", graph id " + graphIdStr); return requestHandler.writeError(Error.PARAMETER_INVALID, - "Cover does not exist: cover id " + coverId + ", graph id " + graphId); + "Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr); } + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get cover " + coverIdStr + " in format " + coverOutputFormatStr ); return Response.ok(requestHandler.writeCover(cover, format)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -1149,23 +1069,10 @@ public Response getCover(@PathParam("graphId") String graphIdStr, @PathParam("co public Response deleteCover(@PathParam("coverId") String coverIdStr, @PathParam("graphId") String graphIdStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } try { - entityHandler.deleteCover(username, graphId, coverId, threadHandler); + database.deleteCover(username, graphIdStr, coverIdStr, threadHandler); //TODO + generalLogger.getLogger().log(Level.INFO, "user " + username + ": delete cover " + coverIdStr); return Response.ok(requestHandler.writeConfirmationXml()).build(); } catch (IllegalArgumentException e) { return requestHandler.writeError(Error.PARAMETER_INVALID, e.getMessage()); @@ -1222,16 +1129,20 @@ public Response runAlgorithm(@PathParam("graphId") String graphIdStr, @DefaultValue("0") @QueryParam("componentNodeCountFilter") String componentNodeCountFilterStr) { try { int componentNodeCountFilter; - long graphId; + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); CoverCreationType algorithmType; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); + + /* + Check if user has a limit regarding number of graph or covers and throw an error if the limit is violated. + */ + if (userLimitsHandler.reachedCoverCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached cover count limit."); + return requestHandler.writeError(Error.INTERNAL, "Cover count limit reached. Delete a cover before generating a new one, or contact administrator to adjust limits."); } + try { + componentNodeCountFilter = Integer.parseInt(componentNodeCountFilterStr); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); @@ -1255,78 +1166,69 @@ public Response runAlgorithm(@PathParam("graphId") String graphIdStr, Map parameters; try { parameters = requestHandler.parseParameters(content); - algorithm = algorithmFactory.getInstance(algorithmType, parameters); + algorithm = algorithmFactory.getInstance(algorithmType, new HashMap(parameters)); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } Cover cover; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId id = new CustomGraphId(graphId, username); + CoverCreationLog log; synchronized (threadHandler) { - EntityTransaction tx = em.getTransaction(); + CustomGraph graph; - try { - tx.begin(); - graph = em.find(CustomGraph.class, id); - if (graph == null) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Graph does not exist: graph id " + graphId); - } - if (graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Invalid graph creation method status for metric execution: " - + graph.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Invalid graph creation method status for metric execution: " - + graph.getCreationMethod().getStatus().name()); - } - boolean weight = Boolean.parseBoolean(contentWeighting); - if(!graph.isOfType(GraphType.CONTENT_LINKED) && !graph.isOfType(GraphType.CONTENT_UNLINKED) && (weight || (algorithm - .getAlgorithmType() == CoverCreationType.COST_FUNC_OPT_CLUSTERING_ALGORITHM - || algorithm.getAlgorithmType() == CoverCreationType.WORD_CLUSTERING_REF_ALGORITHM))) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Content weighted algorithm chosen for non-content graph: " - + algorithm.getAlgorithmType().toString() + " " + graph.getTypes() + " " + graph.getPath()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Content weighted algorithm chosen for non-content graph"); - } - if (weight && (algorithm - .getAlgorithmType() == CoverCreationType.COST_FUNC_OPT_CLUSTERING_ALGORITHM - || algorithm.getAlgorithmType() == CoverCreationType.WORD_CLUSTERING_REF_ALGORITHM)) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Invalid algorithm in combination of weighting requested: " - + algorithm.getAlgorithmType().toString()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Invalid algorithm in combination of weighting requested"); - } - if (weight) { - ContentBasedWeightingAlgorithm weightAlgo = new ContentBasedWeightingAlgorithm(); - graph = weightAlgo.detectOverlappingCommunities(graph, new ExecutionTime()); - } - cover = new Cover(graph, new CCSMatrix(graph.nodeCount(), 0)); - log = new CoverCreationLog(algorithmType, parameters, algorithm.compatibleGraphTypes()); - cover.setCreationMethod(log); - cover.setName(URLDecoder.decode(nameStr, "UTF-8")); - em.persist(cover); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; + graph = database.getGraph(username, graphIdStr); + if (graph == null) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Graph does not exist: graph id " + graphIdStr); } - em.close(); + if (graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Invalid graph creation method status for metric execution: " + + graph.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Invalid graph creation method status for metric execution: " + + graph.getCreationMethod().getStatus().name()); + } + boolean weight = Boolean.parseBoolean(contentWeighting); + if(!graph.isOfType(GraphType.CONTENT_LINKED) && !graph.isOfType(GraphType.CONTENT_UNLINKED) && (weight || (algorithm + .getAlgorithmType() == CoverCreationType.COST_FUNC_OPT_CLUSTERING_ALGORITHM + || algorithm.getAlgorithmType() == CoverCreationType.WORD_CLUSTERING_REF_ALGORITHM))) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Content weighted algorithm chosen for non-content graph: " + + algorithm.getAlgorithmType().toString() + " " + graph.getTypes() + " " + graph.getPath()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Content weighted algorithm chosen for non-content graph"); + } + if (weight && (algorithm + .getAlgorithmType() == CoverCreationType.COST_FUNC_OPT_CLUSTERING_ALGORITHM + || algorithm.getAlgorithmType() == CoverCreationType.WORD_CLUSTERING_REF_ALGORITHM)) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Invalid algorithm in combination of weighting requested: " + + algorithm.getAlgorithmType().toString()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Invalid algorithm in combination of weighting requested"); + } + if (weight) { + ContentBasedWeightingAlgorithm weightAlgo = new ContentBasedWeightingAlgorithm(); + graph = weightAlgo.detectOverlappingCommunities(graph, new ExecutionTime()); + database.updateGraph(graph); //done + } + cover = new Cover(graph, new CCSMatrix(graph.getNodeCount(), 0)); + log = new CoverCreationLog(algorithmType, parameters, algorithm.compatibleGraphTypes()); + cover.setCreationMethod(log); + cover.setName(URLDecoder.decode(nameStr, "UTF-8")); + database.storeCover(cover); //done /* * Registers and starts algorithm */ threadHandler.runAlgorithm(cover, algorithm, componentNodeCountFilter); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run " + algorithm.getClass().getSimpleName() + " on graph " + graph.getKey() + ". Created cover " + cover.getKey()); } return Response.ok(requestHandler.writeId(cover)).build(); } catch (Exception e) { @@ -1368,13 +1270,7 @@ public Response importCentralityMap(@PathParam("graphId") String graphIdStr, String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + CentralityInputFormat format; try { format = CentralityInputFormat.valueOf(centralityInputFormatStr); @@ -1392,39 +1288,31 @@ public Response importCentralityMap(@PathParam("graphId") String graphIdStr, } CentralityCreationLog log = new CentralityCreationLog(null, creationType, null, null); log.setStatus(ExecutionStatus.COMPLETED); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + CentralityMap map; + CustomGraph graph; try { - CustomGraph graph; - try { - graph = entityHandler.getGraph(username, graphId); - } catch (Exception e) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Graph does not exist: graph id " + graphId); - } - try { - map = requestHandler.parseCentralityMap(contentStr, graph, format); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Input centrality data does not correspond to the specified format."); - } - map.setCreationMethod(log); - map.setName(nameStr); - tx.begin(); - em.persist(map); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; + graph = database.getGraph(username, graphIdStr); //done + } catch (Exception e) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Graph does not exist: graph id " + graphIdStr); } - em.close(); + try { + map = requestHandler.parseCentralityMap(contentStr, graph, format); + } catch (Exception e) { + requestHandler.log(Level.WARNING, "user: " + username, e); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Input centrality data does not correspond to the specified format."); + } + map.setCreationMethod(log); + map.setName(nameStr); + + database.storeCentralityMap(map); //done + generalLogger.getLogger().log(Level.INFO, "user " + username + ": import centrality " + nameStr + " in format " + centralityInputFormatStr); return Response.ok(requestHandler.writeId(map)).build(); + } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); return requestHandler.writeError(Error.INTERNAL, "Internal system error."); @@ -1471,16 +1359,7 @@ public Response getCentralityMaps( { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId = 0; - if(!graphIdStr.equals("")) { - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - } + List executionStatusIds = new ArrayList(); if(!executionStatusesStr.equals("")) { try { @@ -1500,36 +1379,21 @@ public Response getCentralityMaps( executionStatusIds.add(executionStatus.getId()); } } - List queryResults; - EntityManager em = entityHandler.getEntityManager(); - /* - * Query - */ - String queryStr = "SELECT c from CentralityMap c" - + " JOIN c." + CentralityMap.GRAPH_FIELD_NAME + " g" - + " JOIN c." + CentralityMap.CREATION_METHOD_FIELD_NAME + " a"; - queryStr += " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username" - + " AND a." + CentralityCreationLog.STATUS_ID_FIELD_NAME + " IN :execStatusIds"; - if(!graphIdStr.equals("")) { - queryStr += " AND g." + CustomGraph.ID_FIELD_NAME + " = " + graphId; - } - /* - * Gets each CentralityMap only once. - */ - queryStr += " GROUP BY c"; - TypedQuery query = em.createQuery(queryStr, CentralityMap.class); + int firstIndex; try { - int firstIndex = Integer.parseInt(firstIndexStr); - query.setFirstResult(firstIndex); + firstIndex = Integer.parseInt(firstIndexStr); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "First index is not valid."); } + int length; try { if(!lengthStr.equals("")) { - int length = Integer.parseInt(lengthStr); - query.setMaxResults(length); + length = Integer.parseInt(lengthStr); + } + else { + length = Integer.MAX_VALUE; } } catch (Exception e) { @@ -1544,16 +1408,13 @@ public Response getCentralityMaps( requestHandler.log(Level.WARNING, "", e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Include meta is not a boolean value."); } - query.setParameter("username", username); - query.setParameter("execStatusIds", executionStatusIds); - queryResults = query.getResultList(); - em.close(); + List queryResults = database.getCentralityMapsEfficiently(username, graphIdStr, executionStatusIds, firstIndex, length); String responseStr; if(includeMeta) { - responseStr = requestHandler.writeCentralityMapMetas(queryResults); + responseStr = requestHandler.writeCentralityMapMetasEfficiently(queryResults); } else { - responseStr = requestHandler.writeCentralityMapIds(queryResults); + responseStr = requestHandler.writeCentralityMapIdsEfficiently(queryResults); } return Response.ok(responseStr).build(); } @@ -1596,17 +1457,11 @@ public Response calculateCentrality( @DefaultValue("Degree Centrality") @QueryParam("algorithm") String centralityMeasureTypeStr, String content) { try { - long graphId; + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); CentralityMeasureType centralityMeasureType; try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - try { + centralityMeasureType = CentralityMeasureType.valueOf(centralityMeasureTypeStr); if(centralityMeasureType == CentralityMeasureType.UNDEFINED) { requestHandler.log(Level.WARNING, "user: " + username + ", " + "Specified centrality measure type is not valid for this request: " + centralityMeasureType.getDisplayName()); @@ -1632,45 +1487,37 @@ public Response calculateCentrality( return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } CentralityMap map; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId id = new CustomGraphId(graphId, username); + synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); + CustomGraph graph; CentralityCreationLog log; - try { - tx.begin(); - graph = em.find(CustomGraph.class, id); - if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); - } - if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for centrality algorithm execution: " + graph.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for centrality algorithm execution: " + graph.getCreationMethod().getStatus().name()); - } - // Some centrality measures cannot be computed or do not give meaningful results on unconnected graphs - if(algorithm.getCentralityMeasureType() == CentralityMeasureType.CURRENT_FLOW_BETWEENNESS || algorithm.getCentralityMeasureType() == CentralityMeasureType.CURRENT_FLOW_CLOSENESS || algorithm.getCentralityMeasureType() == CentralityMeasureType.ECCENTRICITY || algorithm.getCentralityMeasureType() == CentralityMeasureType.CLOSENESS_CENTRALITY) { - if(!GraphChecker.isConnected((Graph)graph)) { - return Response.serverError().entity("Show Error: This centrality measure can only be used on a connected network.").build(); - } - } - map = new CentralityMap(graph); - map.setName(centralityMeasureType.getDisplayName()); - log = new CentralityCreationLog(centralityMeasureType, CentralityCreationType.CENTRALITY_MEASURE, parametersCopy, algorithm.compatibleGraphTypes()); - map.setCreationMethod(log); - em.persist(map); - tx.commit(); + graph = database.getGraph(username, graphIdStr); + if(graph == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); + if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for centrality algorithm execution: " + graph.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for centrality algorithm execution: " + graph.getCreationMethod().getStatus().name()); + } + // Some centrality measures cannot be computed or do not give meaningful results on unconnected graphs + if(algorithm.getCentralityMeasureType() == CentralityMeasureType.CURRENT_FLOW_BETWEENNESS || algorithm.getCentralityMeasureType() == CentralityMeasureType.CURRENT_FLOW_CLOSENESS || algorithm.getCentralityMeasureType() == CentralityMeasureType.ECCENTRICITY || algorithm.getCentralityMeasureType() == CentralityMeasureType.CLOSENESS_CENTRALITY) { + ConnectedComponents ccAlgo = new ConnectedComponents(graph); + if(graph.getEdgeCount() < graph.getNodeCount() || ccAlgo.getGiantComponent().getNodeCount() != graph.getNodeCount()) { //I.e. the graph is not connected + return Response.serverError().entity("Show Error: This centrality measure can only be used on a connected network.").build(); } - throw e; - } - em.close(); - /* + } + //System.out.println(centralityMeasureType.getId() + "Centrality Typ Name : " + centralityMeasureType.getDisplayName()); + map = new CentralityMap(graph); + map.setName(centralityMeasureType.getDisplayName()); + log = new CentralityCreationLog(centralityMeasureType, CentralityCreationType.CENTRALITY_MEASURE, parametersCopy, algorithm.compatibleGraphTypes()); + //System.out.println(log.String()); + map.setCreationMethod(log); + database.storeCentralityMap(map); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run centrality " + algorithm.getClass().getSimpleName() + " on graph " + graph.getId() +". Created centrality " + map.getKey()); + /* * Registers and starts algorithm */ threadHandler.runCentralityAlgorithm(map, algorithm); @@ -1716,22 +1563,7 @@ public Response getCentralityMap( { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long mapId; - try { - mapId = Long.parseLong(mapIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map id is not valid."); - } + CentralityOutputFormat format; try { format = CentralityOutputFormat.valueOf(centralityOutputFormatStr); @@ -1755,10 +1587,11 @@ public Response getCentralityMap( requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Top nodes number is not valid."); } - CentralityMap map = entityHandler.getCentralityMap(username, graphId, mapId); + CentralityMap map = database.getCentralityMap(username, graphIdStr, mapIdStr); //done if(onlyTopNodes && topNodesNumber != 0) { return Response.ok(requestHandler.writeCentralityMapTopNodes(map, topNodesNumber)).build(); } + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get centrality " + mapIdStr ); return Response.ok(requestHandler.writeCentralityMap(map, format)).build(); } catch (Exception e) { @@ -1792,25 +1625,9 @@ public Response deleteCentralityMap( { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long mapId; - try { - mapId = Long.parseLong(mapIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map id is not valid."); - } - - entityHandler.deleteCentralityMap(username, graphId, mapId, threadHandler); - return Response.ok(requestHandler.writeConfirmationXml()).build(); + database.deleteCentralityMap(username, graphIdStr, mapIdStr, threadHandler); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": delete centrality " + mapIdStr); + return Response.ok(requestHandler.writeConfirmationXml()).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -1840,40 +1657,19 @@ public Response getAdjacencyMatrixEigenvalue( double eigenvalue; try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId id = new CustomGraphId(graphId, username); synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); + CustomGraph graph; - try { - tx.begin(); - graph = em.find(CustomGraph.class, id); - if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); - } - if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for eigenvalue calculation: " + graph.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for eigenvalue calculation: " + graph.getCreationMethod().getStatus().name()); - } - tx.commit(); + graph = database.getGraph(username, graphIdStr); + if(graph == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); + } + if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for eigenvalue calculation: " + graph.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for eigenvalue calculation: " + graph.getCreationMethod().getStatus().name()); } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); eigenvalue = MatrixOperations.calculateAbsolutePrincipalEigenvalue(graph.getNeighbourhoodMatrix()); } return Response.ok(requestHandler.writeValueXml(eigenvalue)).build(); @@ -1917,18 +1713,12 @@ public Response runCentralitySimulation( @DefaultValue("SIR Simulation") @QueryParam("simulation") String simulationTypeStr, String content) { try { - long graphId; + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); CentralitySimulationType simulationType; CentralitySimulation simulation; try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - try { + simulationType = CentralitySimulationType.valueOf(simulationTypeStr); } catch (Exception e) { @@ -1949,25 +1739,24 @@ public Response runCentralitySimulation( return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } CentralityMap map; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId id = new CustomGraphId(graphId, username); + synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); + CustomGraph graph; CentralityCreationLog log; try { - tx.begin(); - graph = em.find(CustomGraph.class, id); + graph = database.getGraph(username, graphIdStr); //done if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); } if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for simulation execution: " + graph.getCreationMethod().getStatus().name()); return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for simulation execution: " + graph.getCreationMethod().getStatus().name()); } - if(simulation.getSimulationType() == CentralitySimulationType.RANDOM_PACKAGE_TRANSMISSION_UNWEIGHTED) { - if(!GraphChecker.isConnected((Graph)graph)) { + if(simulation.getSimulationType() == CentralitySimulationType.RANDOM_PACKAGE_TRANSMISSION_UNWEIGHTED) { + ConnectedComponents ccAlgo = new ConnectedComponents(graph); + if(graph.getEdgeCount() < graph.getNodeCount() || ccAlgo.getGiantComponent().getNodeCount() != graph.getNodeCount()) { //I.e. the graph is not connected return Response.serverError().entity("Show Error: This simulation can only be used on a connected network.").build(); } } @@ -1975,21 +1764,19 @@ public Response runCentralitySimulation( map.setName(simulationType.getDisplayName()); log = new CentralityCreationLog(simulationType, CentralityCreationType.SIMULATION, parametersCopy, simulation.compatibleGraphTypes()); map.setCreationMethod(log); - em.persist(map); - tx.commit(); + database.storeCentralityMap(map); //done } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + throw e; } - em.close(); + /* * Registers and starts algorithm */ threadHandler.runCentralitySimulation(map, simulation); - } + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run simulation " + simulationTypeStr + " on graph " + graphIdStr + " with paramneters: " + parameters ); + } return Response.ok(requestHandler.writeId(map)).build(); } catch (Exception e) { @@ -2030,63 +1817,37 @@ public Response getAverageCentralityMap( @QueryParam("mapName") String averageMapName) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + CustomGraph graph; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); + + CustomGraphId gId = new CustomGraphId(graphIdStr, username); synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); try { - tx.begin(); - graph = em.find(CustomGraph.class, gId); + graph = database.getGraph(username, graphIdStr); if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); } if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for centrality calculation: " + graph.getCreationMethod().getStatus().name()); return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for centrality calculation: " + graph.getCreationMethod().getStatus().name()); } - tx.commit(); + } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + throw e; } - em.close(); + } - - List maps = new LinkedList(); - for(int id : ids) { - long mapId = (long) id; - em = entityHandler.getEntityManager(); - CentralityMapId cId = new CentralityMapId(mapId, gId); - - EntityTransaction tx = em.getTransaction(); - CentralityMap map; - try { - tx.begin(); - map = em.find(CentralityMap.class, cId); - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } + + List maps = new LinkedList(); + for(int id : ids) { + String mapIdStr = Integer.toString(id); + CentralityMap map = database.getCentralityMap(username, graphIdStr, mapIdStr); if(map == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); } maps.add(map); } @@ -2095,24 +1856,15 @@ public Response getAverageCentralityMap( Map parameters = new HashMap(); parameters.put("Number of measures", Integer.toString(ids.size())); synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - log = new CentralityCreationLog(CentralityMeasureType.UNDEFINED, CentralityCreationType.AVERAGE, parameters, new HashSet(Arrays.asList(GraphType.values()))); - averageMap.setCreationMethod(log); - averageMap.setName(averageMapName); - em.persist(averageMap); - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); - threadHandler.createCentralityMap(averageMap, new CentralityMapId(averageMap.getId(), new CustomGraphId(graphId, username)), false); - } + log = new CentralityCreationLog(CentralityMeasureType.UNDEFINED, CentralityCreationType.AVERAGE, parameters, new HashSet(Arrays.asList(GraphType.values()))); + averageMap.setCreationMethod(log); + averageMap.setName(averageMapName); + database.storeCentralityMap(averageMap); + //System.out.println(log.String()); + threadHandler.createCentralityMap(averageMap, new CentralityMapId(averageMap.getKey(), gId), false); // 444 should be " new CustomGraphId(graphId, username)" instead of gid + generalLogger.getLogger().log(Level.INFO, "user " + username + ": calculate average " + averageMap +" for centrality maps: " + ids ); + + } return Response.ok(requestHandler.writeId(averageMap)).build(); } @@ -2158,67 +1910,36 @@ public Response getCorrelation( requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Specified correlation coefficient does not exist."); } - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + CustomGraph graph; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); + synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - graph = em.find(CustomGraph.class, gId); - if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); - } - if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); - } - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); + graph = database.getGraph(username, graphIdStr); + if(graph == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); + } + if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); + } + } List maps = new ArrayList(); for(int id : mapIds) { - long mapId = (long) id; - em = entityHandler.getEntityManager(); - CentralityMapId cId = new CentralityMapId(mapId, gId); - - EntityTransaction tx = em.getTransaction(); + String mapIdStr = Integer.toString(id); //TODO unschoener typecast von begin an Strings in request verwenden CentralityMap map; - try { - tx.begin(); - map = em.find(CentralityMap.class, cId); - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } + + map = database.getCentralityMap(username, graphIdStr, mapIdStr); if(map == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); } maps.add(map); } - RealMatrix correlationMatrix = StatisticalProcessor.getCorrelation(graph, maps, correlationCoefficient); - return Response.ok(requestHandler.writeCorrelationMatrix(mapIds, correlationMatrix)).build(); + RealMatrix correlationMatrix = StatisticalProcessor.getCorrelation(graph, maps, correlationCoefficient); + //generalLogger.getLogger().log(Level.INFO, "user " + username + " calculate" + correlationCoefficientStr + " correlation on centrality maps:" + mapIds ); + return Response.ok(requestHandler.writeCorrelationMatrix(mapIds, correlationMatrix)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -2261,68 +1982,33 @@ public Response getPrecision( requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameter k is not valid."); } - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } - catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + CustomGraph graph; - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); synchronized(threadHandler) { - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - graph = em.find(CustomGraph.class, gId); - if(graph == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphId); - } - if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); - } - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); + graph = database.getGraph(username, graphIdStr); + if(graph == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph does not exist: graph id " + graphIdStr); + } + if(graph.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Invalid graph creation method status for correlation calculation: " + graph.getCreationMethod().getStatus().name()); + } } List maps = new ArrayList(); for(int id : mapIds) { - long mapId = (long) id; - em = entityHandler.getEntityManager(); - CentralityMapId cId = new CentralityMapId(mapId, gId); - - EntityTransaction tx = em.getTransaction(); - CentralityMap map; - try { - tx.begin(); - map = em.find(CentralityMap.class, cId); - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } + String mapIdStr = Integer.toString(id); + CentralityMap map = database.getCentralityMap(username, graphIdStr, mapIdStr); if(map == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapId + ", graph id " + graphId); + requestHandler.log(Level.WARNING, "user: " + username + ", " + "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Centrality map does not exist: Centrality map id " + mapIdStr + ", graph id " + graphIdStr); } maps.add(map); } CentralityMap groundTruthMap = maps.get(0); maps = maps.subList(1, maps.size()); - double[] precisionVector = StatisticalProcessor.getPrecision(graph, groundTruthMap, maps, k); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": calculate top" + k + " precision using centralities" + mapIds + " based on " + graphIdStr); + double[] precisionVector = StatisticalProcessor.getPrecision(graph, groundTruthMap, maps, k); return Response.ok(requestHandler.writePrecisionResult(maps, precisionVector)).build(); } catch (Exception e) { @@ -2367,6 +2053,20 @@ public Response runGroundTruthBenchmark(@DefaultValue("unnamed") @QueryParam("co @DefaultValue("LFR") @QueryParam("benchmark") String creationTypeStr, String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); + + /* + Check if user has a limit regarding number of graph or covers and throw an error if the limit is violated. + */ + if (userLimitsHandler.reachedGraphCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached graph count limit."); + return requestHandler.writeError(Error.INTERNAL, "Graph count limit reached. Delete a graph before generating a new one, or contact administrator to adjust limits."); + } + if (userLimitsHandler.reachedCoverCountLimit(username)){ + requestHandler.log(Level.WARNING, "user: " + username + " reached cover count limit."); + return requestHandler.writeError(Error.INTERNAL, "Cover count limit reached. Delete a cover before generating a new one, or contact administrator to adjust limits."); + } + + GraphCreationType benchmarkType; CoverCreationType coverCreationType; try { @@ -2391,45 +2091,48 @@ public Response runGroundTruthBenchmark(@DefaultValue("unnamed") @QueryParam("co } else { try { parameters = requestHandler.parseParameters(contentStr); + + /* + Check if there is a limit on the graph size for the user and if this limit is violated + */ + if (parameters.get("n") != null){ + // limits set for user in userLimitInformation.json file + JSONObject userLimits = userLimitsHandler.getUserLimits(username); + if ( userLimits != null && userLimits.get("graphSize") != null && + Integer.parseInt((String) userLimits.get("graphSize")) < Integer.parseInt(parameters.get("n"))){ + requestHandler.log(Level.WARNING, "user: " + username + " is not allowed to generate graph of size " + parameters.get("n")); + return requestHandler.writeError(Error.INTERNAL, "Graph size is above the user's limit, contact administrator to adjust limits"); + } + } + benchmark = (GroundTruthBenchmark) benchmarkFactory.getInstance(benchmarkType, parameters); } catch (Exception e) { requestHandler.log(Level.WARNING, "user: " + username, e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } } - EntityManager em = entityHandler.getEntityManager(); + CustomGraph graph = new CustomGraph(); graph.setName(URLDecoder.decode(graphNameStr, "UTF-8")); graph.setUserName(username); GraphCreationLog log = new GraphCreationLog(benchmarkType, parameters); log.setStatus(ExecutionStatus.WAITING); graph.setCreationMethod(log); - Cover cover = new Cover(graph, new CCSMatrix(graph.nodeCount(), 0)); + Cover cover = new Cover(graph, new CCSMatrix(graph.getNodeCount(), 0)); cover.setName(URLDecoder.decode(coverNameStr, "UTF-8")); CoverCreationLog coverLog = new CoverCreationLog(coverCreationType, parameters, new HashSet()); coverLog.setStatus(ExecutionStatus.WAITING); cover.setCreationMethod(coverLog); synchronized (threadHandler) { - - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - em.persist(cover); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); + System.out.println("GraphKey : " + database.storeGraph(graph)); //TODO beides in einer transaktion + System.out.println("CoverKey : " + database.storeCover(cover)); /* * Registers and starts benchmark creation. */ threadHandler.runGroundTruthBenchmark(cover, benchmark); - } + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run " + creationTypeStr + " benchmark. Created graph " + graph.getKey() + ", cover " + cover.getKey()); + } return Response.ok(requestHandler.writeId(cover)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -2474,20 +2177,7 @@ public Response runStatisticalMeasure(@PathParam("coverId") String coverIdStr, String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } + OcdMetricType metricType; try { metricType = OcdMetricType.valueOf(metricTypeStr); @@ -2516,80 +2206,70 @@ public Response runStatisticalMeasure(@PathParam("coverId") String coverIdStr, return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } } - - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CoverId cId = new CoverId(coverId, gId); + /* * Finds cover */ OcdMetricLog log; synchronized (threadHandler) { - EntityTransaction tx = em.getTransaction(); + Cover cover; - try { - tx.begin(); - cover = em.find(Cover.class, cId); - if (cover == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " - + "Cover does not exist: cover id " + coverId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover does not exist."); - } - if (cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Invalid cover creation method status for metric execution: " - + cover.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Invalid cover creation method status for metric execution: " - + cover.getCreationMethod().getStatus().name()); - } - - boolean compatibleType = false; - if(cover.getGraph().getTypes().isEmpty()) - { - compatibleType = true; - } - else { - for(GraphType type : cover.getGraph().getTypes()) { - if(metric.compatibleGraphTypes().contains(type)) - { - compatibleType = true; - break; - } - } + cover = database.getCover(username, graphIdStr, coverIdStr); //done + if (cover == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + + "Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover does not exist."); + } + if (cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Invalid cover creation method status for metric execution: " + + cover.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Invalid cover creation method status for metric execution: " + + cover.getCreationMethod().getStatus().name()); + } + + boolean compatibleType = false; + if(cover.getGraph().getTypes().isEmpty()) + { + compatibleType = true; + } + else { + for(GraphType type : cover.getGraph().getTypes()) { + if(metric.compatibleGraphTypes().contains(type)) + { + compatibleType = true; + break; + } } - if(!compatibleType) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Metric not applicable with graph, needs one of these types: " - + metric.compatibleGraphTypes().toString()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Metric not applicable with graph, needs one of these types: " + metric.compatibleGraphTypes().toString()); - } - else if (metric instanceof NewmanModularityCombined && !cover.getGraph().isOfType(GraphType.CONTENT_LINKED) && !cover.getGraph().isOfType(GraphType.CONTENT_UNLINKED)) - { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Metric not applicable with graph, needs to be a graph with node content " - + metric.compatibleGraphTypes().toString()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Metric not applicable with graph, needs to be a graph with node content"); - } - - log = new OcdMetricLog(metricType, 0, parameters, cover); - log.setStatus(ExecutionStatus.WAITING); - cover.addMetric(log); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } + } + if(!compatibleType) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Metric not applicable with graph, needs one of these types: " + + metric.compatibleGraphTypes().toString()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Metric not applicable with graph, needs one of these types: " + metric.compatibleGraphTypes().toString()); + } + else if (metric instanceof NewmanModularityCombined && !cover.getGraph().isOfType(GraphType.CONTENT_LINKED) && !cover.getGraph().isOfType(GraphType.CONTENT_UNLINKED)) + { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Metric not applicable with graph, needs to be a graph with node content " + + metric.compatibleGraphTypes().toString()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Metric not applicable with graph, needs to be a graph with node content"); + } + log = new OcdMetricLog(metricType, 0, parameters, cover); + log.setStatus(ExecutionStatus.WAITING); + cover.addMetric(log); + database.updateCover(cover); //TODO hier muss eine funktion hin, die ein bestehendes cover aendert threadHandler.runStatisticalMeasure(log, metric, cover); - } - + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run statistical measure " + metricTypeStr + " on cover " + coverIdStr + " with parameters " + parameters); + + } + return Response.ok(requestHandler.writeId(log)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -2635,27 +2315,7 @@ public Response runKnowledgeDrivenMeasure(@PathParam("coverId") String coverIdSt @PathParam("groundTruthCoverId") String groundTruthCoverIdStr, String contentStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } - long groundTruthCoverId; - try { - groundTruthCoverId = Long.parseLong(groundTruthCoverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Ground truth cover id is not valid."); - } + OcdMetricType metricType; try { metricType = OcdMetricType.valueOf(metricTypeStr); @@ -2684,70 +2344,64 @@ public Response runKnowledgeDrivenMeasure(@PathParam("coverId") String coverIdSt return requestHandler.writeError(Error.PARAMETER_INVALID, "Parameters are not valid."); } } - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CoverId cId = new CoverId(coverId, gId); - CoverId gtId = new CoverId(groundTruthCoverId, gId); + /* * Finds cover */ OcdMetricLog log; synchronized (threadHandler) { - EntityTransaction tx = em.getTransaction(); Cover cover; Cover groundTruth; - try { - tx.begin(); - cover = em.find(Cover.class, cId); - if (cover == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " - + "Cover does not exist: cover id " + coverId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Cover does not exist: cover id " + coverId + ", graph id " + graphId); - } - if (cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Invalid cover creation method status for metric execution: " - + cover.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Invalid cover creation method status for metric execution: " - + cover.getCreationMethod().getStatus().name()); - } - if (groundTruthCoverId != coverId) { - groundTruth = em.find(Cover.class, gtId); - if (groundTruth == null) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Ground truth cover does not exist: cover id " - + groundTruthCoverId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Ground truth cover does not exist: cover id " + groundTruthCoverId - + ", graph id " + graphId); - } - } else { - groundTruth = cover; - } - if (groundTruth.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - requestHandler.log(Level.WARNING, - "user: " + username + ", " - + "Invalid ground truth cover creation method status for metric execution: " - + groundTruth.getCreationMethod().getStatus().name()); - return requestHandler.writeError(Error.PARAMETER_INVALID, - "Invalid ground truth cover creation method status for metric execution: " - + groundTruth.getCreationMethod().getStatus().name()); - } - log = new OcdMetricLog(metricType, 0, parameters, cover); - log.setStatus(ExecutionStatus.WAITING); - cover.addMetric(log); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } + + cover = database.getCover(username, graphIdStr, coverIdStr); + if (cover == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + + "Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr); + } + if (cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Invalid cover creation method status for metric execution: " + + cover.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Invalid cover creation method status for metric execution: " + + cover.getCreationMethod().getStatus().name()); + } + if (!groundTruthCoverIdStr.equals(coverIdStr)) { + + //System.out.println("Cover und GT are not equal"); + groundTruth = database.getCover(username, graphIdStr, groundTruthCoverIdStr); + if (groundTruth == null) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + "Ground truth cover does not exist: cover id " + + groundTruthCoverIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Ground truth cover does not exist: cover id " + groundTruthCoverIdStr + + ", graph id " + graphIdStr); + } + } else { + //System.out.println("Cover und GT are equal : Cover :" + coverIdStr + " GroundTruth :" + groundTruthCoverIdStr); + groundTruth = cover; + } + if (groundTruth.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + requestHandler.log(Level.WARNING, + "user: " + username + ", " + + "Invalid ground truth cover creation method status for metric execution: " + + groundTruth.getCreationMethod().getStatus().name()); + return requestHandler.writeError(Error.PARAMETER_INVALID, + "Invalid ground truth cover creation method status for metric execution: " + + groundTruth.getCreationMethod().getStatus().name()); + } + log = new OcdMetricLog(metricType, 0, parameters, cover); + log.setStatus(ExecutionStatus.WAITING); + cover.addMetric(log); + + database.updateCover(cover); //done ? threadHandler.runKnowledgeDrivenMeasure(log, metric, cover, groundTruth); - } + generalLogger.getLogger().log(Level.INFO, "user " + username + ": run knowledge driven measure " + metricTypeStr + " on cover " + coverIdStr + " with parameters " + parameters); + } return Response.ok(requestHandler.writeId(log)).build(); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -2777,54 +2431,23 @@ public Response deleteMetric(@PathParam("coverId") String coverIdStr, @PathParam @PathParam("metricId") String metricIdStr) { try { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - long graphId; - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } - long metricId; - try { - metricId = Long.parseLong(metricIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Metric id is not valid."); - } - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CoverId cId = new CoverId(coverId, gId); - OcdMetricLogId mId = new OcdMetricLogId(metricId, cId); - EntityTransaction tx = em.getTransaction(); + + CustomGraphId gId = new CustomGraphId(graphIdStr, username); + CoverId cId = new CoverId(coverIdStr, gId); + OcdMetricLogId mId = new OcdMetricLogId(metricIdStr, cId); OcdMetricLog log; /* * Deletes the metric. */ synchronized (threadHandler) { - tx = em.getTransaction(); - try { - tx.begin(); - log = em.find(OcdMetricLog.class, mId); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } + + log = database.getOcdMetricLog(username, graphIdStr, coverIdStr, metricIdStr); if (log == null) { requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Metric does not exist: cover id " + coverId - + ", graph id " + graphId + ", metric id " + metricId); + "user: " + username + ", " + "Metric does not exist: cover id " + coverIdStr + + ", graph id " + graphIdStr + ", metric id " + metricIdStr); return requestHandler.writeError(Error.PARAMETER_INVALID, "Metric does not exist: cover id " - + coverId + ", graph id " + graphId + ", metric id " + metricId); + + coverIdStr + ", graph id " + graphIdStr + ", metric id " + metricIdStr); } /* * Interrupts metric. @@ -2833,20 +2456,11 @@ public Response deleteMetric(@PathParam("coverId") String coverIdStr, @PathParam /* * Removes metric */ - tx = em.getTransaction(); - try { - tx.begin(); - log.getCover().removeMetric(log); - em.remove(log); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - return Response.ok(requestHandler.writeConfirmationXml()).build(); + Cover cover = log.getCover(); + cover.removeMetric(log); + database.updateCover(cover); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": delete metric " + coverIdStr); + return Response.ok(requestHandler.writeConfirmationXml()).build(); } } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); @@ -2900,21 +2514,9 @@ public Response getCoverVisualization(@PathParam("graphId") String graphIdStr, @DefaultValue("20") @QueryParam("minNodeSize") String minNodeSizeStr, @DefaultValue("45") @QueryParam("maxNodeSize") String maxNodeSizeStr) { try { - long graphId; + String username = getUserName(); - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long coverId; - try { - coverId = Long.parseLong(coverIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Cover id is not valid."); - } + double minNodeSize; try { minNodeSize = Double.parseDouble(minNodeSizeStr); @@ -2972,31 +2574,18 @@ public Response getCoverVisualization(@PathParam("graphId") String graphIdStr, return requestHandler.writeError(Error.PARAMETER_INVALID, "Label edges is not a boolean value."); } - Cover cover = entityHandler.getCover(username, graphId, coverId); + Cover cover = database.getCover(username, graphIdStr, coverIdStr); //done if (cover == null) { requestHandler.log(Level.WARNING, "user: " + username + ", " + "Cover does not exist: cover id " - + coverId + ", graph id " + graphId); + + coverIdStr + ", graph id " + graphIdStr); return requestHandler.writeError(Error.PARAMETER_INVALID, - "Cover does not exist: cover id " + coverId + ", graph id " + graphId); + "Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr); } layoutHandler.doLayout(cover, layout, doLabelNodes, doLabelEdges, minNodeSize, maxNodeSize, painting); - - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.merge(cover); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - - return requestHandler.writeCover(cover, format); + database.updateCover(cover); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get visualization of cover " + coverIdStr + " in " +visualOutputFormatStr + " format." ); + return requestHandler.writeCover(cover, format); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); return requestHandler.writeError(Error.INTERNAL, "Internal system error."); @@ -3039,14 +2628,9 @@ public Response getGraphVisualization(@PathParam("graphId") String graphIdStr, @DefaultValue("20") @QueryParam("minNodeSize") String minNodeSizeStr, @DefaultValue("45") @QueryParam("maxNodeSize") String maxNodeSizeStr) { try { - long graphId; + String username = getUserName(); - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } + double minNodeSize; try { minNodeSize = Double.parseDouble(minNodeSizeStr); @@ -3097,16 +2681,16 @@ public Response getGraphVisualization(@PathParam("graphId") String graphIdStr, return requestHandler.writeError(Error.PARAMETER_INVALID, "Label edges is not a boolean value."); } - CustomGraph graph = entityHandler.getGraph(username, graphId); + CustomGraph graph = database.getGraph(username, graphIdStr); //done if (graph == null) { requestHandler.log(Level.WARNING, - "user: " + username + ", " + "Graph does not exist: graph id " + graphId); + "user: " + username + ", " + "Graph does not exist: graph id " + graphIdStr); return requestHandler.writeError(Error.PARAMETER_INVALID, - "Graph does not exist: graph id " + graphId); + "Graph does not exist: graph id " + graphIdStr); } - layoutHandler.doLayout(graph, layout, doLabelNodes, doLabelEdges, minNodeSize, maxNodeSize); - return requestHandler.writeGraph(graph, format); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get visualization of graph " + graphIdStr + " in " +visualOutputFormatStr + " format." ); + return requestHandler.writeGraph(graph, format); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); return requestHandler.writeError(Error.INTERNAL, "Internal system error."); @@ -3144,21 +2728,9 @@ public Response getCentralityMapVisualization( @DefaultValue("TRUE") @QueryParam("doLabelNodes") String doLabelNodesStr, @DefaultValue("TRUE") @QueryParam("showEdgeWeights") String showEdgeWeightsStr) { try { - long graphId; + String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - try { - graphId = Long.parseLong(graphIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "Graph id is not valid."); - } - long centralityMapId; - try { - centralityMapId = Long.parseLong(centralityMapIdStr); - } catch (Exception e) { - requestHandler.log(Level.WARNING, "user: " + username, e); - return requestHandler.writeError(Error.PARAMETER_INVALID, "CentralityMap id is not valid."); - } + VisualOutputFormat format; GraphLayoutType layout; boolean doLabelNodes; @@ -3193,32 +2765,20 @@ public Response getCentralityMapVisualization( } catch (Exception e) { requestHandler.log(Level.WARNING, "", e); return requestHandler.writeError(Error.PARAMETER_INVALID, "Label edges is not a boolean value."); - } - EntityManager em = entityHandler.getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CentralityMapId cId = new CentralityMapId(centralityMapId, gId); - EntityTransaction tx = em.getTransaction(); - CentralityMap map; - try { - tx.begin(); - map = em.find(CentralityMap.class, cId); - if(map == null) { - requestHandler.log(Level.WARNING, "user: " + username + ", " + "CentralityMap does not exist: CentralityMap id " + centralityMapId + ", graph id " + graphId); - return requestHandler.writeError(Error.PARAMETER_INVALID, "CentralityMap does not exist: CentralityMap id " + centralityMapId + ", graph id " + graphId); - } - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); + } + + + CentralityMap map = database.getCentralityMap(username, graphIdStr, centralityMapIdStr); //444 should take gId + if(map == null) { + requestHandler.log(Level.WARNING, "user: " + username + ", " + "CentralityMap does not exist: CentralityMap id " + centralityMapIdStr + ", graph id " + graphIdStr); + return requestHandler.writeError(Error.PARAMETER_INVALID, "CentralityMap does not exist: CentralityMap id " + centralityMapIdStr + ", graph id " + graphIdStr); + } if(doLabelEdges) { doLabelEdges = map.getGraph().getTypes().contains(GraphType.WEIGHTED) ? true : false; } layoutHandler.doLayout(map, layout, doLabelNodes, doLabelEdges, centralityVisualizationType); - return requestHandler.writeCentralityMap(map, format); + generalLogger.getLogger().log(Level.INFO, "user " + username + ": get visualization of centrality " + centralityMapIdStr + " in " +visualOutputFormatStr + " format." ); + return requestHandler.writeCentralityMap(map, format); } catch (Exception e) { requestHandler.log(Level.SEVERE, "", e); return requestHandler.writeError(Error.INTERNAL, "Internal system error."); @@ -3261,6 +2821,7 @@ public Response getAlgorithmDefaultParams(@PathParam("CoverCreationType") String } else { OcdAlgorithm defaultInstance = algorithmFactory.getInstance(creationType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get default parameters of " + coverCreationTypeStr ); return Response.ok(requestHandler.writeParameters(defaultInstance.getParameters())).build(); } } catch (Exception e) { @@ -3304,6 +2865,7 @@ public Response getCentralityAlgorithmDefaultParams( } else { CentralityAlgorithm defaultInstance = centralityAlgorithmFactory.getInstance(centralityMeasureType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get default parameters of centrality measure " + centralityMeasureTypeStr ); return Response.ok(requestHandler.writeParameters(defaultInstance.getParameters())).build(); } } @@ -3347,6 +2909,7 @@ public Response getSimulationDefaultParams( } else { CentralitySimulation defaultInstance = centralitySimulationFactory.getInstance(simulationType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get default parameters of centrality simulation " + simulationTypeStr ); return Response.ok(requestHandler.writeParameters(defaultInstance.getParameters())).build(); } } @@ -3389,6 +2952,7 @@ public Response getBenchmarkDefaultParams(@PathParam("GraphCreationType") String if (creationType.correspondsGroundTruthBenchmark()) { GroundTruthBenchmark defaultInstance = (GroundTruthBenchmark) benchmarkFactory .getInstance(creationType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get default parameters of benchmark " + graphCreationTypeStr ); return Response.ok(requestHandler.writeParameters(defaultInstance.getParameters())).build(); } else { throw new NotImplementedException("Specified graph creation type is not a benchmark."); @@ -3436,6 +3000,7 @@ public Response getMetricDefaultParameters(@PathParam("OcdMetricType") String oc if (metricType.correspondsStatisticalMeasure()) { StatisticalMeasure defaultInstance = (StatisticalMeasure) metricFactory.getInstance(metricType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get default parameters of metric " + metricType); return Response.ok(requestHandler.writeParameters(defaultInstance.getParameters())).build(); } else { throw new NotImplementedException("Metric type is not properly registered."); @@ -3502,6 +3067,7 @@ public Response getAlgorithmCompatibleGraphTypes(@PathParam("CoverCreationType") } else { OcdAlgorithm defaultInstance = algorithmFactory.getInstance(creationType, new HashMap()); + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get compatible graph types for OCDA " + coverCreationTypeStr); return Response.ok(requestHandler.writeSpecificEnumNames(defaultInstance.compatibleGraphTypes())).build(); } } catch (Exception e) { @@ -3648,6 +3214,7 @@ public Response getCentralitySimulationCompatibleGraphTypes(@PathParam("Centrali return requestHandler.writeError(Error.PARAMETER_INVALID, "Specified cover creation type is not instantiatable: " + simulationType.name()); } else { + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get compatible graph types for centrality simulation " + centralitySimulationTypeStr); CentralitySimulation defaultInstance = centralitySimulationFactory.getInstance(simulationType, new HashMap()); return Response.ok(requestHandler.writeSpecificEnumNames(defaultInstance.compatibleGraphTypes())).build(); @@ -4016,10 +3583,10 @@ public Response getCentralityVisualizationTypeNames() { public Response getSimulations(SimulationSeriesParameters parameters) { List series = new ArrayList<>(); - String userId = getUserId(); + String userId = getUserName(); try { - series = entityHandler.getSimulationSeriesByUser(userId); + series = database.getSimulationSeriesByUser(userId); } catch (Exception e) { Context.getCurrent().monitorEvent(this, MonitoringEvent.SERVICE_ERROR, "fail to get simulation series. " + e.toString()); @@ -4041,23 +3608,24 @@ public Response getSimulations(SimulationSeriesParameters parameters) { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) public Response getSimulationMeta(@DefaultValue("0") @QueryParam("firstIndex") int firstIndex, - @DefaultValue("0") @QueryParam("length") int length, - @DefaultValue("0") @QueryParam("graphId") long graphId, - SimulationSeriesParameters parameters) { + @DefaultValue("0") @QueryParam("length") int length, + @DefaultValue("0") @QueryParam("graphId") String graphKey, + SimulationSeriesParameters parameters) { if (parameters == null) { parameters = new SimulationSeriesParameters(); } - + List simulations = new ArrayList<>(); try { if (firstIndex < 0 || length <= 0) { - simulations = entityHandler.getSimulationSeriesByUser(getUserId()); + + simulations = database.getSimulationSeriesByUser(getUserName()); } else { - if (graphId <= 0) { - simulations = entityHandler.getSimulationSeriesByUser(getUserId(), firstIndex, length); + if (graphKey.equals("0")) { + simulations = database.getSimulationSeriesByUser(getUserName(), firstIndex, length); } else { - simulations = entityHandler.getSimulationSeriesByUser(getUserId(), graphId, firstIndex, length); + simulations = database.getSimulationSeriesByUser(getUserName(), graphKey, firstIndex,length); } } } catch (Exception e) { @@ -4075,7 +3643,7 @@ public Response getSimulationMeta(@DefaultValue("0") @QueryParam("firstIndex") i for (SimulationSeries simulation : simulations) { try { SimulationSeriesMetaData metaData = simulation.getMetaData(); - metaData.setGraphName(entityHandler.getGraph(getUserName(), simulation.getParameters().getGraphId()).getName()); + metaData.setGraphName(database.getGraph(getUserName(), simulation.getSimulationSeriesParameters().getGraphKey()).getName()); metaList.add(metaData); } catch (Exception e) { @@ -4091,7 +3659,7 @@ public Response getSimulationMeta(@DefaultValue("0") @QueryParam("firstIndex") i /** * Gets the results of a performed simulation series on a network * - * @param seriesId the id of the series + * @param seriesKey the key of the series * @return HttpResponse with the returnString */ @GET @@ -4101,16 +3669,15 @@ public Response getSimulationMeta(@DefaultValue("0") @QueryParam("firstIndex") i @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulation(@PathParam("seriesId") long seriesId) { - + public Response getSimulation(@PathParam("seriesId") String seriesKey) { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); SimulationSeries series = null; try { - series = entityHandler.getSimulationSeries(seriesId); + series = database.getSimulationSeries(seriesKey); if (series == null) - return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + seriesId + " found") + return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + seriesKey + " found") .build(); if (!series.isEvaluated()) { @@ -4118,18 +3685,18 @@ public Response getSimulation(@PathParam("seriesId") long seriesId) { } } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("internal error").build(); } - + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get results of simulation series with id " + seriesId ); return Response.ok().entity(series).build(); } /** * Gets the results of a performed simulation series on a network * - * @param seriesId the id of the series + * @param seriesKey the key of the series * @return HttpResponse with the returnString */ @GET @@ -4139,22 +3706,21 @@ public Response getSimulation(@PathParam("seriesId") long seriesId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulationTable(@PathParam("seriesId") long seriesId) { - + public Response getSimulationTable(@PathParam("seriesId") String seriesKey) { String username = getUserName(); SimulationSeries series = null; try { - series = entityHandler.getSimulationSeries(seriesId); + series = database.getSimulationSeries(seriesKey); if (series == null) - return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + seriesId + " found") + return Response.status(Status.BAD_REQUEST).entity("no simulation with key " + seriesKey + " found") .build(); series.evaluate(); } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("internal error").build(); } @@ -4165,14 +3731,14 @@ public Response getSimulationTable(@PathParam("seriesId") long seriesId) { } catch (Exception e) { e.printStackTrace(); } - + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get results of simulation series with id " + seriesId ); return Response.ok().entity(responseString).build(); } /** * Gets the parameters of a simulation * - * @param seriesId the id of the series + * @param seriesKey the key of the series to which the parameters belong * @return HttpResponse with the returnString */ @GET @@ -4182,13 +3748,13 @@ public Response getSimulationTable(@PathParam("seriesId") long seriesId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulationParameters(@PathParam("seriesId") long seriesId) { - + public Response getSimulationParameters(@PathParam("seriesId") String seriesKey) { + SimulationSeriesParameters parameters = null; try { - parameters = entityHandler.getSimulationParameters(seriesId); + parameters = database.getSimulationSeries(seriesKey).getSimulationSeriesParameters(); } catch (Exception e) { - logger.log(Level.WARNING, "fail to get simulation series parameters"); + generalLogger.getLogger().log(Level.WARNING, "fail to get simulation series parameters"); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("fail to get simulation series parameters") .build(); } @@ -4199,7 +3765,7 @@ public Response getSimulationParameters(@PathParam("seriesId") long seriesId) { /** * Deletes a performed simulation series on a network * - * @param seriesId the id of the series + * @param seriesKey the key of the series * @return HttpResponse with the returnString */ @DELETE @@ -4209,10 +3775,9 @@ public Response getSimulationParameters(@PathParam("seriesId") long seriesId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response deleteSimulation(@PathParam("seriesId") long seriesId) { - + public Response deleteSimulation(@PathParam("seriesId") String seriesKey) { try { - entityHandler.deleteSeries(seriesId); + database.deleteSimulationSeries(seriesKey); } catch (Exception e) { return Response.serverError().entity(e.getMessage()).build(); } @@ -4223,9 +3788,9 @@ public Response deleteSimulation(@PathParam("seriesId") long seriesId) { /** * Starts the simulation of a cooperation and defection game simulation - * + * * @param parameters the parameters - * + * * @return HttpResponse with the returnString */ @POST @@ -4238,9 +3803,7 @@ public Response deleteSimulation(@PathParam("seriesId") long seriesId) { public Response postSimulation(SimulationSeriesParameters parameters) { String username = getUserName(); - - long graphId = parameters.getGraphId(); - CustomGraph network = entityHandler.getGraph(username, graphId); + CustomGraph network = database.getGraph(getUserName(), parameters.getGraphKey()); if (network == null) return Response.status(Status.BAD_REQUEST).entity("graph not found").build(); @@ -4270,18 +3833,19 @@ public Response postSimulation(SimulationSeriesParameters parameters) { series = simulationBuilder.simulate(); } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.serverError().entity("simulation could not be carried out\n" + e.getMessage()).build(); } - - if(series.getSimulationDatasets() == null || !(series.getSimulationDatasets().size() == parameters.getIterations())) + + if(series.getSimulationDatasets() == null || !(series.getSimulationDatasets().size() == parameters.getIterations())) return Response.serverError().entity("something went wrong").build(); - - long result; + + String result; try { - result = entityHandler.store(series, getUserId()); - + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": start simulation with parameters " + parameters ); + result = database.storeSimulationSeries(series, getUserName()); + } catch (Exception e) { e.printStackTrace(); return Response.serverError().entity("simulation not stored").build(); @@ -4300,15 +3864,15 @@ public Response postSimulation(SimulationSeriesParameters parameters) { @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) @ApiOperation(tags = {"execution"}, value = "Run simulation group", notes = " Starts a simulation group of evolutionary cooperation or defection games ") public Response putSimulationGroup(@DefaultValue("") @QueryParam("name") String name, - List seriesIds) { - - List series = new ArrayList<>(seriesIds.size()); + List seriesKeys) { + + List series = new ArrayList<>(seriesKeys.size()); try { - for(Integer id: seriesIds) { - series.add(entityHandler.getSimulationSeries(id)); + for(String seriesKey: seriesKeys) { + series.add(database.getSimulationSeries(seriesKey)); } } catch (Exception e) { - logger.log(Level.WARNING, "user: " + getUserName(), e); + generalLogger.getLogger().log(Level.WARNING, "user: " + getUserName(), e); e.printStackTrace(); return Response.serverError().entity("Invalid simulation series \n" + e.getMessage()).build(); } @@ -4318,9 +3882,9 @@ public Response putSimulationGroup(@DefaultValue("") @QueryParam("name") String group = new SimulationSeriesGroup(series); group.setName(name); - entityHandler.store(group, getUserId()); - - + group.calculateMetaData(); // calculate and store metadata that will be used for WebClient + database.storeSimulationSeriesGroup(group, getUserName()); + } catch (Exception e) { e.printStackTrace(); return Response.serverError().entity("fail store series group").build(); @@ -4337,13 +3901,13 @@ public Response putSimulationGroup(@DefaultValue("") @QueryParam("name") String @ApiOperation(tags = {"show"}, value = "Get Simulation Group Meta", notes = "Returns the meta information for a performed group of simulations") public Response getSimulationGroups(@DefaultValue("0") @QueryParam("firstIndex") int firstIndex, @DefaultValue("0") @QueryParam("length") int length) { - + List simulations = new ArrayList<>(); try { if (firstIndex < 0 || length <= 0) { - simulations = entityHandler.getSimulationSeriesGroups(getUserId()); + simulations = database.getSimulationSeriesGroups(getUserName()); } else { - simulations = entityHandler.getSimulationSeriesGroups(getUserId(), firstIndex, length); + simulations = database.getSimulationSeriesGroups(getUserName(), firstIndex, length); } } catch (Exception e) { Context.getCurrent().monitorEvent(this, MonitoringEvent.SERVICE_ERROR, "fail to get simulation series. " + e.toString()); @@ -4351,14 +3915,16 @@ public Response getSimulationGroups(@DefaultValue("0") @QueryParam("firstIndex") e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("fail to get simulation series").build(); } - - if (simulations == null || simulations.size() < 1) + + if (simulations == null || simulations.size() < 1) { return Response.status(Status.BAD_REQUEST).entity("No simulation series found").build(); - + } + List metaList = new ArrayList<>(simulations.size()); try { for (SimulationSeriesGroup simulation : simulations) { - SimulationSeriesGroupMetaData metaData = simulation.getMetaData(); + SimulationSeriesGroupMetaData metaData = simulation.getGroupMetaData(); + metaData.setKey(simulation.getKey()); // set group key, which became available when group was created metaList.add(metaData); } } catch (Exception e) { @@ -4371,7 +3937,7 @@ public Response getSimulationGroups(@DefaultValue("0") @QueryParam("firstIndex") /** * Gets the results of a performed simulation series group on a network * - * @param groupId the id of the group + * @param groupKey the id of the group * @return HttpResponse with the returnString */ @GET @@ -4381,33 +3947,38 @@ public Response getSimulationGroups(@DefaultValue("0") @QueryParam("firstIndex") @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulationGroupTable(@PathParam("groupId") long groupId) { - + public Response getSimulationGroupTable(@PathParam("groupId") String groupKey) { String username = getUserName(); - SimulationSeriesGroup series = null; + SimulationSeriesGroup simulationSeriesGroup = null; try { - series = entityHandler.getSimulationSeriesGroup(groupId); + simulationSeriesGroup = database.getSimulationSeriesGroup(groupKey); + + List simulationSeriesInGroup = new ArrayList<>(); + for (String simulationSeriesKey : simulationSeriesGroup.getSimulationSeriesKeys()){ + simulationSeriesInGroup.add(database.getSimulationSeries(simulationSeriesKey)); + } + simulationSeriesGroup.setSimulationSeries(simulationSeriesInGroup); - if (series == null) - return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + groupId + " found") + if (simulationSeriesGroup == null) + return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + groupKey + " found") .build(); - series.evaluate(); + simulationSeriesGroup.evaluate(); } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("internal error").build(); } String responseString = ""; try { - responseString = series.toTable().print(); + responseString = simulationSeriesGroup.toTable().print(); } catch (Exception e) { e.printStackTrace(); } - + //generalLogger.getLogger().log(Level.INFO, "user " + username + ": get results of simulation series with id " + groupId ); return Response.ok().entity(responseString).build(); } @@ -4418,11 +3989,17 @@ public Response getSimulationGroupTable(@PathParam("groupId") long groupId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) @ApiOperation(tags = {"show"}, value = "Get a Simulation Group", notes = "Returns a performed simulation group") - public Response getSimulationGroup(@PathParam("groupId") long groupId) { - + public Response getSimulationGroup(@PathParam("groupId") String groupKey) { SimulationSeriesGroup simulation = null; - try { - simulation = entityHandler.getSimulationSeriesGroup(groupId); + try { + simulation = database.getSimulationSeriesGroup(groupKey); + + List simulationSeriesInGroup = new ArrayList<>(); + for (String simulationSeriesKey : simulation.getSimulationSeriesKeys()){ + simulationSeriesInGroup.add(database.getSimulationSeries(simulationSeriesKey)); + } + simulation.setSimulationSeries(simulationSeriesInGroup); + if(!simulation.isEvaluated()) simulation.evaluate(); @@ -4442,7 +4019,7 @@ public Response getSimulationGroup(@PathParam("groupId") long groupId) { /** * Deletes a simulation series group * - * @param groupId the id of the group + * @param groupKey the id of the group * @return HttpResponse with the returnString */ @DELETE @@ -4452,14 +4029,14 @@ public Response getSimulationGroup(@PathParam("groupId") long groupId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response deleteSimulationSeriesGroup(@PathParam("groupId") long groupId) { - + public Response deleteSimulationSeriesGroup(@PathParam("groupId") String groupKey) { try { - entityHandler.deleteGroup(groupId); + database.deleteSimulationSeriesGroup(groupKey); } catch (Exception e) { e.printStackTrace(); return Response.serverError().entity(e.getMessage()).build(); - } + } + generalLogger.getLogger().log(Level.INFO, "user " + getUserName() + ": delete simulation series with id " + groupKey ); return Response.ok("done").build(); } @@ -4473,34 +4050,44 @@ public Response deleteSimulationSeriesGroup(@PathParam("groupId") long groupId) @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulationGroupMapping(@PathParam("groupId") long groupId) { - + public Response getSimulationGroupMapping(@PathParam("groupId") String groupKey) { + String username = getUserName(); SimulationSeriesGroup simulationGroup = null; SimulationSeriesSetMapping mapping; try { - simulationGroup = entityHandler.getSimulationSeriesGroup(groupId); + simulationGroup = database.getSimulationSeriesGroup(groupKey); + + List simulationSeriesInGroup = new ArrayList<>(); + for (String simulationSeriesKey : simulationGroup.getSimulationSeriesKeys()){ + simulationSeriesInGroup.add(database.getSimulationSeries(simulationSeriesKey)); + } + simulationGroup.setSimulationSeries(simulationSeriesInGroup); - if (simulationGroup == null) - return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + groupId + " found") + + if (simulationGroup == null) { + return Response.status(Status.BAD_REQUEST).entity("no simulation with id " + groupKey + " found") .build(); + } - if (!simulationGroup.isEvaluated()) + if (!simulationGroup.isEvaluated()) { simulationGroup.evaluate(); - + } + MappingFactory factory = new MappingFactory(); - mapping = factory.build(simulationGroup.getSimulationSeries(), simulationGroup.getName()); + mapping = factory.build(simulationGroup.getSeriesList(), simulationGroup.getName()); for(SimulationSeries sim: mapping.getSimulation()) { - sim.setNetwork(entityHandler.getGraph(getUserName(), sim.getParameters().getGraphId())); + sim.setNetwork(database.getGraph(getUserName(), sim.getSimulationSeriesParameters().getGraphKey())); } - - if (!mapping.isEvaluated()) + + if (!mapping.isEvaluated()) { mapping.correlate(); + } } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("internal error").build(); } @@ -4519,16 +4106,23 @@ public Response getSimulationGroupMapping(@PathParam("groupId") long groupId) { @ApiResponses(value = { @ApiResponse(code = HttpURLConnection.HTTP_OK, message = "OK"), @ApiResponse(code = HttpURLConnection.HTTP_UNAUTHORIZED, message = "Unauthorized") }) - public Response getSimulationGroupsMapping(List groupIds) { + public Response getSimulationGroupsMapping(List groupKeys) { String username = getUserName(); - List groups = new ArrayList<>(groupIds.size()); + List groups = new ArrayList<>(groupKeys.size()); SimulationGroupSetMapping mapping = null; try { - for (Long groupId : groupIds) { + for (String groupKey : groupKeys) { try { - SimulationSeriesGroup group = entityHandler.getSimulationSeriesGroup(groupId); + SimulationSeriesGroup group = database.getSimulationSeriesGroup(groupKey); + // load simulation series belonging to the group + // based on the simulation series keys stored in the group + List simulationSeriesInGroup = new ArrayList<>(); + for (String simulationSeriesKey : group.getSimulationSeriesKeys()){ + simulationSeriesInGroup.add(database.getSimulationSeries(simulationSeriesKey)); + } + group.setSimulationSeries(simulationSeriesInGroup); groups.add(group); } catch (Exception e) { @@ -4540,10 +4134,10 @@ public Response getSimulationGroupsMapping(List groupIds) { try { for (int i = 0; i < groups.size(); i++) { - for (int j = 0; j < groups.get(i).getSimulationSeries().size(); j++) { - groups.get(i).getSimulationSeries().get(j).setNetwork(entityHandler.getGraph(getUserName(), - groups.get(i).getSimulationSeries().get(j).getParameters().getGraphId())); - groups.get(i).getSimulationSeries().get(j).evaluate(); + for (int j = 0; j < groups.get(i).getSeriesList().size(); j++) { + groups.get(i).getSeriesList().get(j).setNetwork(database.getGraph(getUserName(), + groups.get(i).getSeriesList().get(j).getSimulationSeriesParameters().getGraphKey())); + groups.get(i).getSeriesList().get(j).evaluate(); } groups.get(i).evaluate(); } @@ -4555,7 +4149,7 @@ public Response getSimulationGroupsMapping(List groupIds) { } } catch (Exception e) { - logger.log(Level.WARNING, "user: " + username, e); + generalLogger.getLogger().log(Level.WARNING, "user: " + username, e); e.printStackTrace(); return Response.status(Status.INTERNAL_SERVER_ERROR).entity("internal error").build(); } @@ -4631,24 +4225,23 @@ public Response getBreakConditions() { * method invocation. It returns only default types and classes. * * - * @param graphId + * @param graphIdStr * Id of the requested stored graph * @return HashMap * */ - public Map getGraphById(long graphId) { - + public Map getGraphById(String graphIdStr) { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); CustomGraph graph; try { - graph = entityHandler.getGraph(username, graphId); + graph = database.getGraph(username, graphIdStr); } catch (Exception e) { e.printStackTrace(); return null; } - Integer nodeCount = graph.nodeCount(); - Integer edgeCount = graph.edgeCount(); + Integer nodeCount = graph.getNodeCount(); + Integer edgeCount = graph.getEdgeCount(); Boolean directed = graph.isDirected(); Boolean weighted = graph.isWeighted(); String name = graph.getName(); @@ -4664,7 +4257,7 @@ public Map getGraphById(long graphId) { graphData.put("name", name); graphData.put("graph", adjList); - logger.log(Level.INFO, "RMI requested a graph: " + graphId); + generalLogger.getLogger().log(Level.INFO, "RMI requested a graph: " + graphIdStr); return graphData; } @@ -4674,17 +4267,16 @@ public Map getGraphById(long graphId) { * @return List * @throws AgentNotRegisteredException if the agent was not registered */ - public List getGraphIds() throws AgentNotRegisteredException { - + public List getGraphIds() throws AgentNotRegisteredException { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - List graphIdList = new ArrayList(); + List graphIdList = new ArrayList(); - List graphList = entityHandler.getGraphs(username); + List graphList = database.getGraphs(username); for (int i = 0, si = graphList.size(); i < si; i++) { - graphIdList.add(graphList.get(i).getId()); + graphIdList.add(graphList.get(i).getKey()); } - logger.log(Level.INFO, "RMI requested graph Ids"); + generalLogger.getLogger().log(Level.INFO, "RMI requested graph Ids"); return graphIdList; } @@ -4696,9 +4288,9 @@ public List getGraphIds() throws AgentNotRegisteredException { * This method is intended to be used by other las2peer services for remote * method invocation. It returns only default types and classes. * - * @param graphId + * @param graphIdStr * Index of the requested graph - * @param coverId + * @param coverIdStr * Index of the requested community cover * * @return HashMap including the community members lists. The outer list has @@ -4706,12 +4298,11 @@ public List getGraphIds() throws AgentNotRegisteredException { * contains the indices of the member nodes. * */ - public Map getCoverById(long graphId, long coverId) { - + public Map getCoverById(String graphIdStr, String coverIdStr) { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); Cover cover; try { - cover = entityHandler.getCover(username, graphId, coverId); + cover = database.getCover(username, graphIdStr, coverIdStr); } catch (Exception e) { e.printStackTrace(); return null; @@ -4726,8 +4317,8 @@ public Map getCoverById(long graphId, long coverId) { Map coverData = new HashMap(); coverData.put("size", communityCount); coverData.put("algorithm", algorithm); - coverData.put("graphId", graphId); - coverData.put("coverId", coverId); + coverData.put("graphId", graphIdStr); + coverData.put("coverId", coverIdStr); coverData.put("cover", communityMemberList); return coverData; @@ -4739,25 +4330,24 @@ public Map getCoverById(long graphId, long coverId) { * This method is intended to be used by other las2peer services for remote * method invocation. It returns only default types and classes. * - * @param graphId + * @param graphIdStr * Index of the requested graph * * @return list containing cover indices. * */ - public List getCoverIdsByGraphId(long graphId) { - + public List getCoverIdsByGraphId(String graphIdStr) { String username = ((UserAgent) Context.getCurrent().getMainAgent()).getLoginName(); - List covers = entityHandler.getCovers(username, graphId); + List covers = database.getCovers(username, graphIdStr); int size = covers.size(); - List coverIds = new ArrayList<>(size); + List coverIds = new ArrayList<>(size); for (int i = 0; i < size; i++) { - coverIds.add(covers.get(i).getId()); + coverIds.add(covers.get(i).getKey()); } return coverIds; } -} \ No newline at end of file +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityInput/NodeValueListInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityInput/NodeValueListInputAdapter.java index 703e1de0..acf9b673 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityInput/NodeValueListInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityInput/NodeValueListInputAdapter.java @@ -1,13 +1,14 @@ package i5.las2peer.services.ocd.adapters.centralityInput; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.adapters.Adapters; import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class NodeValueListInputAdapter extends AbstractCentralityInputAdapter { @@ -19,10 +20,9 @@ public CentralityMap readCentrality(CustomGraph graph) throws AdapterException { // Get all node names from the graph List nodeNames = new ArrayList(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - nodeNames.add(graph.getNodeName(nc.node())); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + nodeNames.add(graph.getNodeName(nc.next())); } try { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/DefaultXmlCentralityOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/DefaultXmlCentralityOutputAdapter.java index d9b98343..1ca94e1b 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/DefaultXmlCentralityOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/DefaultXmlCentralityOutputAdapter.java @@ -1,5 +1,6 @@ package i5.las2peer.services.ocd.adapters.centralityOutput; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -18,8 +19,7 @@ import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.utils.ExecutionStatus; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class DefaultXmlCentralityOutputAdapter extends AbstractCentralityOutputAdapter { @@ -37,10 +37,10 @@ public void writeCentralityMap(CentralityMap map) throws AdapterException { */ Element centralityValuesElt = doc.createElement("CentralityValues"); if(map.getCreationMethod().getStatus() == ExecutionStatus.COMPLETED) { - NodeCursor nodes = map.getGraph().nodes(); + Iterator nodes = map.getGraph().iterator(); Node node; - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); Element nodeElt = doc.createElement("Node"); Element nodeIdElt = doc.createElement("Name"); nodeIdElt.appendChild(doc.createTextNode(map.getGraph().getNodeName(node)) ); @@ -49,7 +49,6 @@ public void writeCentralityMap(CentralityMap map) throws AdapterException { nodeValueElt.appendChild(doc.createTextNode( ((Double)map.getNodeValue(node)).toString()) ); nodeElt.appendChild(nodeValueElt); centralityValuesElt.appendChild(nodeElt); - nodes.next(); } } mapElt.appendChild(centralityValuesElt); @@ -105,7 +104,7 @@ private void writeMetaInfo(CentralityMap map, Document doc, Element mapElt) { mapIdElt.appendChild(doc.createTextNode(Long.toString(map.getId()))); idElt.appendChild(mapIdElt); Element graphIdElt = doc.createElement("GraphId"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(map.getGraph().getId()))); + graphIdElt.appendChild(doc.createTextNode(map.getGraph().getKey())); idElt.appendChild(graphIdElt); mapElt.appendChild(idElt); Element graphElt = doc.createElement("Graph"); @@ -113,7 +112,7 @@ private void writeMetaInfo(CentralityMap map, Document doc, Element mapElt) { graphNameElt.appendChild(doc.createTextNode(map.getGraph().getName())); graphElt.appendChild(graphNameElt); Element graphSizeElt = doc.createElement("GraphSize"); - graphSizeElt.appendChild(doc.createTextNode(Integer.toString(map.getGraph().nodeCount()))); + graphSizeElt.appendChild(doc.createTextNode(Integer.toString(map.getGraph().getNodeCount()))); graphElt.appendChild(graphSizeElt); mapElt.appendChild(graphElt); /* diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/MetaXmlCentralityOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/MetaXmlCentralityOutputAdapter.java index e66ca00d..3651279a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/MetaXmlCentralityOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/centralityOutput/MetaXmlCentralityOutputAdapter.java @@ -35,10 +35,10 @@ public void writeCentralityMap(CentralityMap map) throws AdapterException { mapElt.appendChild(nameElt); Element idElt = doc.createElement("Id"); Element mapIdElt = doc.createElement("CentralityMapId"); - mapIdElt.appendChild(doc.createTextNode(Long.toString(map.getId()))); + mapIdElt.appendChild(doc.createTextNode(map.getKey())); //done idElt.appendChild(mapIdElt); Element graphIdElt = doc.createElement("GraphId"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(map.getGraph().getId()))); + graphIdElt.appendChild(doc.createTextNode(map.getGraph().getKey())); //done idElt.appendChild(graphIdElt); mapElt.appendChild(idElt); Element graphElt = doc.createElement("Graph"); @@ -46,7 +46,7 @@ public void writeCentralityMap(CentralityMap map) throws AdapterException { graphNameElt.appendChild(doc.createTextNode(map.getGraph().getName())); graphElt.appendChild(graphNameElt); Element graphSizeElt = doc.createElement("GraphSize"); - graphSizeElt.appendChild(doc.createTextNode(Integer.toString(map.getGraph().nodeCount()))); + graphSizeElt.appendChild(doc.createTextNode(Integer.toString(map.getGraph().getNodeCount()))); graphElt.appendChild(graphSizeElt); mapElt.appendChild(graphElt); /* diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsCoverInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsCoverInputAdapter.java index 0f6dce5c..d8085f1a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsCoverInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsCoverInputAdapter.java @@ -6,16 +6,12 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import java.io.Reader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * A cover input adapter for the community member list format. @@ -98,19 +94,18 @@ public Cover readCover(CustomGraph graph) throws AdapterException { e.printStackTrace(); } } - Matrix memberships = new CCSMatrix(graph.nodeCount(), communityCount); - NodeCursor nodes = graph.nodes(); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), communityCount); + Iterator nodes = graph.iterator(); Node node; - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); nodeName = graph.getNodeName(node); communityIndices = nodeCommunities.get(nodeName); if(communityIndices != null) { for(int communityIndex : communityIndices) { - memberships.set(node.index(), communityIndex, 1d/communityIndices.size()); + memberships.set(node.getIndex(), communityIndex, 1d/communityIndices.size()); } } - nodes.next(); } Cover cover = new Cover(graph, memberships); if(communityNamesDefined) { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapter.java index d64f6698..173c4f84 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapter.java @@ -7,14 +7,14 @@ import java.io.Reader; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * A cover input adapter for the labeled membership matrix format. @@ -42,21 +42,20 @@ public LabeledMembershipMatrixCoverInputAdapter() { @Override public Cover readCover(CustomGraph graph) throws AdapterException { - NodeCursor nodes = graph.nodes(); + Iterator nodes = graph.iterator(); Node node; Map reverseNodeNames = new HashMap(); - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); reverseNodeNames.put(graph.getNodeName(node), node); - nodes.next(); } try { List line = Adapters.readLine(reader); - Matrix memberships = new CCSMatrix(graph.nodeCount(), line.size() - 1); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), line.size() - 1); int nodeIndex; double belongingFactor; while(line.size() > 0) { - nodeIndex = reverseNodeNames.get(line.get(0)).index(); + nodeIndex = reverseNodeNames.get(line.get(0)).getIndex(); for(int i=1; i nodes = graph.iterator(); Node node; - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); nodeName = graph.getNodeName(node); communityIndices = nodeCommunities.get(nodeName); for(int communityIndex : communityIndices) { - memberships.set(node.index(), communityIndex, 1d/communityIndices.size()); + memberships.set(node.getIndex(), communityIndex, 1d/communityIndices.size()); } - nodes.next(); } return new Cover(graph, memberships); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/DefaultXmlCoverOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/DefaultXmlCoverOutputAdapter.java index daaa6683..2b9e10e8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/DefaultXmlCoverOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/DefaultXmlCoverOutputAdapter.java @@ -5,6 +5,7 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import java.util.Iterator; import java.util.Map; import javax.xml.parsers.DocumentBuilder; @@ -18,8 +19,7 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * A cover output adapter for the default XML format. @@ -92,7 +92,7 @@ public void writeCover(Cover cover) throws AdapterException { OcdMetricLog metric = cover.getMetrics().get(i); Element metricElt = doc.createElement("Metric"); Element metricIdElt = doc.createElement("Id"); - metricIdElt.appendChild(doc.createTextNode(Long.toString(metric.getId()))); + metricIdElt.appendChild(doc.createTextNode(metric.getKey())); //done metricElt.appendChild(metricIdElt); Element metricTypeElt = doc.createElement("Type"); metricTypeElt.appendChild(doc.createTextNode(metric.getType().name())); @@ -154,10 +154,10 @@ public void writeCover(Cover cover) throws AdapterException { * Community Memberships */ Element membershipsElt = doc.createElement("Memberships"); - NodeCursor nodes = cover.getGraph().nodes(); + Iterator nodes = cover.getGraph().iterator(); Node node; - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); Element membershipElt = doc.createElement("Membership"); Element memberIdElt = doc.createElement("Name"); memberIdElt.appendChild(doc.createTextNode(graph.getNodeName(node))); @@ -166,7 +166,6 @@ public void writeCover(Cover cover) throws AdapterException { belongingFactorElt.appendChild(doc.createTextNode(String.format("%.5f\n", cover.getBelongingFactor(node, i)))); membershipElt.appendChild(belongingFactorElt); membershipsElt.appendChild(membershipElt); - nodes.next(); } communityElt.appendChild(membershipsElt); communitiesElt.appendChild(communityElt); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/LabeledMembershipMatrixCoverOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/LabeledMembershipMatrixCoverOutputAdapter.java index f9f3bdd8..4886bfb1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/LabeledMembershipMatrixCoverOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/coverOutput/LabeledMembershipMatrixCoverOutputAdapter.java @@ -5,9 +5,9 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import java.io.Writer; +import java.util.Iterator; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * A cover output adapter for the labeled membership matrix format. @@ -33,19 +33,18 @@ public LabeledMembershipMatrixCoverOutputAdapter() { public void writeCover(Cover cover) throws AdapterException { try { CustomGraph graph = cover.getGraph(); - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); + Iterator nodes = graph.iterator(); + while(nodes.hasNext()) { + Node node = nodes.next(); String nodeName = graph.getNodeName(node); if(nodeName.isEmpty()) { - nodeName = Integer.toString(node.index()); + nodeName = Integer.toString(node.getIndex()); } writer.write(nodeName + " "); for(int i=0; i nodes = new ArrayList<>(); for (int i = 0; i < nodeCount; i++) { - nodes.add(i, graph.createNode()); + nodes.add(i, graph.addNode(String.valueOf(i))); graph.setNodeName(nodes.get(i), String.valueOf(i+1)); } @@ -49,7 +50,7 @@ public CustomGraph readGraph() throws AdapterException { Node targetNode = nodes.get(column); double edgeWeight = Double.parseDouble(line.get(column)); if (edgeWeight > 0) { - Edge edge = graph.createEdge(sourceNode, targetNode); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), sourceNode, targetNode); graph.setEdgeWeight(edge, edgeWeight); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapter.java index c052dfa6..21ff0797 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapter.java @@ -1,5 +1,7 @@ package i5.las2peer.services.ocd.adapters.graphInput; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.graphs.CustomGraph; @@ -8,121 +10,114 @@ import java.io.InputStream; import java.text.ParseException; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Scanner; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; -import y.io.GMLIOHandler; +import org.apache.lucene.util.ThreadInterruptedException; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; +import org.graphstream.stream.file.FileSourceGML; +import org.graphstream.stream.file.gml.GMLParser; /** * A graph input adapter for GML format, based on the GMLIOHandler of the yFiles library. * In case each node has a label with a unique value node names will be derived from there. Otherwise node names will be set as indices. * In case each edge has a label with a numeric value edge weights will be derived from there. - * @author Sebastian * + * @author Sebastian */ +//TODO: Test for graphstream public class GmlGraphInputAdapter extends AbstractGraphInputAdapter { - - @Override - public void setParameter(Map param) throws IllegalArgumentException, ParseException{ - - } - - @Override - public CustomGraph readGraph() throws AdapterException { - GMLIOHandler ioh = new GMLIOHandler(); - Scanner scanner = new Scanner(reader); - String inString = scanner.useDelimiter("\\A").next(); - scanner.close(); - InputStream is = new ByteArrayInputStream(inString.getBytes()); - CustomGraph graph = new CustomGraph(); - try { - ioh.read(graph, is); - } catch (IOException e) { - throw new AdapterException(e); - } finally { - try { - is.close(); - } catch (IOException e) { - } - } - /* - * Check whether node labels are unique names. - */ - NodeCursor nodes = graph.nodes(); - Node node; - HashMap nodenames = new HashMap(); - try { - while(nodes.ok()) { - node = nodes.node(); - String name = graph.getRealizer(node).getLabel().getText(); - if(name.isEmpty()) { - break; - } - nodenames.put(node, name); - nodes.next(); - } - } catch (RuntimeException e) { - // label not set - } - nodes.toFirst(); - /* - * Node labels are unique. - */ - if(nodenames.size() == graph.nodeCount()) { - while(nodes.ok()) { - node = nodes.node(); - graph.setNodeName(node, nodenames.get(node)); - nodes.next(); - } - } - /* - * Node labels are not unique. - */ - else { - while(nodes.ok()) { - node = nodes.node(); - graph.setNodeName(node, Integer.toString(node.index())); - nodes.next(); - } - } - /* - * Check whether node labels are numeric. - */ - EdgeCursor edges = graph.edges(); - Edge edge; - HashMap edgeweights = new HashMap(); - try { - while(edges.ok()) { - edge = edges.edge(); - String weightStr = graph.getRealizer(edge).getLabel().getText(); - Double weight = Double.parseDouble(weightStr); - if(weight != null) { - edgeweights.put(edge, weight); - } - else { - break; - } - edges.next(); - } - } catch (RuntimeException e) { - // label not set - } - edges.toFirst(); - /* - * all labels correspond numeric - */ - if(edgeweights.size() == graph.edgeCount()) { - while(edges.ok()) { - edge = edges.edge(); - graph.setEdgeWeight(edge, edgeweights.get(edge)); - edges.next(); - } - } - return graph; - } + + @Override + public void setParameter(Map param) throws IllegalArgumentException, ParseException { + + } + + @Override + public CustomGraph readGraph() throws AdapterException { + CustomGraph graph = new CustomGraph(); + FileSourceGML fileSource = new FileSourceGML(); + fileSource.addSink(graph); + + try { + InputStream inStream = new ByteArrayInputStream(CharStreams.toString(reader) + .getBytes(Charsets.UTF_8)); + + reader.close(); + + fileSource.begin(inStream); + while (fileSource.nextEvents()) { //TODO: Check if that is necessary here or if we shouldnt just do readAll + if (Thread.interrupted()) { + throw new InterruptedException(); + } + } + inStream.close(); + } catch (Exception e) { + throw new AdapterException("ERROR Could not read file: " + e.getMessage()); + } + + /* + * Check whether node labels are unique names. + */ + Iterator nodesIt = graph.iterator(); + Node node; + HashMap nodenames = new HashMap(); + while (nodesIt.hasNext()) { + node = nodesIt.next(); + CharSequence name = node.getLabel("ui.label"); + if (name == null) { + break; + } + nodenames.put(node, name.toString()); + } + nodesIt = graph.iterator(); + /* + * Node labels are unique. + */ + if (nodenames.size() == graph.getNodeCount()) { + while (nodesIt.hasNext()) { + node = nodesIt.next(); + graph.setNodeName(node, nodenames.get(node)); + } + } + /* + * Node labels are not unique. + */ + else { + while (nodesIt.hasNext()) { + node = nodesIt.next(); + graph.setNodeName(node, node.getId()); //TODO: Changed from Index to Id here, check if that makes sense with how graphstream reads it + } + } + /* + * Check whether edge labels/weights are numeric. + */ + Iterator edges = graph.edges().iterator(); + Edge edge; + HashMap edgeweights = new HashMap(); + while (edges.hasNext()) { + edge = edges.next(); + Double weight = edge.getNumber("weight"); + if (!weight.isNaN()) { + edgeweights.put(edge, weight); + } else { + break; + } + } + edges = graph.edges().iterator(); + /* + * all labels correspond numeric + */ + if (edgeweights.size() == graph.getEdgeCount()) { + while (edges.hasNext()) { + edge = edges.next(); + graph.setEdgeWeight(edge, edgeweights.get(edge)); + } + } + + return graph; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapter.java index 228da156..52594b4c 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapter.java @@ -1,27 +1,18 @@ package i5.las2peer.services.ocd.adapters.graphInput; +import com.google.common.base.Charsets; +import com.google.common.io.CharStreams; import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.graphs.CustomGraph; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; import java.text.ParseException; -import java.util.HashSet; -import java.util.Map; -import java.util.Scanner; -import java.util.Set; +import java.util.*; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.EdgeMap; -import y.base.Node; -import y.base.NodeCursor; -import y.base.NodeMap; -import y.io.GraphMLIOHandler; -import y.io.graphml.GraphMLHandler; -import y.io.graphml.KeyScope; -import y.io.graphml.KeyType; +import org.graphstream.stream.file.FileSourceGraphML; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * A graph input adapter for GraphML format, based on the GraphMLIOHandler of the yFiles library.. @@ -30,6 +21,7 @@ * @author Sebastian * */ +//TODO: Test for graphstream public class GraphMlGraphInputAdapter extends AbstractGraphInputAdapter { @Override @@ -39,78 +31,71 @@ public void setParameter(Map param) throws IllegalArgumentExcepti @Override public CustomGraph readGraph() throws AdapterException { - Scanner scanner = new Scanner(reader); - String inString = scanner.useDelimiter("\\A").next(); - scanner.close(); - InputStream is = new ByteArrayInputStream(inString.getBytes()); - GraphMLIOHandler ioh = new GraphMLIOHandler(); CustomGraph graph = new CustomGraph(); - NodeMap nodeNames = graph.createNodeMap(); - EdgeMap edgeWeights = graph.createEdgeMap(); - GraphMLHandler core = ioh.getGraphMLHandler(); - core.addInputDataAcceptor("name", nodeNames, KeyScope.NODE, KeyType.STRING); - core.addInputDataAcceptor("weight", edgeWeights, KeyScope.EDGE, KeyType.DOUBLE); + FileSourceGraphML fileSource = new FileSourceGraphML(); + fileSource.addSink(graph); + try { - ioh.read(graph, is); + InputStream inStream = new ByteArrayInputStream(CharStreams.toString(reader) + .getBytes(Charsets.UTF_8)); + + reader.close(); + + fileSource.begin(inStream); + while (fileSource.nextEvents()) { //TODO: Check if that is necessary here or if we shouldnt just do readAll + if (Thread.interrupted()) { + throw new InterruptedException(); + } + } + inStream.close(); + } catch (Exception e) { + throw new AdapterException("ERROR Could not read file: " + e.getMessage()); + } /* * Checks whether node names are unique. */ - NodeCursor nodes = graph.nodes(); - Node node; - String name; - Set names = new HashSet(); - while(nodes.ok()) { - name = (String)nodeNames.get(nodes.node()); - if(name == null || name.isEmpty()) { + Iterator nodes = graph.iterator(); + CharSequence name; + HashMap names = new HashMap(); + while(nodes.hasNext()) { + Node node = nodes.next(); + name = node.getLabel("ui.label"); + if(name == null || name.toString().isEmpty()) { break; } - names.add(name); - nodes.next(); + names.put(node.getIndex(), name.toString()); } - nodes.toFirst(); + nodes = graph.iterator(); /* * Sets unique node names. */ - if(names.size() == graph.nodeCount()) { - while(nodes.ok()) { - node = nodes.node(); - graph.setNodeName(node, (String)nodeNames.get(node)); - nodes.next(); + if(names.size() == graph.getNodeCount()) { + while(nodes.hasNext()) { + Node node = nodes.next(); + graph.setNodeName(node, names.get(node.getIndex())); } } /* * If names not unique sets indices instead. */ else { - while(nodes.ok()) { - node = nodes.node(); - graph.setNodeName(node, Integer.toString(node.index())); - nodes.next(); + while(nodes.hasNext()) { + Node node = nodes.next(); + graph.setNodeName(node, node.getId()); //TODO: Changed from Index to Id here, check if that makes sense with how graphstream reads it } } - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; - while(edges.ok()) { - edge = edges.edge(); - Double weight = (Double)edgeWeights.get(edge); - if(weight != null) { + while(edges.hasNext()) { + edge = edges.next(); + Double weight = edge.getNumber("weight"); + if(!weight.isNaN()) { graph.setEdgeWeight(edge, weight); } else { break; } - edges.next(); } - } catch (Exception e) { - throw new AdapterException(e); - } finally { - graph.disposeNodeMap(nodeNames); - graph.disposeEdgeMap(edgeWeights); - try { - is.close(); - } catch (IOException e) { - } - } return graph; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapter.java index d16b232b..a24a9769 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapter.java @@ -6,11 +6,11 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Node; import org.apache.jena.query.Query; import org.apache.jena.query.QueryExecution; @@ -95,9 +95,10 @@ public CustomGraph readGraph() throws AdapterException { try { if(!involvedUsers.isEmpty()) { //System.out.println("Users: " + involvedUsers + " " + involvedUsers.size() + " <" + involvedUserURIs + ">"); + int i = 0; for(String userUri : involvedUsers) { if(users.containsKey(userUri)) { - Node userNode = graph.createNode(); + Node userNode = graph.addNode(Integer.toString(i++)); if(showUserNames) { graph.setNodeName(userNode, users.get(userUri)); } @@ -111,8 +112,9 @@ public CustomGraph readGraph() throws AdapterException { } else { //create nodes for all users + int i = 0; for(Map.Entry user : users.entrySet()) { - Node userNode = graph.createNode(); + Node userNode = graph.addNode(Integer.toString(i++)); if(showUserNames) { graph.setNodeName(userNode, user.getValue()); } @@ -137,7 +139,7 @@ public CustomGraph readGraph() throws AdapterException { for(String interactingUser : interactingUsers) { //System.out.println("USERS: " + user.getKey() + " " + interactingUser); if(nodeIds.containsKey(interactingUser)) { - graph.createEdge(nodeIds.get(interactingUser), user.getValue()); + graph.addEdge(UUID.randomUUID().toString(), nodeIds.get(interactingUser), user.getValue()); } } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapter.java index 63517051..26dba839 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapter.java @@ -4,12 +4,7 @@ import java.io.Reader; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; import i5.las2peer.services.ocd.adapters.AdapterException; @@ -17,8 +12,8 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.preprocessing.TextProcessor; import i5.las2peer.services.ocd.utils.DocIndexer; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * A graph input adapter for a node list which includes a content attribute for each node and edges in form of a @@ -179,7 +174,7 @@ private CustomGraph readSenderReceiverGraph(int senderIndex, int receiverIndex, String customNodeReceiver = line.get(receiverIndex); // node does not yet exist if(!nodeNames.containsKey(customNodeName)){ - node = graph.createNode(); //create new node and add attributes + node = graph.addNode(UUID.randomUUID().toString()); //create new node and add attributes graph.setNodeName(node , customNodeName); nodeContents.put(customNodeName, customNodeContent); //graph.setNodeContent(node, customNodeContent); @@ -222,7 +217,7 @@ private CustomGraph readSenderReceiverGraph(int senderIndex, int receiverIndex, HashMap list = entry.getValue(); for(Entry e : list.entrySet()){ if(nodeNames.containsKey(e.getKey())){ - Edge edge = graph.createEdge(curr, nodeNames.get(e.getKey())); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), curr, nodeNames.get(e.getKey())); graph.setEdgeWeight(edge, e.getValue()); } } @@ -266,7 +261,7 @@ private CustomGraph readThreadGraph(int nameIndex, int contentIndex, int dateInd String customNodeContent = textProc.preprocText(line.get(contentIndex)); String customNodeThread = line.get(threadIndex); if(!nodeNames.containsKey(customNodeName)){ - node = graph.createNode(); + node = graph.addNode(UUID.randomUUID().toString()); graph.setNodeName(node , customNodeName); nodeContents.put(customNodeName, customNodeContent); //graph.setNodeContent(node, customNodeContent); @@ -302,7 +297,7 @@ private CustomGraph readThreadGraph(int nameIndex, int contentIndex, int dateInd for(String str:list){ for(Entry> reciever : nodeThreads.entrySet()){ if(curr != reciever.getKey() && reciever.getValue().contains(str)){ - graph.createEdge(curr, reciever.getKey()); + graph.addEdge(UUID.randomUUID().toString(), curr, reciever.getKey()); //graph.setEdgeWeight(edge, reciever.getValue()); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeIdDeserializationHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeIdDeserializationHandler.java deleted file mode 100644 index 9cb79bd1..00000000 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeIdDeserializationHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package i5.las2peer.services.ocd.adapters.graphInput; - -import java.util.HashMap; - -import org.w3c.dom.Element; - -import y.io.graphml.input.DeserializationEvent; -import y.io.graphml.input.DeserializationHandler; -import y.io.graphml.input.GraphMLParseException; - -public class NodeIdDeserializationHandler implements DeserializationHandler { - - private HashMap nodeIds = new HashMap(); - int i=0; - - @Override - public void onHandleDeserialization(DeserializationEvent event) - throws GraphMLParseException { - // get the element to parse - org.w3c.dom.Node xmlNode = event.getXmlNode(); - - // if the element can be parsed - // create a new instance - if (xmlNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE - && "node".equals(xmlNode.getLocalName())) { - // create a new instance with the value of the "value" attribute - String id = new String(((Element) xmlNode).getAttribute("id")); - // pass the new instance as result - // Note: setting the result already marks the event as handled - nodeIds.put(i, id); - i++; - } - - } - -} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapter.java index 8a52ddae..b2bd4a28 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapter.java @@ -9,9 +9,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * A graph input adapter for node weighted edge list format. @@ -53,8 +54,9 @@ public CustomGraph readGraph() throws AdapterException { * Reads nodes */ while(line.size() == 1) { - Node node = graph.createNode(); String nodeName = line.get(0); + Node node = graph.addNode(nodeName); + if(!reverseNodeNames.containsKey(nodeName)) { graph.setNodeName(node, nodeName); reverseNodeNames.put(nodeName, node); @@ -79,7 +81,7 @@ public CustomGraph readGraph() throws AdapterException { if(targetNode == null) { throw new AdapterException("Node not specified: " + targetNodeName); } - Edge edge = graph.createEdge(sourceNode, targetNode); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), sourceNode, targetNode); graph.setEdgeWeight(edge, edgeWeight); line = Adapters.readLine(reader); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapter.java index 1fd88586..12993ae2 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapter.java @@ -9,9 +9,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * A graph input adapter for unweighted edge list format. @@ -55,7 +56,7 @@ public CustomGraph readGraph() throws AdapterException { String sourceNodeName = line.get(0); Node sourceNode; if (!reverseNodeNames.containsKey(sourceNodeName)) { - sourceNode = graph.createNode(); + sourceNode = graph.addNode(sourceNodeName); reverseNodeNames.put(sourceNodeName, sourceNode); graph.setNodeName(sourceNode, sourceNodeName); } else { @@ -64,13 +65,13 @@ public CustomGraph readGraph() throws AdapterException { String targetNodeName = line.get(1); Node targetNode; if (!reverseNodeNames.containsKey(targetNodeName)) { - targetNode = graph.createNode(); + targetNode = graph.addNode(targetNodeName); reverseNodeNames.put(targetNodeName, targetNode); graph.setNodeName(targetNode, targetNodeName); } else { targetNode = reverseNodeNames.get(targetNodeName); } - Edge edge = graph.createEdge(sourceNode, targetNode); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), sourceNode, targetNode); graph.setEdgeWeight(edge, 1); line = Adapters.readLine(reader); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapter.java index fb949709..911624e0 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapter.java @@ -9,9 +9,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * A graph input adapter for weighted edge list format. @@ -54,7 +55,7 @@ public CustomGraph readGraph() throws AdapterException { String sourceNodeName = line.get(0); Node sourceNode; if (!reverseNodeNames.containsKey(sourceNodeName)) { - sourceNode = graph.createNode(); + sourceNode = graph.addNode(sourceNodeName); reverseNodeNames.put(sourceNodeName, sourceNode); graph.setNodeName(sourceNode, sourceNodeName); } @@ -64,7 +65,7 @@ public CustomGraph readGraph() throws AdapterException { String targetNodeName = line.get(1); Node targetNode; if (!reverseNodeNames.containsKey(targetNodeName)) { - targetNode = graph.createNode(); + targetNode = graph.addNode(targetNodeName); reverseNodeNames.put(targetNodeName, targetNode); graph.setNodeName(targetNode, targetNodeName); } @@ -73,7 +74,7 @@ public CustomGraph readGraph() throws AdapterException { } String edgeWeightString = line.get(2); double edgeWeight = Double.parseDouble(edgeWeightString); - Edge edge = graph.createEdge(sourceNode, targetNode); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), sourceNode, targetNode); graph.setEdgeWeight(edge, edgeWeight); line = Adapters.readLine(reader); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapter.java index 9aa33a2f..1d2990c2 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapter.java @@ -27,14 +27,13 @@ import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.graphs.CustomGraph; //import i5.las2peer.services.ocd.utils.DocIndexer; -import y.base.Edge; -import y.base.Node; -import y.view.EdgeLabel; -import y.view.EdgeRealizer; -import y.view.LineType; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + import java.io.Reader; import java.io.FileReader; +import java.util.UUID; //TODO: Currently only for the youtube graph, make more general //TODO: Be able to have more Attributes for nodes(at least string id's) and maybe edges(at least type) in general @@ -82,8 +81,6 @@ public void setParameter(Map param) throws IllegalArgumentExcept // Ignore for now as LineTypes are not stored in persistence for some reason public void setLineType(Element edgeElement, Edge edge, CustomGraph graph) { if (type1 != "" || type2 != "" || type3 != "") { - EdgeRealizer eRealizer = graph.getRealizer(edge); - NodeList atts = edgeElement.getChildNodes(); if (atts.getLength() != 0) { if (key.contentEquals("")) { @@ -93,14 +90,17 @@ public void setLineType(Element edgeElement, Edge edge, CustomGraph graph) { System.out.println(e.getAttribute(type2)); System.out.println(e.getAttribute("name")); if (type1 != "" && e.hasAttribute(type1)) { - eRealizer.setLineType(LineType.LINE_1); + edge.setAttribute("ui.fill-mode", "plain"); break; } else if (type2 != "" && e.hasAttribute(type2)) { - eRealizer.setLineType(LineType.DASHED_1); - System.out.println(eRealizer.getLineType().equals(LineType.DASHED_1)); + edge.setAttribute("ui.fill-mode", "none"); + edge.setAttribute("ui.size", "0px"); + edge.setAttribute("ui.stroke-mode", "dashes"); break; } else if (type3 != "" && e.hasAttribute(type3)) { - eRealizer.setLineType(LineType.DOTTED_1); + edge.setAttribute("ui.fill-mode", "none"); + edge.setAttribute("ui.size", "0px"); + edge.setAttribute("ui.stroke-mode", "dots"); break; } } @@ -111,13 +111,17 @@ public void setLineType(Element edgeElement, Edge edge, CustomGraph graph) { Element e = (Element) atts.item(u); if (type1 != "" && e.getAttribute(key).contentEquals(type1)) { - eRealizer.setLineType(LineType.LINE_1); + edge.setAttribute("ui.fill-mode", "plain"); break; } else if (type2 != "" && e.getAttribute(key).contentEquals(type2)) { - eRealizer.setLineType(LineType.DASHED_1); + edge.setAttribute("ui.fill-mode", "none"); + edge.setAttribute("ui.size", "0px"); + edge.setAttribute("ui.stroke-mode", "dashes"); break; } else if (type3 != "" && e.getAttribute(key).contentEquals(type3)) { - eRealizer.setLineType(LineType.DOTTED_1); + edge.setAttribute("ui.fill-mode", "none"); + edge.setAttribute("ui.size", "0px"); + edge.setAttribute("ui.stroke-mode", "dots"); break; } } @@ -187,7 +191,7 @@ public CustomGraph readGraph() throws AdapterException { } // node does not yet exist if (!nodeIds.containsKey(customNodeId)) { - node = graph.createNode(); // create new node and add attributes + node = graph.addNode(customNodeId); // create new node and add attributes graph.setNodeName(node, customNodeId); nodeIds.put(customNodeId, node); // nodeContents.put(customNodeName, customNodeContent); @@ -206,11 +210,11 @@ public CustomGraph readGraph() throws AdapterException { if (nodeIds.containsKey(e.getAttribute("source")) && nodeIds.containsKey(e.getAttribute("target"))) { if (!edgeMap.containsKey(e.getAttribute("label"))) { - Edge edge = graph.createEdge(nodeIds.get(e.getAttribute("source")), nodeIds.get(e.getAttribute("target"))); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), nodeIds.get(e.getAttribute("source")), nodeIds.get(e.getAttribute("target"))); //setLineType(e, edge, graph); if (undirected) { - Edge reverseEdge = graph.createEdge(nodeIds.get(e.getAttribute("target")), nodeIds.get(e.getAttribute("source"))); + Edge reverseEdge = graph.addEdge(UUID.randomUUID().toString(), nodeIds.get(e.getAttribute("target")), nodeIds.get(e.getAttribute("source"))); //graph.getRealizer(reverseEdge).setLineType(graph.getRealizer(edge).getLineType()); } edgeMap.put(e.getAttribute("source") + e.getAttribute("target"), edge); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapter.java index 6fb76fe4..065a0d72 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.UUID; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -27,8 +28,8 @@ import i5.las2peer.services.ocd.preprocessing.TextProcessor; import i5.las2peer.services.ocd.utils.DocIndexer; //import i5.las2peer.services.ocd.utils.DocIndexer; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class XMLGraphInputAdapter extends AbstractGraphInputAdapter{ @@ -119,7 +120,7 @@ public CustomGraph readGraph() throws AdapterException{ String customNodeParent = e.getAttribute("ParentId"); // node does not yet exist if(!nodeNames.containsKey(customNodeName)){ - node = graph.createNode(); //create new node and add attributes + node = graph.addNode(customNodeName); //create new node and add attributes graph.setNodeName(node , customNodeName); nodeIds.put(customNodeId, node); nodeContents.put(customNodeName, customNodeContent); @@ -171,7 +172,7 @@ public CustomGraph readGraph() throws AdapterException{ HashMap list = entry.getValue(); for(Entry e : list.entrySet()){ if(nodeIds.containsKey(e.getKey())){ - Edge edge = graph.createEdge(curr, nodeIds.get(e.getKey())); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), curr, nodeIds.get(e.getKey())); graph.setEdgeWeight(edge, e.getValue()); } } @@ -185,10 +186,8 @@ public CustomGraph readGraph() throws AdapterException{ } catch (IOException e) { e.printStackTrace(); } catch (DOMException e) { - // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseException e) { - // TODO Auto-generated catch block e.printStackTrace(); } return graph; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapter.java index 49d2160c..15a26673 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapter.java @@ -5,52 +5,39 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Iterator; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.EdgeMap; -import y.base.Node; -import y.base.NodeCursor; -import y.base.NodeMap; -import y.io.GraphMLIOHandler; -import y.io.graphml.GraphMLHandler; -import y.io.graphml.KeyScope; -import y.io.graphml.KeyType; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; +import org.graphstream.stream.file.FileSinkGraphML; /** - * A graph output adapter for GraphML format, based on the GraphMLIOHandler of the yFiles library.. - * Node names will be written into a CDATA Section in a "name" element. - * Edge weights will be written into a "weight" element. + * A graph output adapter for GraphML format, based on the GraphMLIOHandler of the graphstream library. + * Node names will be written into a CDATA Section in a "name" element. //TODO + * Edge weights will be written into a "weight" element. //TODO * @author Sebastian * */ +//TODO: Check how output of customgraph attributes looks public class GraphMlGraphOutputAdapter extends AbstractGraphOutputAdapter { @Override public void writeGraph(CustomGraph graph) throws AdapterException { + FileSinkGraphML fileSink = new FileSinkGraphML(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - NodeMap nodeNames = graph.createNodeMap(); - NodeCursor nodes = graph.nodes(); - Node node; - while(nodes.ok()) { - node = nodes.node(); - nodeNames.set(node, graph.getNodeName(node)); - nodes.next(); + + //write node names and edge weights into attributes + for (Node node : graph) { + node.setAttribute("name", graph.getNodeName(node)); } - EdgeMap edgeWeights = graph.createEdgeMap(); - EdgeCursor edges = graph.edges(); - Edge edge; - while(edges.ok()) { - edge = edges.edge(); - edgeWeights.set(edge, graph.getEdgeWeight(edge)); - edges.next(); + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("weight", graph.getEdgeWeight(edge)); } - GraphMLIOHandler ioh = new GraphMLIOHandler(); - GraphMLHandler core = ioh.getGraphMLHandler(); - core.addOutputDataProvider("name", nodeNames, KeyScope.NODE, KeyType.STRING); - core.addOutputDataProvider("weight", edgeWeights, KeyScope.EDGE, KeyType.DOUBLE); + try { - ioh.write(graph, outStream); + fileSink.writeAll(graph, outStream); String outString = outStream.toString(); writer.write(outString); } @@ -67,8 +54,6 @@ public void writeGraph(CustomGraph graph) throws AdapterException { } catch(IOException e) { } - graph.disposeNodeMap(nodeNames); - graph.disposeEdgeMap(edgeWeights); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/MetaXmlGraphOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/MetaXmlGraphOutputAdapter.java index 521e3401..9fea9633 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/MetaXmlGraphOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/MetaXmlGraphOutputAdapter.java @@ -35,7 +35,7 @@ public void writeGraph(CustomGraph graph) throws AdapterException { * Basic Attributes */ Element graphIdElt = doc.createElement("Id"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(graph.getId()))); + graphIdElt.appendChild(doc.createTextNode(graph.getKey())); graphElt.appendChild(graphIdElt); Element graphNameElt = doc.createElement("Name"); graphNameElt.appendChild(doc.createTextNode(graph.getName())); @@ -44,10 +44,10 @@ public void writeGraph(CustomGraph graph) throws AdapterException { // graphDescrElt.appendChild(doc.createTextNode(graph.getDescription())); // graphElt.appendChild(graphDescrElt); Element graphNodeCountElt = doc.createElement("NodeCount"); - graphNodeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.nodeCount()))); + graphNodeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.getNodeCount()))); graphElt.appendChild(graphNodeCountElt); Element graphEdgeCountElt = doc.createElement("EdgeCount"); - graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.edgeCount()))); + graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.getEdgeCount()))); graphElt.appendChild(graphEdgeCountElt); // Element lastUpdateElt = doc.createElement("LastUpdate"); // if(graph.getLastUpdate() != null) { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/PropertiesXmlGraphOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/PropertiesXmlGraphOutputAdapter.java index f9218071..7e73eedb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/PropertiesXmlGraphOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/PropertiesXmlGraphOutputAdapter.java @@ -28,7 +28,7 @@ public void writeGraph(CustomGraph graph) throws AdapterException { doc.appendChild(graphElt); Element graphIdElt = doc.createElement("Id"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(graph.getId()))); + graphIdElt.appendChild(doc.createTextNode(graph.getKey())); //done graphElt.appendChild(graphIdElt); Element graphNameElt = doc.createElement("Name"); @@ -36,14 +36,14 @@ public void writeGraph(CustomGraph graph) throws AdapterException { graphElt.appendChild(graphNameElt); Element graphNodeCountElt = doc.createElement("Size"); - graphNodeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.nodeCount()))); + graphNodeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.getNodeCount()))); graphElt.appendChild(graphNodeCountElt); Element graphEdgeCountElt = doc.createElement("Links"); if (graph.isDirected()) { - graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.edgeCount()))); + graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.getEdgeCount()))); } else { - graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.edgeCount() / 2))); + graphEdgeCountElt.appendChild(doc.createTextNode(Integer.toString(graph.getEdgeCount() / 2))); } graphElt.appendChild(graphEdgeCountElt); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/WeightedEdgeListGraphOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/WeightedEdgeListGraphOutputAdapter.java index 3638a548..b41099f3 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/WeightedEdgeListGraphOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/graphOutput/WeightedEdgeListGraphOutputAdapter.java @@ -4,9 +4,9 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import java.io.Writer; +import java.util.Iterator; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Edge; /** * A graph output adapter for weighted edge list format. @@ -44,17 +44,16 @@ public void setWeighted(boolean weighted) { @Override public void writeGraph(CustomGraph graph) throws AdapterException { try { - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; - while(edges.ok()) { - edge = edges.edge(); - writer.write(graph.getNodeName(edge.source()) + " "); - writer.write(graph.getNodeName(edge.target())); + while(edges.hasNext()) { + edge = edges.next(); + writer.write(graph.getNodeName(edge.getSourceNode()) + " "); + writer.write(graph.getNodeName(edge.getTargetNode())); if(weighted) { writer.write(" " + String.format("%.2f", graph.getEdgeWeight(edge))); } - edges.next(); - if(edges.ok()) { + if(edges.hasNext()) { writer.write("\n"); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCentralityMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCentralityMetaOutputAdapter.java new file mode 100644 index 00000000..06220ac0 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCentralityMetaOutputAdapter.java @@ -0,0 +1,10 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AbstractOutputAdapter; + +/** + * An abstract class for centrality meta information output adapters. + * + */ +public abstract class AbstractCentralityMetaOutputAdapter extends AbstractOutputAdapter implements CentralityMetaOutputAdapter { +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCoverMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCoverMetaOutputAdapter.java new file mode 100644 index 00000000..d994f03b --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractCoverMetaOutputAdapter.java @@ -0,0 +1,11 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AbstractOutputAdapter; + +/** + * An abstract class for cover meta information output adapters. + * + */ +public abstract class AbstractCoverMetaOutputAdapter extends AbstractOutputAdapter implements CoverMetaOutputAdapter { + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractGraphMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractGraphMetaOutputAdapter.java new file mode 100644 index 00000000..a67b575a --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/AbstractGraphMetaOutputAdapter.java @@ -0,0 +1,11 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AbstractOutputAdapter; + + +/** + * An abstract class for graph meta information output adapters. + * + */ +public abstract class AbstractGraphMetaOutputAdapter extends AbstractOutputAdapter implements GraphMetaOutputAdapter { +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CentralityMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CentralityMetaOutputAdapter.java new file mode 100644 index 00000000..10b42ecc --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CentralityMetaOutputAdapter.java @@ -0,0 +1,19 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.adapters.OutputAdapter; +import i5.las2peer.services.ocd.centrality.data.CentralityMeta; + +/** + * The common interface of centrality output adapters. + * + */ +public interface CentralityMetaOutputAdapter extends OutputAdapter { + + /** + * Writes a CentralityMap and closes the writer. + * @param centralityMeta The CentralityMeta instance holding meta information about centrality. + * @throws AdapterException if the adapter failed + */ + public void writeCentralityMap(CentralityMeta centralityMeta) throws AdapterException; +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CoverMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CoverMetaOutputAdapter.java new file mode 100644 index 00000000..2b6af808 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/CoverMetaOutputAdapter.java @@ -0,0 +1,18 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.adapters.OutputAdapter; +import i5.las2peer.services.ocd.graphs.CoverMeta; + +/** + * The common interface of graph output adapters. + * + */ +public interface CoverMetaOutputAdapter extends OutputAdapter { + /** + * Writes a cover and closes the writer. + * @param coverMeta TThe cover meta information to write. + * @throws AdapterException if the adapter failed + */ + public void writeCover(CoverMeta coverMeta) throws AdapterException; +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/GraphMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/GraphMetaOutputAdapter.java new file mode 100644 index 00000000..22dc94af --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/GraphMetaOutputAdapter.java @@ -0,0 +1,21 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.adapters.OutputAdapter; +import i5.las2peer.services.ocd.graphs.CustomGraphMeta; + + +/** + * The common interface of graph output adapters. + * + */ +public interface GraphMetaOutputAdapter extends OutputAdapter { + + /** + * Writes a graph meta and closes the writer. + * @param graphMeta The graph meta information to write. + * @throws AdapterException if the adapter failed + */ + public void writeGraph(CustomGraphMeta graphMeta) throws AdapterException; + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapter.java new file mode 100644 index 00000000..c0b8d4d3 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapter.java @@ -0,0 +1,105 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.centrality.data.CentralityMeta; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.util.Map; + +/** + * A centrality meta information output adapter for the meta XML format. More efficient than + * MetaXmlCentralityOutputAdapter due to not loading full centrality details, but only + * necessary metadata. The output contains meta information about the centrality and corresponding + * graph in XML format. + * + */ +public class MetaXmlCentralityMetaOutputAdapter extends AbstractCentralityMetaOutputAdapter { + + @Override + public void writeCentralityMap(CentralityMeta centralityMeta) throws AdapterException { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document doc = builder.newDocument(); + Element mapElt = doc.createElement("CentralityMap"); + doc.appendChild(mapElt); + /* + * Basic Attributes + */ + Element nameElt = doc.createElement("Name"); + nameElt.appendChild(doc.createTextNode(centralityMeta.getCentralityName())); + mapElt.appendChild(nameElt); + Element idElt = doc.createElement("Id"); + Element mapIdElt = doc.createElement("CentralityMapId"); + mapIdElt.appendChild(doc.createTextNode((centralityMeta.getCentralityKey()))); + idElt.appendChild(mapIdElt); + Element graphIdElt = doc.createElement("GraphId"); + graphIdElt.appendChild(doc.createTextNode(centralityMeta.getGraphKey())); + idElt.appendChild(graphIdElt); + mapElt.appendChild(idElt); + Element graphElt = doc.createElement("Graph"); + Element graphNameElt = doc.createElement("GraphName"); + graphNameElt.appendChild(doc.createTextNode(centralityMeta.getGraphName())); + graphElt.appendChild(graphNameElt); + mapElt.appendChild(graphElt); + /* + * Creation Method + */ + Element creationMethodElt = doc.createElement("CreationMethod"); + Element creationMethodTypeElt = doc.createElement("Type"); + creationMethodTypeElt.appendChild(doc.createTextNode(centralityMeta.getCreationTypeName())); + creationMethodTypeElt.setAttribute("displayName", centralityMeta.getCreationTypeDisplayName()); + creationMethodElt.appendChild(creationMethodTypeElt); +// /* +// * Parameters +// */ +// Element creationMethodParameters = doc.createElement("Parameters"); +// Map parameters = centralityMeta.getCentralityCreationLog().getParameters(); +// for(String parameter : parameters.keySet()) { +// Element creationMethodParameter = doc.createElement("Parameter"); +// Element creationMethodParameterName = doc.createElement("ParameterName"); +// creationMethodParameterName.appendChild(doc.createTextNode(parameter)); +// Element creationMethodParameterValue = doc.createElement("ParameterValue"); +// creationMethodParameterValue.appendChild(doc.createTextNode(parameters.get(parameter))); +// creationMethodParameter.appendChild(creationMethodParameterName); +// creationMethodParameter.appendChild(creationMethodParameterValue); +// creationMethodParameters.appendChild(creationMethodParameter); +// } +// creationMethodElt.appendChild(creationMethodParameters); + /* + * Status + */ + Element creationMethodStatusElt = doc.createElement("Status"); + creationMethodStatusElt.appendChild(doc.createTextNode(centralityMeta.getCreationStatusName())); + creationMethodElt.appendChild(creationMethodStatusElt); + /* + * Execution Time + */ + Element creationMethodExecutionTimeElt = doc.createElement("ExecutionTime"); + creationMethodExecutionTimeElt.appendChild(doc.createTextNode(Long.toString(centralityMeta.getExecutionTime()))); + creationMethodElt.appendChild(creationMethodExecutionTimeElt); + + mapElt.appendChild(creationMethodElt); + /* + * XML output + */ + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + DOMSource domSource = new DOMSource(doc); + StreamResult streamResult = new StreamResult(this.writer); + transformer.transform(domSource, streamResult); + } + catch(Exception e) { + throw new AdapterException(e); + } + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapter.java new file mode 100644 index 00000000..15c3df5a --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapter.java @@ -0,0 +1,93 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.graphs.CoverMeta; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.util.Map; + +/** + * A cover meta information output adapter for the meta XML format. More efficient than MetaXmlCoverOutputAdapter + * due to not loading full covers/graphs. The output contains meta information about the cover and corresponding + * graph in XML format, but not the actual cover/graph instances or other node or edge related meta data. + * + */ +public class MetaXmlCoverMetaOutputAdapter extends AbstractCoverMetaOutputAdapter{ + @Override + public void writeCover(CoverMeta coverMeta) throws AdapterException { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document doc = builder.newDocument(); + Element coverElt = doc.createElement("Cover"); + doc.appendChild(coverElt); + /* + * Basic Attributes + */ + Element idElt = doc.createElement("Id"); + Element coverIdElt = doc.createElement("CoverId"); + coverIdElt.appendChild(doc.createTextNode(coverMeta.getKey())); + idElt.appendChild(coverIdElt); + Element graphIdElt = doc.createElement("GraphId"); + graphIdElt.appendChild(doc.createTextNode(coverMeta.getGraphKey())); + idElt.appendChild(graphIdElt); + coverElt.appendChild(idElt); + Element coverNameElt = doc.createElement("Name"); + coverNameElt.appendChild(doc.createTextNode(coverMeta.getName())); + coverElt.appendChild(coverNameElt); +// Element coverDescrElt = doc.createElement("Description"); +// coverDescrElt.appendChild(doc.createTextNode(cover.getDescription())); +// coverElt.appendChild(coverDescrElt); + Element graphElt = doc.createElement("Graph"); + Element graphNameElt = doc.createElement("Name"); + graphNameElt.appendChild(doc.createTextNode(coverMeta.getGraphName())); + graphElt.appendChild(graphNameElt); + coverElt.appendChild(graphElt); +// Element lastUpdateElt = doc.createElement("LastUpdate"); +// if(cover.getLastUpdate() != null) { +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss"); +// lastUpdateElt.appendChild(doc.createTextNode(dateFormat.format(cover.getLastUpdate()))); +// coverElt.appendChild(lastUpdateElt); +// } + /* + * Creation Method + */ + Element creationMethodElt = doc.createElement("CreationMethod"); + Element creationMethodTypeElt = doc.createElement("Type"); + creationMethodTypeElt.appendChild(doc.createTextNode(coverMeta.getCreationTypeName())); + creationMethodElt.appendChild(creationMethodTypeElt); + creationMethodElt.setAttribute("displayName", coverMeta.getCreationTypeDisplayName()); + Element creationMethodStatusElt = doc.createElement("Status"); + creationMethodStatusElt.appendChild(doc.createTextNode(coverMeta.getCreationStatusName())); + creationMethodElt.appendChild(creationMethodStatusElt); + coverElt.appendChild(creationMethodElt); + /* + * Communities + */ + Element communityCountElement = doc.createElement("CommunityCount"); + communityCountElement.appendChild(doc.createTextNode(Long.toString(coverMeta.getNumberOfCommunities()))); + coverElt.appendChild(communityCountElement); + /* + * XML output + */ + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + DOMSource domSource = new DOMSource(doc); + StreamResult streamResult = new StreamResult(this.writer); + transformer.transform(domSource, streamResult); + } + catch(Exception e) { + throw new AdapterException(e); + } + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapter.java new file mode 100644 index 00000000..12e1925f --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapter.java @@ -0,0 +1,101 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.graphs.CustomGraphMeta; +import i5.las2peer.services.ocd.graphs.GraphType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + + +/** + * A graph meta information output adapter for the meta XML format. More efficient than MetaXmlGraphOutputAdapter + * due to not loading full graphs. The output contains meta information about the graph in XML format, but + * not the actual graph instance or other node or edge related meta data. + * + */ +public class MetaXmlGraphMetaOutputAdapter extends AbstractGraphMetaOutputAdapter { + + @Override + public void writeGraph(CustomGraphMeta graphMeta) throws AdapterException { + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + try { + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document doc = builder.newDocument(); + Element graphElt = doc.createElement("Graph"); + doc.appendChild(graphElt); + /* + * Basic Attributes + */ + Element graphIdElt = doc.createElement("Id"); + graphIdElt.appendChild(doc.createTextNode(graphMeta.getKey())); + graphElt.appendChild(graphIdElt); + Element graphNameElt = doc.createElement("Name"); + graphNameElt.appendChild(doc.createTextNode(graphMeta.getName())); + graphElt.appendChild(graphNameElt); +// Element graphDescrElt = doc.createElement("Description"); +// graphDescrElt.appendChild(doc.createTextNode(graph.getDescription())); +// graphElt.appendChild(graphDescrElt); + Element graphNodeCountElt = doc.createElement("NodeCount"); + graphNodeCountElt.appendChild(doc.createTextNode(Long.toString(graphMeta.getNodeCount()))); + graphElt.appendChild(graphNodeCountElt); + Element graphEdgeCountElt = doc.createElement("EdgeCount"); + graphEdgeCountElt.appendChild(doc.createTextNode(Long.toString(graphMeta.getEdgeCount()))); + graphElt.appendChild(graphEdgeCountElt); +// Element lastUpdateElt = doc.createElement("LastUpdate"); +// if(graph.getLastUpdate() != null) { +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd hh:mm:ss"); +// lastUpdateElt.appendChild(doc.createTextNode(dateFormat.format(graph.getLastUpdate()))); +// graphElt.appendChild(lastUpdateElt); +// } + /* + * Graph Types + */ + + Element typesElt = doc.createElement("Types"); + for(Integer type_id : graphMeta.getTypes()) { + + if(type_id != null) { // case where graph has no types + GraphType type = GraphType.lookupType(type_id); + Element typeElt = doc.createElement("Type"); + typeElt.appendChild(doc.createTextNode(type.name())); + typeElt.setAttribute("displayName", type.getDisplayName()); + typesElt.appendChild(typeElt); + } + } + graphElt.appendChild(typesElt); + /* + * Creation Method + */ + Element creationMethodElt = doc.createElement("CreationMethod"); + Element creationMethodTypeElt = doc.createElement("Type"); + creationMethodTypeElt.appendChild(doc.createTextNode(graphMeta.getCreationTypeName())); + creationMethodTypeElt.setAttribute("displayName", graphMeta.getCreationTypeDisplayName()); + creationMethodElt.appendChild(creationMethodTypeElt); + Element creationMethodStatus = doc.createElement("Status"); + creationMethodStatus.appendChild(doc.createTextNode(graphMeta.getCreationStatusName())); + creationMethodElt.appendChild(creationMethodStatus); + graphElt.appendChild(creationMethodElt); + /* + * XML output + */ + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + DOMSource domSource = new DOMSource(doc); + StreamResult streamResult = new StreamResult(this.writer); + transformer.transform(domSource, streamResult); + } + catch(Exception e) { + throw new AdapterException(e); + } + //System.out.println("end: writing Graph in MetaXmlGraphMetaOutputAdapter"); + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/simulationOutput/MetaXmlSimulationOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/simulationOutput/MetaXmlSimulationOutputAdapter.java index 4f821212..7564b84d 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/simulationOutput/MetaXmlSimulationOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/simulationOutput/MetaXmlSimulationOutputAdapter.java @@ -58,7 +58,7 @@ public void write(SimulationSeries simulation) throws AdapterException { private void writeElementsAbstract(SimulationAbstract simulation, Document doc, Element root) { Element eltId = doc.createElement("Id"); - eltId.appendChild(doc.createTextNode(Long.toString(simulation.getId()))); + eltId.appendChild(doc.createTextNode(simulation.getKey())); root.appendChild(eltId); Element eltName = doc.createElement("Name"); @@ -75,7 +75,7 @@ private void writeElementsAbstract(SimulationAbstract simulation, Document doc, Element eltGraph = doc.createElement("Graph"); Element eltGraphId = doc.createElement("Id"); - eltGraphId.appendChild(doc.createTextNode(String.valueOf(simulation.getNetwork().getId()))); + eltGraphId.appendChild(doc.createTextNode(String.valueOf(simulation.getNetwork().getKey()))); eltGraph.appendChild(eltGraphId); Element eltGraphName = doc.createElement("Name"); eltGraphName.appendChild(doc.createTextNode(String.valueOf(simulation.getNetwork().getName()))); @@ -86,7 +86,7 @@ private void writeElementsAbstract(SimulationAbstract simulation, Document doc, private void writeElementsSeries(SimulationSeries simulation, Document doc, Element root) { Element eltGraph = doc.createElement("Parameters"); - SimulationSeriesParameters parameters = simulation.getParameters(); + SimulationSeriesParameters parameters = simulation.getSimulationSeriesParameters(); Element eltGraphId = doc.createElement("Game"); eltGraphId.appendChild(doc.createTextNode(String.valueOf(parameters.getGame().humanRead()))); eltGraph.appendChild(eltGraphId); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapter.java index c7bdd5af..d47cece3 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapter.java @@ -8,26 +8,19 @@ import net.minidev.json.JSONObject; import net.minidev.json.JSONArray; -import y.base.Node; -import y.base.Edge; -import y.view.Graph2D; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; -import y.view.NodeLabel; -import java.awt.Color; -import y.view.NodeRealizer; -import y.view.ShapeNodeRealizer; -import y.view.EdgeLabel; -import y.view.EdgeRealizer; -import y.view.LineType; +import java.awt.*; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; -//TODO: Add labels -public class JsonVisualOutputAdapter extends AbstractVisualOutputAdapter { +public class JsonVisualOutputAdapter extends AbstractVisualOutputAdapter { /** * Creates a new instance setting the writer attribute. * @param writer The writer used for output. @@ -43,37 +36,44 @@ public JsonVisualOutputAdapter() { } @Override - public void writeGraph(Graph2D graph) throws AdapterException { + //TODO: Check if color values still need to be multiplied with 255 + public void writeGraph(CustomGraph graph) throws AdapterException { JSONObject obj = new JSONObject(); // Document doc = builder.newDocument(); ArrayList nodes = new ArrayList(); - for (Node n : graph.getNodeArray()) { + Iterator nodesIt = graph.iterator(); + while (nodesIt.hasNext()) { + Node n = nodesIt.next(); HashMap tmp = new HashMap(); - tmp.put("id", n.index()); + tmp.put("id", n.getIndex()); if(graph instanceof CustomGraph) { - tmp.put("name", ((CustomGraph)graph).getNodeName(n)); + tmp.put("name", graph.getNodeName(n)); } - NodeRealizer nRealizer = graph.getRealizer(n); - //TODO: Check what the color is when not set - //Color + //TODO: Check whether default coloring makes sense here + //Color //rgba(r,g,b,a) - float[] nodeColor = new float[4]; - nodeColor = nRealizer.getFillColor().getRGBComponents(nodeColor); - tmp.put("color", "rgba(" + nodeColor[0]*255 + "," + nodeColor[1]*255 + "," + nodeColor[2]*255 + "," + nodeColor[3] + ")"); - - //TODO: Check what the size is when not set + + float[] fillColor = (float[]) n.getAttribute("ui.fill-color"); + if(fillColor == null) { + fillColor = new float[]{0.f,0.f,1.f, 0.6f}; // default coloring + } + tmp.put("color", "rgba(" + fillColor[0] + "," + fillColor[1] + "," + fillColor[2] + "," + fillColor[3] + ")"); + + //TODO: Check whether default size makes sense here //Size //As the force graph representation uses circles and height and width are the same in our layoutHandler, this suffices - double nodeSize = 0.0f; - nodeSize = nRealizer.getHeight(); - tmp.put("size", nodeSize); + double nodeSize = .3f; + if(n.getAttribute("ui.size") != null) { + tmp.put("size", n.getAttribute("ui.size").toString()); + } + else { + tmp.put("size", nodeSize); + } //Label - String nodeLabel = ""; - nodeLabel = nRealizer.getLabelText(); - tmp.put("label", nodeLabel); + tmp.put("label", n.getLabel("label").toString()); JSONObject jsonNode = (JSONObject) JSONValue.parse(JSONValue.toJSONString(tmp)); @@ -82,23 +82,21 @@ public void writeGraph(Graph2D graph) throws AdapterException { ArrayList edges = new ArrayList(); - for (Edge e : graph.getEdgeArray()) { + Iterator edgesIt = graph.edges().iterator(); + while (edgesIt.hasNext()) { + Edge e = edgesIt.next(); HashMap tmp = new HashMap(); - tmp.put("source", e.source().index()); - tmp.put("target", e.target().index()); + tmp.put("source", e.getSourceNode().getIndex()); + tmp.put("target", e.getTargetNode().getIndex()); // LINE_STYLE = 0; DASHED_STYLE = 1; DOTTED_STYLE = 2; DASHED_DOTTED_STYLE = 3; - EdgeRealizer eRealizer = graph.getRealizer(e); - LineType lineType = LineType.LINE_1; - lineType = eRealizer.getLineType(); - if(lineType.equals(LineType.DASHED_1)) - { - System.out.println("WORKED"); - tmp.put("style", 1); - } - else if(lineType.equals(LineType.DOTTED_1)) - { - tmp.put("style", 2); + if(e.getAttribute("ui.stroke-mode") != null) { + String lineType = e.getAttribute("ui.stroke-mode").toString(); + if (lineType.equals("dashes")) { + tmp.put("style", 1); + } else if (lineType.equals("dots")) { + tmp.put("style", 2); + } } else { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualOutputAdapter.java index c10efb64..8c87509a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualOutputAdapter.java @@ -5,20 +5,20 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import y.io.IOHandler; -import y.view.Graph2D; -import yext.svg.io.SVGIOHandler; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import org.graphstream.stream.file.FileSinkSVG; public class SvgVisualOutputAdapter extends AbstractVisualOutputAdapter { @Override - public void writeGraph(Graph2D graph) throws AdapterException { + public void writeGraph(CustomGraph graph) throws AdapterException { + FileSinkSVG fileSink = new FileSinkSVG(); ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + // Writes out the graph using the IOHandler - IOHandler ioh = new SVGIOHandler(); try { - ioh.write(graph, outStream); + fileSink.writeAll(graph, outStream); String outString = outStream.toString(); writer.write(outString); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/VisualOutputAdapter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/VisualOutputAdapter.java index 5f3ffb40..884e5de6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/VisualOutputAdapter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/adapters/visualOutput/VisualOutputAdapter.java @@ -2,7 +2,7 @@ import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.adapters.OutputAdapter; -import y.view.Graph2D; +import i5.las2peer.services.ocd.graphs.CustomGraph; /** * The common interface of all visual output adapters. @@ -16,6 +16,6 @@ public interface VisualOutputAdapter extends OutputAdapter { * @param graph The graph to write. * @throws AdapterException if the adapter failed */ - public void writeGraph(Graph2D graph) throws AdapterException; + public void writeGraph(CustomGraph graph) throws AdapterException; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationAlgorithm.java index 7f22b82c..1975b504 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationAlgorithm.java @@ -21,6 +21,7 @@ import java.util.Map.Entry; import java.util.Random; import java.util.Set; +import java.util.UUID; import java.lang.Double; import java.lang.Math; @@ -29,9 +30,9 @@ import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.vector.Vector; import org.la4j.vector.dense.BasicVector; -import y.base.Edge; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * The original version of the overlapping community detection algorithm introduced in 2020 by Ping Ji, Shanxin Zhang, Zhiping Zhou: @@ -49,7 +50,7 @@ public class AntColonyOptimizationAlgorithm implements OcdAlgorithm { * maximal clique encoding. the integer represents the number of the clique and the Hashset stores the * clique members */ - private HashMap> maxClq; + private HashMap> maxClq; /** * number of ants/subproblems to solve. Must be at least 2 (Otherwise it will result in a division by 0). @@ -226,7 +227,7 @@ public CoverCreationType getAlgorithmType(){ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithmException, InterruptedException, OcdMetricException { // construct the maximal clique graph and initialize the parameters CustomGraph MCR = representationScheme(graph); - int nodeNr = MCR.nodeCount(); + int nodeNr = MCR.getNodeCount(); List ants = initialization(MCR, nodeNr); for(int i = 0; i < maxIterations; i++) {// constructions of the Pareto Front (Pareto optimal solutions) @@ -251,8 +252,9 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithm * connected. * @param graph to make an Maximal Clique Graph from * @return encoded input graph + * @throws InterruptedException If the executing thread was interrupted. */ - protected CustomGraph representationScheme(CustomGraph graph) { + protected CustomGraph representationScheme(CustomGraph graph) throws InterruptedException { // maximal clique search MaximalCliqueSearch MCR = new MaximalCliqueSearch(); maxClq = MCR.cliques(graph); @@ -265,16 +267,16 @@ protected CustomGraph representationScheme(CustomGraph graph) { int nodes = maxClq.size(); CustomGraph encoding = new CustomGraph(); for(int i = 0; i < nodes; i++) {//creating clique nodes - encoding.createNode(); + encoding.addNode(Integer.toString(i)); } - for(Node n1: encoding.getNodeArray()) { // creating clique edges - int i1 = n1.index(); - for(Node n2: encoding.getNodeArray()) { - int i2 = n2.index(); + for(Node n1: encoding.nodes().toArray(Node[]::new)) { // creating clique edges + int i1 = n1.getIndex(); + for(Node n2: encoding.nodes().toArray(Node[]::new)) { + int i2 = n2.getIndex(); double ls = lkstrgth.get(i1, i2); if(ls>=wtr) { // filter out weak edges - Edge e1 = encoding.createEdge(n1, n2); - Edge e2 = encoding.createEdge(n2, n1); + Edge e1 = encoding.addEdge(UUID.randomUUID().toString(),n1, n2); + Edge e2 = encoding.addEdge(UUID.randomUUID().toString(),n2, n1); encoding.setEdgeWeight(e1, ls); encoding.setEdgeWeight(e2, ls); } @@ -288,8 +290,9 @@ protected CustomGraph representationScheme(CustomGraph graph) { * @param graph Original undirected graph * @param maxClq output of the MaximalCliqueGraphRepresentation * @return Matrix of link strength of the clique edges + * @throws InterruptedException If the executing thread was interrupted. */ - protected Matrix linkStrength(CustomGraph graph, HashMap> maxClq) { + protected Matrix linkStrength(CustomGraph graph, HashMap> maxClq) throws InterruptedException { int clqNr = maxClq.size(); Matrix lkstrgth = new Basic2DMatrix(clqNr,clqNr); @@ -336,35 +339,35 @@ protected Matrix linkStrength(CustomGraph graph, HashMap> * @param v1 node which is in a clique * @param v2 node which is not in the same clique as v1 * @return Czechkanowski Dice distance + * @throws InterruptedException If the executing thread was interrupted. */ - protected double CzechkanowskiDice(CustomGraph graph, Node v1, Node v2) { - NodeCursor nbors1 = v1.neighbors(); - NodeCursor nbors2 = v2.neighbors(); + protected double CzechkanowskiDice(CustomGraph graph, Node v1, Node v2) throws InterruptedException { + Node[] nbors1 = graph.getNeighbours(v1).toArray(Node[]::new); + Node[] nbors2 = graph.getNeighbours(v2).toArray(Node[]::new); - int nbor1size = nbors1.size()/2; - int nbor2size = nbors2.size()/2; + int nbor1size = nbors1.length/2; + int nbor2size = nbors2.length/2; // compute the shared neighbors - double olapsize = 0; - for(int i = 0 ; i = nbors2.length) { + j1=0; + } + Node n2 = nbors2[j1]; if(n2 == n1) { olapsize++; break; } - - nbors2.cyclicNext(); } - - nbors1.cyclicNext(); } // compute the distance - double edgeNr = graph.edgeCount()/2; - double nodeNr = graph.nodeCount(); + double edgeNr = graph.getEdgeCount()/2; + double nodeNr = graph.getNodeCount(); double avgDegr = 2*edgeNr/nodeNr; double tmp1 = avgDegr - nbor1size; double tmp2 = avgDegr - nbor2size; @@ -448,7 +451,7 @@ protected List initialization(CustomGraph graph, int nodeNr) throws Interru heuristic = new Basic2DMatrix(nodeNr,nodeNr); // heuristic information matrix Matrix neighbors = graph.getNeighbourhoodMatrix(); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); pheromones = new ArrayList(); double[][] p = new double[nodeNr][nodeNr]; for(int i = 0; i < nodeNr-1; i++) { @@ -467,7 +470,7 @@ protected List initialization(CustomGraph graph, int nodeNr) throws Interru for(int j = i+1; j < nodeNr; j++) { Node n2 = nodes[j]; double h; // heuristic for edge ij - if(!graph.containsEdge(n1, n2)) { + if(!n1.hasEdgeToward(n2)) { h = 0; } else { Vector nbor2 = neighbors.getRow(j); @@ -491,8 +494,8 @@ protected List initialization(CustomGraph graph, int nodeNr) throws Interru h = 1/(1+Math.pow(Math.E, pearson)); // heuristic information value for nodes i, j // set initial pheromone matrix - p[n1.index()][n2.index()] = initialPheromones; - p[n2.index()][n1.index()] = initialPheromones; + p[n1.getIndex()][n2.getIndex()] = initialPheromones; + p[n2.getIndex()][n1.getIndex()] = initialPheromones; } // set heuristic information matrix @@ -691,7 +694,7 @@ protected void update(CustomGraph graph, List ants, int nodeNr) throws Inte */ protected void constructSolution(CustomGraph graph, Ant ant, int nodeNr) throws InterruptedException { Random rand = new Random(); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); ant.setFalseNew_sol(); Matrix phi = new Basic2DMatrix(nodeNr,nodeNr); @@ -799,7 +802,7 @@ protected double tchebycheffDecomposition(Vector fitness, Vector lambda) { * @return whether edge (k,l) is contained in solution sol */ protected double isEdgeinSol(CustomGraph graph, Vector sol, int k, int l) { - if(graph.containsEdge(graph.getNodeArray()[l], graph.getNodeArray()[k])&& sol.get(k) == sol.get(l)) { + if(graph.getNode(l).hasEdgeToward(graph.getNode(k)) && sol.get(k) == sol.get(l)) { //TODO: Check if this behaves the same as previous return 1; } return 0; @@ -865,7 +868,7 @@ protected Vector fitnessCalculations(CustomGraph graph, Vector sol, int nodeNr) */ protected double cliqueInterconectivity(CustomGraph graph, Vector com1, Vector com2, int nodeNr) { double L = 0; // counter of edges in between the communities - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); for(int i = 0; i < nodeNr; i++) { if(com1.get(i) == 0) { // filters out all nodes within a community from the community vector continue; @@ -876,8 +879,8 @@ protected double cliqueInterconectivity(CustomGraph graph, Vector com1, Vector c continue; } Node n2 = nodes[j]; - if (graph.containsEdge(n1, n2)) { // if two nodes from these two communities are connected by an edge - L += graph.getEdgeWeight(n1.getEdgeTo(n2)); + if (n1.hasEdgeToward(n2)) { // if two nodes from these two communities are connected by an edge + L += graph.getEdgeWeight(n1.getEdgeToward(n2)); //TODO: Check if this behaves the same as before } } } @@ -909,13 +912,13 @@ protected Cover decodeMaximalCliques(CustomGraph graph, int nodeNr) throws OcdAl ModularityMetric MM = new ModularityMetric(); HashSet inCommunity = new HashSet(); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); for(Vector sol: EP.values()) { // find out how many communities are there List membershipMatrixVectors = new ArrayList(nodeNr); List com = new ArrayList(); - for(int i = 0; i < graph.nodeCount(); i++) { + for(int i = 0; i < graph.getNodeCount(); i++) { inCommunity.add(nodes[i]); } for(int i = 0; i < nodeNr; i++) { @@ -926,7 +929,7 @@ protected Cover decodeMaximalCliques(CustomGraph graph, int nodeNr) throws OcdAl } for(int i = 0; i < nodeNr; i++) { // create empty membership vectors - Vector v = new BasicVector(graph.nodeCount()); + Vector v = new BasicVector(graph.getNodeCount()); membershipMatrixVectors.add(i,v); } @@ -936,7 +939,7 @@ protected Cover decodeMaximalCliques(CustomGraph graph, int nodeNr) throws OcdAl for(Node n: entry.getValue()){ inCommunity.remove(n); Vector v = membershipMatrixVectors.get(member); - v.set(n.index(), 1); + v.set(n.getIndex(), 1); membershipMatrixVectors.set(member, v); // set node in community } } @@ -945,11 +948,11 @@ protected Cover decodeMaximalCliques(CustomGraph graph, int nodeNr) throws OcdAl for(Node n: inCommunity) { Set neighbors = graph.getNeighbours(n); for(Node neighbor: neighbors) { - int id = neighbor.index(); + int id = neighbor.getIndex(); for(int i = 0; i < membershipMatrixVectors.size(); i++) { Vector v = membershipMatrixVectors.get(i); if(v.get(id) == 1) { - v.set(n.index(), 1); + v.set(n.getIndex(), 1); break; } } @@ -958,7 +961,7 @@ protected Cover decodeMaximalCliques(CustomGraph graph, int nodeNr) throws OcdAl } // set membership matrix - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(),com.size()); + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(),com.size()); for(int i = 0; i < com.size(); i++) { membershipMatrix.setColumn(i, membershipMatrixVectors.get(com.get(i))); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithm.java index 35fbe00c..f510afb5 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithm.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Set; +import org.graphstream.graph.implementations.MultiNode; import org.la4j.matrix.Matrix; import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.matrix.sparse.CCSMatrix; @@ -21,10 +22,9 @@ import org.la4j.vector.Vectors; import org.la4j.vector.dense.BasicVector; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements a custom extended version of the Random Walk Label Propagation Algorithm, also called DMID, by M. Shahriari, S. Krott and R. Klamma: @@ -148,22 +148,18 @@ protected Matrix getTransposedDisassortativityMatrix(CustomGraph graph) throws I * Calculates transposed disassortativity matrix in a special sparse * matrix format. */ - Matrix disassortativities = new CCSMatrix(graph.nodeCount(), - graph.nodeCount()); - EdgeCursor edges = graph.edges(); + Matrix disassortativities = new CCSMatrix(graph.getNodeCount(), + graph.getNodeCount()); double disassortativity; - Edge edge; - while (edges.ok()) { + for (Edge edge : graph.edges().toArray(Edge[]::new)) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); disassortativity = Math - .abs(graph.getWeightedInDegree(edge.target()) - - graph.getWeightedInDegree(edge.source())); - disassortativities.set(edge.target().index(), - edge.source().index(), disassortativity); - edges.next(); + .abs(graph.getWeightedInDegree(edge.getTargetNode()) + - graph.getWeightedInDegree(edge.getSourceNode())); + disassortativities.set(edge.getTargetNode().getIndex(), + edge.getSourceNode().getIndex(), disassortativity); } /* @@ -234,23 +230,20 @@ protected Vector executeRandomWalk(Matrix disassortativityMatrix) */ protected Vector getLeadershipValues(CustomGraph graph, Vector disassortativityVector) throws InterruptedException { - Vector leadershipVector = new BasicVector(graph.nodeCount()); - NodeCursor nodes = graph.nodes(); - Node node; + Vector leadershipVector = new BasicVector(graph.getNodeCount()); + double leadershipValue; - while (nodes.ok()) { + for (Node node : graph.nodes().toArray(Node[]::new)) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); /* * Note: degree normalization is left out since it * does not influence the outcome. */ leadershipValue = graph.getWeightedInDegree(node) - * disassortativityVector.get(node.index()); - leadershipVector.set(node.index(), leadershipValue); - nodes.next(); + * disassortativityVector.get(node.getIndex()); + leadershipVector.set(node.getIndex(), leadershipValue); } return leadershipVector; } @@ -269,12 +262,12 @@ protected Vector getLeadershipValues(CustomGraph graph, protected Map getFollowerDegrees(CustomGraph graph, Vector leadershipVector) throws InterruptedException { Map followerMap = new HashMap(); - NodeCursor nodes = graph.nodes(); + Iterator nodes = graph.iterator(); /* * Iterates over all nodes to detect their local leader */ Node node; - NodeCursor successors; + Iterator successorsIt; double maxInfluence; List leaders = new ArrayList(); Node successor; @@ -282,21 +275,21 @@ protected Map getFollowerDegrees(CustomGraph graph, double successorInfluence; Edge nodeEdge; double followerDegree; - while (nodes.ok()) { + while (nodes.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - successors = node.successors(); + node = nodes.next(); + successorsIt = graph.getSuccessorNeighbours(node).iterator(); maxInfluence = Double.NEGATIVE_INFINITY; leaders.clear(); /* * Checks all successors for possible leader */ - while (successors.ok()) { - successor = successors.node(); - successorEdge = node.getEdgeTo(successor); - successorInfluence = leadershipVector.get(successor.index()) + while (successorsIt.hasNext()) { + successor = successorsIt.next(); + successorEdge = node.getEdgeToward(successor); + successorInfluence = leadershipVector.get(successor.getIndex()) * graph.getEdgeWeight(successorEdge); if (successorInfluence >= maxInfluence) { nodeEdge = node.getEdgeFrom(successor); @@ -305,7 +298,7 @@ protected Map getFollowerDegrees(CustomGraph graph, */ if (nodeEdge == null || successorInfluence > leadershipVector.get(node - .index()) * graph.getEdgeWeight(nodeEdge)) { + .getIndex()) * graph.getEdgeWeight(nodeEdge)) { if (successorInfluence > maxInfluence) { /* * Other nodes have lower influence @@ -316,7 +309,6 @@ protected Map getFollowerDegrees(CustomGraph graph, maxInfluence = successorInfluence; } } - successors.next(); } if (!leaders.isEmpty()) { for (Node leader : leaders) { @@ -328,7 +320,6 @@ protected Map getFollowerDegrees(CustomGraph graph, followerDegree += 1d / leaders.size()); } } - nodes.next(); } return followerMap; } @@ -439,7 +430,8 @@ protected Map executeLabelPropagation(CustomGraph graph, Iterator nodeIt; Node node; double profitability; - NodeCursor nodeSuccessors; + Set nodesuccessors; + Iterator nodesuccessorsIt; Node nodeSuccessor; do { if(Thread.interrupted()) { @@ -456,17 +448,17 @@ protected Map executeLabelPropagation(CustomGraph graph, while (nodeIt.hasNext()) { node = nodeIt.next(); profitability = 0; - nodeSuccessors = node.successors(); - while (nodeSuccessors.ok()) { - nodeSuccessor = nodeSuccessors.node(); + nodesuccessors = graph.getSuccessorNeighbours(node); + nodesuccessorsIt = nodesuccessors.iterator(); + while (nodesuccessorsIt.hasNext()) { + nodeSuccessor = nodesuccessorsIt.next(); Integer joinIteration = memberships.get(nodeSuccessor); if (nodeSuccessor.equals(leader) || ( joinIteration != null && joinIteration < iterationCount)) { profitability++; } - nodeSuccessors.next(); } - if (profitability / nodeSuccessors.size() > profitabilityThreshold) { + if (profitability / nodesuccessors.size() > profitabilityThreshold) { memberships.put(node, iterationCount); } } @@ -494,32 +486,30 @@ protected Map executeLabelPropagation(CustomGraph graph, protected Set getBehaviorPredecessors(CustomGraph graph, Map memberships, Node leader) throws InterruptedException { Set neighbors = new HashSet(); - NodeCursor leaderPredecessors = leader.predecessors(); + Iterator leaderpredecessorsIt = graph.getPredecessorNeighbours(leader).iterator(); Node leaderPredecessor; - while (leaderPredecessors.ok()) { + while (leaderpredecessorsIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - leaderPredecessor = leaderPredecessors.node(); + leaderPredecessor = leaderpredecessorsIt.next(); if (!memberships.containsKey(leaderPredecessor)) { neighbors.add(leaderPredecessor); } - leaderPredecessors.next(); } - NodeCursor memberPredecessors; + Iterator memberpredecessorsIt; Node memberPredecessor; for (Node member : memberships.keySet()) { if(Thread.interrupted()) { throw new InterruptedException(); } - memberPredecessors = member.predecessors(); - while (memberPredecessors.ok()) { - memberPredecessor = memberPredecessors.node(); + memberpredecessorsIt = graph.getPredecessorNeighbours(member).iterator(); + while (memberpredecessorsIt.hasNext()) { + memberPredecessor = memberpredecessorsIt.next(); if (!memberPredecessor.equals(leader) && !memberships.containsKey(memberPredecessor)) { neighbors.add(memberPredecessor); } - memberPredecessors.next(); } } return neighbors; @@ -541,15 +531,12 @@ protected Set getBehaviorPredecessors(CustomGraph graph, protected boolean areAllNodesAssigned(CustomGraph graph, Map> communities) throws InterruptedException { boolean allNodesAreAssigned = true; - NodeCursor nodes = graph.nodes(); boolean nodeIsAssigned; - Node node; - while (nodes.ok()) { + for (Node node : graph.nodes().toArray(Node[]::new)) { if(Thread.interrupted()) { throw new InterruptedException(); } nodeIsAssigned = false; - node = nodes.node(); for (Map.Entry> entry : communities .entrySet()) { if (entry.getValue().containsKey(node)) { @@ -561,7 +548,6 @@ protected boolean areAllNodesAssigned(CustomGraph graph, allNodesAreAssigned = false; break; } - nodes.next(); } return allNodesAreAssigned; } @@ -580,7 +566,7 @@ protected boolean areAllNodesAssigned(CustomGraph graph, */ protected Cover getMembershipDegrees(CustomGraph graph, Map> communities) throws InterruptedException { - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), communities.size()); int communityIndex = 0; double membershipDegree; @@ -588,11 +574,11 @@ protected Cover getMembershipDegrees(CustomGraph graph, if(Thread.interrupted()) { throw new InterruptedException(); } - membershipMatrix.set(leader.index(), communityIndex, 1.0); + membershipMatrix.set(leader.getIndex(), communityIndex, 1.0); for (Map.Entry entry : communities.get(leader) .entrySet()) { membershipDegree = 1.0 / Math.pow(entry.getValue(), 2); - membershipMatrix.set(entry.getKey().index(), communityIndex, + membershipMatrix.set(entry.getKey().getIndex(), communityIndex, membershipDegree); } communityIndex++; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithm.java index 37cb61eb..737c6789 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithm.java @@ -21,8 +21,9 @@ import org.la4j.vector.Vectors; import org.la4j.vector.functor.VectorAccumulator; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * The original version of the overlapping community detection algorithm introduced in 2012 by H.J. Li, J. Zhang, Z.P. Liu, L. Chen and X.S. Zhang: @@ -152,36 +153,32 @@ protected Matrix calculateMemberships(CustomGraph graph, Map lead Matrix updatedMemberships = initMembershipMatrix(graph, leaders); Vector membershipContributionVector; Vector updatedMembershipVector; - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; - NodeCursor successors; - Node successor; + Set successors; int iteration = 0; do { memberships = updatedMemberships; updatedMemberships = new CCSMatrix(memberships.rows(), memberships.columns()); - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if(!leaders.keySet().contains(node)) { - successors = node.successors(); - updatedMembershipVector = memberships.getRow(node.index()); - while(successors.ok()) { - successor = successors.node(); - membershipContributionVector = memberships.getRow(successor.index()); + successors = graph.getSuccessorNeighbours(node); + updatedMembershipVector = memberships.getRow(node.getIndex()); + for(Node successor : successors) { + membershipContributionVector = memberships.getRow(successor.getIndex()); updatedMembershipVector = updatedMembershipVector.add(membershipContributionVector); - successors.next(); } - updatedMemberships.setRow(node.index(), updatedMembershipVector.divide(1 + successors.size())); + updatedMemberships.setRow(node.getIndex(), updatedMembershipVector.divide(1 + successors.size())); } else { - updatedMemberships.set(node.index(), leaders.get(node), 1); + updatedMemberships.set(node.getIndex(), leaders.get(node), 1); } - nodes.next(); } - nodes.toFirst(); + nodesIt = graph.iterator(); iteration++; } while (getMaxDifference(updatedMemberships, memberships) > membershipsPrecisionFactor && iteration < membershipsIterationBound); @@ -225,23 +222,22 @@ protected double getMaxDifference(Matrix matA, Matrix matB) throws InterruptedEx */ protected Matrix initMembershipMatrix(CustomGraph graph, Map leaders) throws InterruptedException { int communityCount = Collections.max(leaders.values()) + 1; - Matrix memberships = new CCSMatrix(graph.nodeCount(), communityCount); - NodeCursor nodes = graph.nodes(); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), communityCount); + Iterator nodesIt = graph.iterator(); Node node; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if(leaders.keySet().contains(node)) { - memberships.set(node.index(), leaders.get(node), 1); + memberships.set(node.getIndex(), leaders.get(node), 1); } else { for(int i=0; i lead * @throws InterruptedException if the thread was interrupted */ protected Map determineCommunityLeaders(CustomGraph graph, Matrix distances, Map leadershipValues) throws InterruptedException { - Node[] nodeArray = graph.getNodeArray(); + Node[] nodeArray = graph.nodes().toArray(Node[]::new); Map communityLeaders = new HashMap(); int communityCount = 0; Set leaders = determineLeaders(graph, distances, leadershipValues); @@ -270,7 +266,7 @@ protected Map determineCommunityLeaders(CustomGraph graph, Matrix leader = leaderIt.next(); communityLeaders.put(leader, communityCount); leaders.remove(leader); - for(Integer i : getInfluenceNodes(distances.getRow(leader.index()), distances.getColumn(leader.index()))) { + for(Integer i : getInfluenceNodes(distances.getRow(leader.getIndex()), distances.getColumn(leader.getIndex()))) { influenceNode = nodeArray[i]; if(leaders.contains(influenceNode)) { communityLeaders.put(influenceNode, communityCount); @@ -296,29 +292,27 @@ protected Map determineCommunityLeaders(CustomGraph graph, Matrix */ protected Set determineLeaders(CustomGraph graph, Matrix distances, Map leadershipValues) throws InterruptedException { Set leaders = new HashSet(); - NodeCursor nodes = graph.nodes(); - Node[] nodeArray = graph.getNodeArray(); + Iterator nodesIt = graph.iterator(); + Node[] nodeArray = graph.nodes().toArray(Node[]::new); Node node; - while(nodes.ok()) { - leaders.add(nodes.node()); - nodes.next(); + while(nodesIt.hasNext()) { + leaders.add(nodesIt.next()); } - nodes.toFirst(); - while(nodes.ok()) { + nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if(leaders.contains(node)) { double nodeLeadershipValue = leadershipValues.get(node); - for(Integer i : getInfluenceNodes(distances.getRow(node.index()), distances.getColumn(node.index()))) { + for(Integer i : getInfluenceNodes(distances.getRow(node.getIndex()), distances.getColumn(node.getIndex()))) { if(leadershipValues.get(nodeArray[i]) > nodeLeadershipValue) { leaders.remove(node); break; } } } - nodes.next(); } return leaders; } @@ -333,16 +327,15 @@ protected Set determineLeaders(CustomGraph graph, Matrix distances, Map calculateLeadershipValues(CustomGraph graph, Matrix distances) throws InterruptedException { - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; Map leadershipValues = new HashMap(); - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - leadershipValues.put(node, getLeadershipValue(distances.getColumn(node.index()))); - nodes.next(); + node = nodesIt.next(); + leadershipValues.put(node, getLeadershipValue(distances.getColumn(node.getIndex()))); } return leadershipValues; } @@ -357,20 +350,20 @@ protected Map calculateLeadershipValues(CustomGraph graph, Matrix * @throws InterruptedException if the thread was interrupted */ protected Matrix calculateNodeDistances(CustomGraph graph) throws InterruptedException { - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; - NodeCursor predecessors; + Iterator predecessorsIt; Node predecessor; double edgeWeight; double minEdgeWeight = graph.getMinEdgeWeight(); double maxEdgeWeight = graph.getMaxEdgeWeight(); Map influencedNodeDistances = new HashMap(); Map candidateNodeDistances = new HashMap(); - Matrix nodeDistances = new CCSMatrix(graph.nodeCount(), graph.nodeCount()); + Matrix nodeDistances = new CCSMatrix(graph.getNodeCount(), graph.getNodeCount()); Node closestCandidate; double closestCandidateDistance; double updatedDistance; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } @@ -379,17 +372,16 @@ protected Matrix calculateNodeDistances(CustomGraph graph) throws InterruptedExc */ influencedNodeDistances.clear(); candidateNodeDistances.clear(); - node = nodes.node(); + node = nodesIt.next(); influencedNodeDistances.put(node, 0d); /* * Initializes node predecessors. */ - predecessors = node.predecessors(); - while(predecessors.ok()) { - predecessor = predecessors.node(); + predecessorsIt = graph.getPredecessorNeighbours(node).iterator(); + while(predecessorsIt.hasNext()) { + predecessor = predecessorsIt.next(); edgeWeight = graph.getEdgeWeight(node.getEdgeFrom(predecessor)); candidateNodeDistances.put(predecessor, getEdgeLength(edgeWeight, minEdgeWeight, maxEdgeWeight)); - predecessors.next(); } /* * Determines node distances to predecessors. @@ -413,9 +405,9 @@ protected Matrix calculateNodeDistances(CustomGraph graph) throws InterruptedExc if(closestCandidateDistance <= distanceBound) { influencedNodeDistances.put(closestCandidate, closestCandidateDistance); candidateNodeDistances.remove(closestCandidate); - predecessors = closestCandidate.predecessors(); - while(predecessors.ok()) { - predecessor = predecessors.node(); + predecessorsIt = graph.getPredecessorNeighbours(closestCandidate).iterator(); + while(predecessorsIt.hasNext()) { + predecessor = predecessorsIt.next(); edgeWeight = graph.getEdgeWeight(closestCandidate.getEdgeFrom(predecessor)); updatedDistance = closestCandidateDistance + getEdgeLength(edgeWeight, minEdgeWeight, maxEdgeWeight); if(candidateNodeDistances.containsKey(predecessor)) { @@ -425,7 +417,6 @@ protected Matrix calculateNodeDistances(CustomGraph graph) throws InterruptedExc else if(!influencedNodeDistances.containsKey(predecessor)) { candidateNodeDistances.put(predecessor, updatedDistance); } - predecessors.next(); } } @@ -435,9 +426,8 @@ else if(!influencedNodeDistances.containsKey(predecessor)) { */ influencedNodeDistances.remove(node); for(Map.Entry entry : influencedNodeDistances.entrySet()) { - nodeDistances.set(entry.getKey().index(), node.index(), entry.getValue()); + nodeDistances.set(entry.getKey().getIndex(), node.getIndex(), entry.getValue()); } - nodes.next(); } return nodeDistances; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ContentBasedWeightingAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ContentBasedWeightingAlgorithm.java index 4e7b18f3..0ae8f34e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ContentBasedWeightingAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ContentBasedWeightingAlgorithm.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.algorithms; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.commons.math3.linear.ArrayRealVector; @@ -13,9 +10,10 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.metrics.ExecutionTime; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; + +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements one of the algorithms by Sabrina Haefele conceived in the thesis: @@ -65,40 +63,37 @@ public CustomGraph detectOverlappingCommunities(CustomGraph graph, ExecutionTime //et.stop(); Similarities sim = new Similarities(); //normalize weights - EdgeCursor edges = graph.edges(); - EdgeCursor comp = graph.edges(); + Iterator edgeIterator = graph.edges().iterator(); + Iterator comp = graph.edges().iterator(); Edge edge; Edge compEdge; double max = 0; - while(edges.ok()){ - edge = edges.edge(); - while(comp.ok()){ - compEdge = comp.edge(); - if(edge.source().equals(compEdge.source()) || edge.target().equals(compEdge.source())){ + while(edgeIterator.hasNext()){ + edge = edgeIterator.next(); + while(comp.hasNext()){ + compEdge = comp.next(); + if(edge.getSourceNode().equals(compEdge.getSourceNode()) || edge.getTargetNode().equals(compEdge.getSourceNode())){ double temp = graph.getEdgeWeight(compEdge); if(max < temp){ max = temp; } } - comp.next(); } - comp.toFirst(); + comp = graph.edges().iterator(); graph.setEdgeWeight(edge, graph.getEdgeWeight(edge)/max); - edges.next(); } - edges.toFirst(); + edgeIterator = graph.edges().iterator(); //compute and combine content-based weight - while(edges.ok()){ - edge = edges.edge(); - Node source = edge.source(); - Node target = edge.target(); + while(edgeIterator.hasNext()){ + edge = edgeIterator.next(); + Node source = edge.getSourceNode(); + Node target = edge.getTargetNode(); ArrayRealVector v = (ArrayRealVector) tm.getMatrix().getRowVector(tm.getNodeIdList().indexOf(source)); ArrayRealVector u = (ArrayRealVector) tm.getMatrix().getRowVector(tm.getNodeIdList().indexOf(target)); double s = sim.cosineSim(v, u); s = (s + graph.getEdgeWeight(edge))/2; graph.setEdgeWeight(edge, s); - edges.next(); } return graph; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/CostFunctionOptimizationClusteringAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/CostFunctionOptimizationClusteringAlgorithm.java index 8edd0000..b3d816d6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/CostFunctionOptimizationClusteringAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/CostFunctionOptimizationClusteringAlgorithm.java @@ -21,11 +21,12 @@ import i5.las2peer.services.ocd.metrics.ExecutionTime; import i5.las2peer.services.ocd.algorithms.utils.Similarities; import i5.las2peer.services.ocd.algorithms.utils.Point; -import y.base.Node; import i5.las2peer.services.ocd.algorithms.utils.Cluster; import i5.las2peer.services.ocd.algorithms.utils.CostFunction; import i5.las2peer.services.ocd.algorithms.utils.Clustering; +import org.graphstream.graph.Node; + /** * Implements one of the algorithms by Sabrina Haefele conceived in the thesis: * Overlapping Community Detection Based on Content and Authority diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/DetectingOverlappingCommunitiesAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/DetectingOverlappingCommunitiesAlgorithm.java index 45297076..9177bbba 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/DetectingOverlappingCommunitiesAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/DetectingOverlappingCommunitiesAlgorithm.java @@ -5,8 +5,6 @@ import i5.las2peer.services.ocd.graphs.CoverCreationType; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.Node; import java.util.ArrayList; import java.util.HashMap; @@ -17,6 +15,10 @@ import org.la4j.matrix.Matrix; import org.la4j.matrix.dense.Basic2DMatrix; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + /** * This class is an implementation of the algorithm by Nam P. Nguyen, Thang N. Dinh, Dung T. Nguyen, My T. Thai: * Overlapping community structures and their detection on social networks @@ -120,7 +122,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) public Matrix getMembershipMatrix(CustomGraph graph) { //DEBUG System.out.println(communities); - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), communities.size()); + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), communities.size()); int j=0; for(Map.Entry> communityPair : communities.entrySet()) { @@ -149,17 +151,17 @@ public Matrix getMembershipMatrix(CustomGraph graph) { */ public void findOverlappingCommunityStructures(CustomGraph graph) throws OcdAlgorithmException, InterruptedException { communityIntersections = new ArrayList(); // initialize communityIntersections - nodeDegrees = new HashMap(graph.nodeCount()); - adjacencyList = new HashMap>(graph.nodeCount()); - for(Node node : graph.getNodeArray()) {// Initialize nodeDegree, maxDegree, AdjacencyList + nodeDegrees = new HashMap(graph.getNodeCount()); + adjacencyList = new HashMap>(graph.getNodeCount()); + for(Node node : graph.nodes().toArray(Node[]::new)) {// Initialize nodeDegree, maxDegree, AdjacencyList Set neighbours = graph.getNeighbours(node); - nodeDegrees.put(node.index(), neighbours.size()); + nodeDegrees.put(node.getIndex(), neighbours.size()); - maxDegree = Math.max(maxDegree, nodeDegrees.get(node.index())); + maxDegree = Math.max(maxDegree, nodeDegrees.get(node.getIndex())); - adjacencyList.put(node.index(), new ArrayList(neighbours.size())); + adjacencyList.put(node.getIndex(), new ArrayList(neighbours.size())); for(Node neighbour : neighbours) { - adjacencyList.get(node.index()).add(neighbour.index()); + adjacencyList.get(node.getIndex()).add(neighbour.getIndex()); } } @@ -177,10 +179,10 @@ public void findOverlappingCommunityStructures(CustomGraph graph) throws OcdAlgo */ public void findDenseCommunities(CustomGraph graph) throws OcdAlgorithmException, InterruptedException { // initialize nodeCommunities, communityNumbers, intersectionCounters - communityNumbers = new ArrayList(graph.nodeCount()); + communityNumbers = new ArrayList(graph.getNodeCount()); intersectionCounters = new HashMap(); - nodeCommunities = new HashMap>(graph.nodeCount()); - for(int i=0; i<=graph.nodeCount(); i++) { // initially, each node has one community ID, TODO: i was 1 first, check if this breaks anything + nodeCommunities = new HashMap>(graph.getNodeCount()); + for(int i=0; i<=graph.getNodeCount(); i++) { // initially, each node has one community ID, TODO: i was 1 first, check if this breaks anything nodeCommunities.put(i, new HashMap()); communityNumbers.add(0); } @@ -191,10 +193,10 @@ public void findDenseCommunities(CustomGraph graph) throws OcdAlgorithmException communityEdgeSizes = new HashMap(); int numEdge=0; - for(Edge edge : graph.getEdgeArray()) { // reading from the beginning of file - if (!sameCommunity(edge.source().index(), edge.target().index())) + for(Edge edge : graph.edges().toArray(Edge[]::new)) { // reading from the beginning of file + if (!sameCommunity(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex())) { // if a and b are not in a community together - tryFormingNewCommunity(edge.source().index(), edge.target().index(), graph); // try to form a dense local community from (a,b) + tryFormingNewCommunity(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), graph); // try to form a dense local community from (a,b) } if(Thread.interrupted()) { throw new InterruptedException(); @@ -372,7 +374,7 @@ public int findCommunityAdjacencyList(int comA, HashMap commun updateCounter(); // update the counter for(i=0; i graph.nodeCount() || x <0) { //TODO: was <= 0, see if this changes anything + if (x > graph.getNodeCount() || x <0) { //TODO: was <= 0, see if this changes anything throw new OcdAlgorithmException("Error: x > N || x <0 in findComAdjList: " + x + " " + communities.get(comA)); } if (communityNumbers.get(x) < 2) { // skip x if it is in just one community @@ -625,14 +627,14 @@ public void findCommunityIntersection(int comA, int comB) { */ public void findTinyCommunities(CustomGraph graph) throws OcdAlgorithmException { realCommunityCount = communityCount; - for(Edge edge : graph.getEdgeArray()) { // Read the adjacent list to find N and M - if ( communityNumbers.get(edge.source().index())>0 || communityNumbers.get(edge.target().index())>0 ) { + for(Edge edge : graph.edges().toArray(Edge[]::new)) { // Read the adjacent list to find N and M + if ( communityNumbers.get(edge.getSourceNode().getIndex())>0 || communityNumbers.get(edge.getTargetNode().getIndex())>0 ) { continue; } - findNodeIntersection(edge.source().index(), edge.target().index(), graph); // Find the intersection of the two adjacencyLists + findNodeIntersection(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), graph); // Find the intersection of the two adjacencyLists if (nodeIntersectionCounter == 3) { // If we find a triangle - if (communityCount >= graph.nodeCount()) { // If communityCount exceeds the upper bound, return error - throw new OcdAlgorithmException("Error : numCOM >= MULTI_N in findTinyCommunities()" + " " + communities.size() + " " + graph.nodeCount() + "\n" + communities); + if (communityCount >= graph.getNodeCount()) { // If communityCount exceeds the upper bound, return error + throw new OcdAlgorithmException("Error : numCOM >= MULTI_N in findTinyCommunities()" + " " + communities.size() + " " + graph.getNodeCount() + "\n" + communities); } markNodes(communityCount + 1); // Mark all the nodes in the intersection communityCount++; @@ -663,7 +665,7 @@ public void visitUnAssignedVertices(CustomGraph graph) throws OcdAlgorithmExcept maxOutliers = 0; // The number of outliers findNumDegList(numDegList); // Find the numDegList; oldCommunityNodeSizes = new HashMap(communityNodeSizes); - for(i=0; i 0) { continue; } @@ -701,7 +703,7 @@ public void visitUnAssignedVertices(CustomGraph graph) throws OcdAlgorithmExcept } } //finalRefinement(oldCommunityNodeSizes, graph); // Final refinement TODO: Remove - for(i=1;i<=graph.nodeCount();i++) { + for(i=1;i<=graph.getNodeCount();i++) { maxCommunityNumber = Math.max( maxCommunityNumber, communityNumbers.get(i) ); } for(i=1;i<=communityCount;i++) { @@ -745,7 +747,7 @@ private int findTau(int n, CustomGraph graph) throws OcdAlgorithmException { // if (n <= 3) { // if we dont have enough nodes return 0; } - if (n > graph.nodeCount()) { // if the number of nodes gets too large + if (n > graph.getNodeCount()) { // if the number of nodes gets too large throw new OcdAlgorithmException("Error: Counter too large for findTau"); } int pn = n*(n-1)/2; // since we have a safety check above, this step should not be a problem diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/EvolutionaryAlgorithmBasedOnSimilarity.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/EvolutionaryAlgorithmBasedOnSimilarity.java index bc256d13..287c0f28 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/EvolutionaryAlgorithmBasedOnSimilarity.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/EvolutionaryAlgorithmBasedOnSimilarity.java @@ -1,36 +1,23 @@ package i5.las2peer.services.ocd.algorithms; import java.io.File; -//import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.algorithms.mea.MeaAlgorithm; -import org.apache.commons.exec.CommandLine; -import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.DefaultExecutor; -import org.apache.commons.lang3.SystemUtils; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import java.util.Scanner; - import i5.las2peer.services.ocd.algorithms.utils.OcdAlgorithmException; -import i5.las2peer.services.ocd.benchmarks.OcdBenchmarkException; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CoverCreationType; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; + +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements the algorithm by C. Liu, J. Liu, and Z. Jiang: @@ -38,8 +25,8 @@ * https://doi.org/10.1109/TCYB.2014.2305974 * @author YLi */ +//TODO: Rework this algorithm implementation so that it doesn't need to produce pajek files anymore, they are an unnecessary extra step public class EvolutionaryAlgorithmBasedOnSimilarity implements OcdAlgorithm { - /** * Path of the directory reserved for the application. */ @@ -100,20 +87,19 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithm * the network file to have the index 1. If not, the input file * should be adapted. */ - NodeCursor nodes = graph.nodes(); + Iterator nodes = graph.iterator(); Node node; int count = 0; - while (nodes.ok()) { - node = nodes.node(); + while (nodes.hasNext()) { + node = nodes.next(); if (count == 0) { - minNodeIndex = node.index(); + minNodeIndex = node.getIndex(); } else { - if (node.index() < minNodeIndex) { - minNodeIndex = node.index(); + if (node.getIndex() < minNodeIndex) { + minNodeIndex = node.getIndex(); } } count++; - nodes.next(); } writeNetworkFile(graph); @@ -124,7 +110,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithm }catch(Exception e){} - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); Matrix membershipMatrix = translateCommunityFile(LastResultPath, nodeCount); Cover cover = new Cover(graph, membershipMatrix); return cover; @@ -153,26 +139,25 @@ protected void writeNetworkFile(CustomGraph graph) throws IOException, Interrupt try { networkFile.write(String.format("*Vertices ")); networkFile.write("\t"); - networkFile.write(Integer.toString(graph.nodeCount())); + networkFile.write(Integer.toString(graph.getNodeCount())); networkFile.write(System.lineSeparator()); networkFile.write(String.format("*Edges")); networkFile.write(System.lineSeparator()); - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - if (edge.source().index() <= edge.target().index()) { - networkFile.write(Integer.toString(edge.source().index() + (1 - minNodeIndex)));// networkFile.write(Integer.toString(edge.source().index()+1)); + edge = edges.next(); + if (edge.getSourceNode().getIndex() <= edge.getTargetNode().getIndex()) { + networkFile.write(Integer.toString(edge.getSourceNode().getIndex() + (1 - minNodeIndex)));// networkFile.write(Integer.toString(edge.getSourceNode().getIndex()+1)); networkFile.write("\t"); - networkFile.write(Integer.toString(edge.target().index() + (1 - minNodeIndex)));// networkFile.write(Integer.toString(edge.source().index()+1)); + networkFile.write(Integer.toString(edge.getTargetNode().getIndex() + (1 - minNodeIndex)));// networkFile.write(Integer.toString(edge.getSourceNode().getIndex()+1)); networkFile.write("\t"); networkFile.write(Double.toString(graph.getEdgeWeight(edge))); networkFile.write(System.lineSeparator()); } - edges.next(); } } finally { networkFile.close(); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ExtendedSpeakerListenerLabelPropagationAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ExtendedSpeakerListenerLabelPropagationAlgorithm.java index 704f31d1..318044e9 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ExtendedSpeakerListenerLabelPropagationAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/ExtendedSpeakerListenerLabelPropagationAlgorithm.java @@ -24,8 +24,9 @@ import org.la4j.vector.Vector; import org.la4j.vector.sparse.CompressedVector; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements a custom extended version of the original Speaker Listener Label Propagation Algorithm by J. Xie, B. K. Szymanski, and X. Liu: @@ -138,12 +139,12 @@ public Cover detectOverlappingCommunities( List memory; for(int t=0; t+1> memories, List nodeOrder) throws InterruptedException { List memory; - for(int i=0; i(); memory.add(i); memories.add(memory); - nodeOrder.add(graph.getNodeArray()[i]); + nodeOrder.add(nodeArray[i]); } } @@ -173,15 +175,15 @@ protected void initializeCommunityDetection(CustomGraph graph, List> memories, Node listener) { + protected int getNextLabel(CustomGraph graph, List> memories, Node listener) throws InterruptedException { Map receivedLabels = new HashMap(); - NodeCursor speakers = listener.successors(); + Iterator speakersIt = graph.getSuccessorNeighbours(listener).iterator(); Node speaker; - while(speakers.ok()) { - speaker = speakers.node(); - receivedLabels.put(speaker, speakerRule.getLabel(graph, speaker, memories.get(speaker.index()))); - speakers.next(); + while(speakersIt.hasNext()) { + speaker = speakersIt.next(); + receivedLabels.put(speaker, speakerRule.getLabel(graph, speaker, memories.get(speaker.getIndex()))); } return listenerRule.getLabel(graph, listener, receivedLabels); } @@ -216,7 +218,7 @@ protected Cover calculateMembershipDegrees(CustomGraph graph, List /* * Adapts matrix size for new communities. */ - membershipMatrix = membershipMatrix.resize(graph.nodeCount(), nodeMembershipDegrees.length()); + membershipMatrix = membershipMatrix.resize(graph.getNodeCount(), nodeMembershipDegrees.length()); } membershipMatrix.setRow(i, nodeMembershipDegrees); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/FuzzyCMeansSpectralClusteringAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/FuzzyCMeansSpectralClusteringAlgorithm.java index b691ba1c..6824f0da 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/FuzzyCMeansSpectralClusteringAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/FuzzyCMeansSpectralClusteringAlgorithm.java @@ -15,12 +15,7 @@ import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.metrics.OcdMetricException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.ml.clustering.CentroidCluster; @@ -29,8 +24,9 @@ import org.apache.commons.math3.random.JDKRandomGenerator; import org.la4j.decomposition.EigenDecompositor; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** @@ -234,9 +230,9 @@ public Cover detectOverlappingCommunities(CustomGraph graph) new_modularity = modularityFunction(new_membership_matrix, A, customThreshold); - System.out.println("modularity with K = " + i + " and custom threshold = " + customThreshold - + " : " + new_modularity); - System.out.println(); +// System.out.println("modularity with K = " + i + " and custom threshold = " + customThreshold +// + " : " + new_modularity); +// System.out.println(); // if modularity of some cluster size is better that modularity value of cluster // sizes seen before, set that cluster size as optimal @@ -258,8 +254,8 @@ public Cover detectOverlappingCommunities(CustomGraph graph) modularity = modularityFunction(membership_matrix, A, customThreshold); - System.out.println("modularity without optimizing cluster quantity and with K = " + K - + " and custom threshold = " + customThreshold + " is " + modularity); +// System.out.println("modularity without optimizing cluster quantity and with K = " + K +// + " and custom threshold = " + customThreshold + " is " + modularity); } @@ -292,8 +288,8 @@ public Cover detectOverlappingCommunities(CustomGraph graph) // Calculate modularity function output for the clusters found above new_modularity = modularityFunction(new_membership_matrix, A); - System.out.println("modularity with K = " + i + " is " + new_modularity); - System.out.println(); +// System.out.println("modularity with K = " + i + " is " + new_modularity); +// System.out.println(); // if modularity of some cluster size is better than modularity value of cluster // sizes seen before, set that cluster size as optimal @@ -316,7 +312,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) modularity = modularityFunction(membership_matrix, A); - System.out.println("modularity without optimizing cluster quantity and K = " + K + " is " + modularity); +// System.out.println("modularity without optimizing cluster quantity and K = " + K + " is " + modularity); } @@ -327,8 +323,8 @@ public Cover detectOverlappingCommunities(CustomGraph graph) // build the cover using the input graph and the membership matrix built above resulting_cover = new Cover(graph,membership_matrix); - System.out.println("================== CHOSEN SOLUTION ====================="); - System.out.println("Optimal K is: " + optimal_K + " optimal modularity is: " + modularity); +// System.out.println("================== CHOSEN SOLUTION ====================="); +// System.out.println("Optimal K is: " + optimal_K + " optimal modularity is: " + modularity); return resulting_cover; @@ -365,20 +361,17 @@ public Set compatibleGraphTypes() { */ public Matrix createAdjacencyMatrix(CustomGraph graph) { - Matrix A = new Basic2DMatrix(graph.nodeCount(), graph.nodeCount()); + Matrix A = new Basic2DMatrix(graph.getNodeCount(), graph.getNodeCount()); A = A.blank(); // create an empty matrix of size n - EdgeCursor edge_list = graph.edges(); // added + Iterator edge_list = graph.edges().iterator(); // added - while (edge_list.ok()) { + while (edge_list.hasNext()) { - Edge edge = edge_list.edge(); + Edge edge = edge_list.next(); - A.set(edge.source().index(), edge.target().index(), graph.getEdgeWeight(edge)); - - edge_list.next(); - + A.set(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), graph.getEdgeWeight(edge)); } return A; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithm.java new file mode 100644 index 00000000..d76f1920 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithm.java @@ -0,0 +1,450 @@ +package i5.las2peer.services.ocd.algorithms; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Iterator; + +import i5.las2peer.services.ocd.algorithms.OcdAlgorithm; +import org.graphstream.graph.Node; +import org.la4j.matrix.Matrix; +import org.la4j.matrix.dense.Basic2DMatrix; + +import i5.las2peer.services.ocd.algorithms.utils.MaximalCliqueSearch; +import i5.las2peer.services.ocd.algorithms.utils.OcdAlgorithmException; +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.CoverCreationType; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.graphs.GraphType; + + +/** + * Implementation of the Local Optimization Algorithm based on Cliques by Jian Ma and Jianping: + * Local Optimization for Clique-Based Overlapping Community Detection in Complex Networks + * https://doi.org/10.1109/ACCESS.2019.2962751 + */ + +public class LOCAlgorithm implements OcdAlgorithm { + + /** + Parameter to control the size of a community. The larger the value of alpha, + the smaller the community size is. + The default value is 1. Must be greater than 0. + */ + private double alpha = 1.0; + /** + A value to determine the size of the used k-cliques. + The default value is 3. Must be at least 3. + Recommended are values between 3 and 6. + */ + private int k = 3; + /** + The cutoff distance that determines the local density of a node. + The default value is 1. Must be at least 1. + Recommended are values between 1 and 3. + */ + private int dc = 1; + + /* + * PARAMETER NAMES + */ + + protected static final String ALPHA_NAME = "alpha"; + + protected static final String K_NAME = "k"; + + protected static final String DC_NAME = "dc"; + + + /** + * Creates a standard instance of the algorithm. + * All attributes are assigned their default values. + */ + public LOCAlgorithm() { + } + + @Override + public CoverCreationType getAlgorithmType() { + return CoverCreationType.LOC_ALGORITHM; + } + + @Override + public Set compatibleGraphTypes() { + Set compatibilities = new HashSet(); + return compatibilities; + } + @Override + public Map getParameters() { + Map parameters = new HashMap(); + parameters.put(ALPHA_NAME, Double.toString(alpha)); + parameters.put(K_NAME, Integer.toString(k)); + parameters.put(DC_NAME, Integer.toString(dc)); + return parameters; + } + + @Override + public void setParameters(Map parameters) throws IllegalArgumentException { + if(parameters.containsKey(ALPHA_NAME)) { + alpha = Double.parseDouble(parameters.get(ALPHA_NAME)); + if(alpha <= 0) { + throw new IllegalArgumentException("alpha must be greater than 0"); + } + parameters.remove(ALPHA_NAME); + } + if(parameters.containsKey(K_NAME)) { + k = Integer.parseInt(parameters.get(K_NAME)); + if(k < 3) { + throw new IllegalArgumentException("k must be at least 3"); + } + parameters.remove(K_NAME); + } + if(parameters.containsKey(DC_NAME)) { + dc = Integer.parseInt(parameters.get(DC_NAME)); + if(dc < 1) { + throw new IllegalArgumentException("dc must be at least 1"); + } + parameters.remove(DC_NAME); + } + if (parameters.size() > 0) { + throw new IllegalArgumentException("Too many input parameters!"); + } + } + + @Override + public Cover detectOverlappingCommunities(CustomGraph graph)throws OcdAlgorithmException, InterruptedException { + //gives every node its local density value + HashMap localDensityMap = getLocalDensityMap(graph); + //calculates the cliques of size at least k + HashMap> cliques = getCliques(graph); + + //Variables + Set> communitys = new HashSet>(); + Set cluster = new HashSet(); + Set neighbors = new HashSet(); + Node maxLocalDensityNode = null; + double maxNodeFitness = Double.NEGATIVE_INFINITY; + double currentNodeFitness; + Node fittestNode = null; + boolean negativeNodeExist = true; + int terminierungLD = graph.getNodeCount() + 5; + int terminierungNeighbors = graph.getNodeCount() + 5; + + while(!localDensityMap.isEmpty()) { + + //Save termination + terminierungLD--; // termination variable (not important) + if (terminierungLD <0) { + System.out.println("LOC Algorithm only terminated because of termination variable"); + break; + } + //Start iteration with fresh cluster + cluster.clear(); + + maxLocalDensityNode = getMaxValueNode(localDensityMap); + + cluster.add(maxLocalDensityNode); + terminierungNeighbors = graph.getNodeCount() + 1; + while(terminierungNeighbors > 0) { // while(true) should also work + terminierungNeighbors--; // termination variable (not important) + neighbors = getClusterNeighbors(cluster, localDensityMap, graph); + if(neighbors.isEmpty()) { + //remove nodes in clique from localDensityMap + for (Node clusterNode : cluster) { + if(localDensityMap.containsKey(clusterNode)) { + localDensityMap.remove(clusterNode); + } + } + //add the node cluster to found communities + addClusterToCommunitys(communitys, cluster); + break; + + } + else { + //find neighbor node with highest fitness value + maxNodeFitness = Double.NEGATIVE_INFINITY; + currentNodeFitness = maxNodeFitness; + for(Node neighbor : neighbors) { + currentNodeFitness = getNodeFitness(neighbor, cluster, graph); + if(currentNodeFitness > maxNodeFitness) { + fittestNode = neighbor; + maxNodeFitness = currentNodeFitness; + } + } + if(maxNodeFitness >= 0) { //chosen node and the cliques it belongs to are added to the cluster + cluster.add(fittestNode); + addCliqueNodesToCluster(fittestNode, cluster, cliques); + + negativeNodeExist = true; + while(negativeNodeExist) { //remove nodes with negative fitnessvalue + //Thread handler ? + if(Thread.interrupted()) { + throw new InterruptedException(); + } + negativeNodeExist = false; + for(Node node : cluster) { + if(getNodeFitness(node, cluster, graph) < 0) { + //Step 7 + cluster.remove(node); + negativeNodeExist = true; + break; + } + } + + } + + } + else { + //remove nodes in clique from localDensityMap + for (Node clusterNode : cluster) { + if(localDensityMap.containsKey(clusterNode)) { + localDensityMap.remove(clusterNode); + } + } + addClusterToCommunitys(communitys, cluster); + break; + } + } + } + + } + Matrix membershipMatrix = getMemberships(communitys, graph); + return new Cover(graph, membershipMatrix); + } + + + + /** + * Calculates the local density value for every node in the network + * @param graph The graph being analyzed + * @return A map of every node and its local density value + * @throws InterruptedException when the method execution is interrupted + */ + public HashMap getLocalDensityMap(CustomGraph graph) throws InterruptedException { + //TODO optimize funktion for dc=1 + Matrix[] m = new Matrix[dc]; + + m[0] = graph.getNeighbourhoodMatrix(); + + //get identity Matrix + Matrix result = identity(m[0].rows()); + + //claculate matix from 0 to dc + for (int i = 1; i<=dc-1; i++) { + m[i] = m[i-1].multiply(m[0]); + } + + for (Matrix matrix : m) { + result = result.add(matrix); + } + + HashMap ldm = new HashMap(); + + int sum = 0; + int nodenumber = 0; + for (Node node : graph.nodes().toArray(Node[]::new)) { + if(Thread.interrupted()) { + throw new InterruptedException(); + } + for(int i = 0; i < result.columns(); i++){ + if (result.get(nodenumber, i) > 0){ + sum += 1; + } + } + ldm.put(node, sum); + nodenumber += 1; + sum = 0; + } + return ldm; + } + + /** + * Calculates the neighbors of a cluster. + * A node n is added to the output iff the following conditions hold: + * There is an edge from a node in the cluster set to n AND + * n does not belong to the cluster AND + * n is a node that is listed in the localDensityMap (is not assigned to a community yet) + * @param cluster The Set of nodes from which the function determines the neighbors + * @param localDensityMap A Map of nodes and local density values, where the nodes have not yet been added to a final community + * @param graph The graph being analyzed + * @throws InterruptedException when the method execution is interrupted + * @return A Set of nodes + */ + public Set getClusterNeighbors(Set cluster, HashMap localDensityMap, CustomGraph graph) throws InterruptedException{ + Set neighbours = new HashSet(); + for(Node clusterNode : cluster) { + Iterator successorsIt = graph.getSuccessorNeighbours(clusterNode).iterator(); + while (successorsIt.hasNext()) { + Node neighbourNode = successorsIt.next(); + if(!cluster.contains(neighbourNode) && localDensityMap.containsKey(neighbourNode)) { + neighbours.add(neighbourNode); + } + } + } + return neighbours; + } + + /** + * Calculates the Set of all cliques, that have at least the size of this algorithms parameter k. + * @param graph The graph being analyzed + * throws InterruptedException when the method execution is interrupted + * @return A Map with an ID and a Set of nodes + */ + public HashMap> getCliques(CustomGraph graph) throws InterruptedException { + + MaximalCliqueSearch maxCliqueSearch = new MaximalCliqueSearch(); + HashMap> cliques = maxCliqueSearch.cliques(graph); + Iterator iterator = cliques.keySet().iterator(); + int i; + while(iterator.hasNext()) { + i = (int)iterator.next(); + if(cliques.get(i).size() < k) { + iterator.remove(); + } + } + return cliques; + } + + /** + * The function finds all cliques in which the node "fittestNode" is a member. + * Then it adds all the nodes which are a member of these cliques to the cluster. + * @param fittestNode The node with the highest fitness value in respect to the cluster + * @param cluster A set of nodes on which nodes will be added + * @param cliques A map of IDs and a Set of nodes + */ + public void addCliqueNodesToCluster(Node fittestNode, Set cluster, HashMap> cliques) { + HashSet clique; + for(int i : cliques.keySet()) { + clique = cliques.get(i); + if(clique.contains(fittestNode)) { + for(Node node : clique) { + cluster.add(node); + } + } + } + } + + /** + * Calculates the fitness value of a node in respect to the cluster. + * @param node The node we want to get the fitness value from + * @param originalCluster A set of nodes + * @param graph The graph being analyzed + * @return A map of every node and its local density value + * @throws InterruptedException when the method execution is interrupted + */ + public double getNodeFitness(Node node, Set originalCluster, CustomGraph graph) throws InterruptedException { + //TODO possible without to copy ? + + Set cluster = new HashSet(); + for(Node n : originalCluster) { + cluster.add(n); + } + + cluster.remove(node); + double fitnessWithoutNode = getFitness(cluster, graph); // fitness of the cluster WITHOUT the node + cluster.add(node); + double fitnessWithNode = getFitness(cluster, graph); // fitness of the cluster WITH the node + + return fitnessWithNode - fitnessWithoutNode; + } + + /** + * Calculates the fitness value of a cluster. + * @param cluster A set of nodes + * @param graph The graph being analyzed + * @return The fitness value + */ + public double getFitness(Set cluster, CustomGraph graph) throws InterruptedException { + double k_in = (double)getKIn(cluster, graph); + double edgeCount = (double)getClusterEdgeCount(cluster, graph); + return (k_in)/Math.pow(edgeCount, alpha); + } + + public int getKIn(Set cluster, CustomGraph graph) throws InterruptedException { + int sum = 0; + Node node; + for (Node clusterNode : cluster) { + //K_in : 2 times number of all edges in the cluster + Iterator successorsIt = graph.getSuccessorNeighbours(clusterNode).iterator(); + while (successorsIt.hasNext()) { + node = successorsIt.next(); + if(cluster.contains(node)) {sum++;} + } + } + return sum; + } + + public int getClusterEdgeCount(Set cluster, CustomGraph graph) { + int sum = 0; + for (Node node : cluster) { //(K_in +K_out) from paper is computed together + sum += node.getOutDegree(); + } + return sum; + } + + + + /** + * Determines the membership matrix with a set of communities. + * @param communitys A set of all communities that were found + * @param graph The graph being analyzed + * @return The membership matrix + */ + + public Matrix getMemberships(Set> communitys, CustomGraph graph) { + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), communitys.size()); + int i = 0; + for(Set community : communitys) { + for (Node node : community) { + membershipMatrix.set(node.getIndex(), i , 1); + } + i++; + } + return membershipMatrix; + } + + /** + * Adds the cluster as one community to the set of communities. + * @param communitys A set of communities that has to be filled + * @param cluster A set of nodes + */ + public void addClusterToCommunitys(Set> communitys, Set cluster) { + Set community = new HashSet(); + for (Node node : cluster) { + community.add(node); + } + communitys.add(community); + } + + /** + * Finds the node from the map to which the highest value was assigned. + * @param map A map of nodes and an associated value + * @return The node with the highest value + * @throws IllegalArgumentException when the given map is empty + */ + public Node getMaxValueNode(HashMap map) throws IllegalArgumentException{ + if (map.isEmpty()){ + throw new IllegalArgumentException("HashMap is empty"); + } + Set set = map.keySet(); + Node ret = set.iterator().next(); + int maxValueInMap = map.get(ret); //return max value in the Hashmap + for (Node key : set) { + if (map.get(key) > maxValueInMap) { + maxValueInMap = map.get(key); + ret = key; + } + } + return ret; + } + + //Bibliothek sollte das tun + private Basic2DMatrix identity(int size) { + double[][] array = new double[size][size]; + for (int i = 0; i < size; i++) { + array[i][i] = 1; + } + return new Basic2DMatrix(array); + } + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LinkCommunitiesAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LinkCommunitiesAlgorithm.java index fb216e70..e700f0f1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LinkCommunitiesAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LinkCommunitiesAlgorithm.java @@ -6,14 +6,8 @@ import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.utils.Pair; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; @@ -21,10 +15,9 @@ import org.la4j.vector.Vectors; import org.la4j.vector.sparse.CompressedVector; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * The original standard version of the Link Communities Algorithm by Y.-Y. Ahn, J. P. Bagrow, and S. Lehmann: @@ -134,63 +127,60 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws InterruptedE } private Matrix calculateEdgeSimilarities(CustomGraph graph, List linkageDegrees) throws InterruptedException { - Matrix similarities = new CCSMatrix(graph.edgeCount(), graph.edgeCount()); - EdgeCursor rowEdges = graph.edges(); + Matrix similarities = new CCSMatrix(graph.getEdgeCount(), graph.getEdgeCount()); + Iterator rowEdgesIt = graph.edges().iterator(); Edge rowEdge; Node source; Node target; List edgeIndices = new ArrayList(); - EdgeCursor columnEdges; + Iterator columnEdges; Edge columnEdge; Edge reverseRowEdge; Edge reverseColumnEdge; double similarity; - while(rowEdges.ok()) { + while(rowEdgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - rowEdge = rowEdges.edge(); - source = rowEdge.source(); - target = rowEdge.target(); - reverseRowEdge = target.getEdgeTo(source); + rowEdge = rowEdgesIt.next(); + source = rowEdge.getSourceNode(); + target = rowEdge.getTargetNode(); + reverseRowEdge = target.getEdgeToward(source); /* * Sets similarities only if they have not been set already for the reverse Edge. */ - if(reverseRowEdge == null || rowEdge.index() < reverseRowEdge.index()) { + if(reverseRowEdge == null || rowEdge.getIndex() < reverseRowEdge.getIndex()) { /* * Sets similarities for in and out edges of the row edge target node. */ - edgeIndices.add(rowEdge.index()); - columnEdges = target.edges(); - while(columnEdges.ok()) { - columnEdge = columnEdges.edge(); - if(columnEdge.index() < rowEdge.index()) { - reverseColumnEdge = columnEdge.target().getEdgeTo(columnEdge.source()); - if(reverseColumnEdge == null || columnEdge.index() < reverseColumnEdge.index()) { - similarity = getSimpleSimilarity(source, columnEdge.opposite(target)); - similarities.set(rowEdge.index(), columnEdge.index(), similarity); + edgeIndices.add(rowEdge.getIndex()); + columnEdges = target.edges().iterator(); + while(columnEdges.hasNext()) { + columnEdge = columnEdges.next(); + if(columnEdge.getIndex() < rowEdge.getIndex()) { + reverseColumnEdge = columnEdge.getTargetNode().getEdgeToward(columnEdge.getSourceNode()); + if(reverseColumnEdge == null || columnEdge.getIndex() < reverseColumnEdge.getIndex()) { + similarity = getSimpleSimilarity(graph, source, columnEdge.getOpposite(target)); + similarities.set(rowEdge.getIndex(), columnEdge.getIndex(), similarity); } } - columnEdges.next(); } /* * Sets similarities for in edges of the row edge source node. * If a reverse edge of the row edge exists, it is set for the out edges also. */ - columnEdges = source.edges(); - while(columnEdges.ok()) { - columnEdge = columnEdges.edge(); - if(columnEdge.index() < rowEdge.index() && columnEdge.source() != target) { - reverseColumnEdge = columnEdge.target().getEdgeTo(columnEdge.source()); - if(reverseColumnEdge == null || columnEdge.index() < reverseColumnEdge.index()) { - similarity = getSimpleSimilarity(target, columnEdge.opposite(source)); - similarities.set(rowEdge.index(), columnEdge.index(), similarity); + columnEdges = source.edges().iterator(); + while(columnEdges.hasNext()) { + columnEdge = columnEdges.next(); + if(columnEdge.getIndex() < rowEdge.getIndex() && columnEdge.getSourceNode() != target) { + reverseColumnEdge = columnEdge.getTargetNode().getEdgeToward(columnEdge.getSourceNode()); + if(reverseColumnEdge == null || columnEdge.getIndex() < reverseColumnEdge.getIndex()) { + similarity = getSimpleSimilarity(graph, target, columnEdge.getOpposite(source)); + similarities.set(rowEdge.getIndex(), columnEdge.getIndex(), similarity); } } - columnEdges.next(); } } - rowEdges.next(); } int[] indices = new int[edgeIndices.size()]; for(int i=0; i linkage */ private List calculateLinkageDegrees(CustomGraph graph) throws InterruptedException { List linkageDegrees = new ArrayList(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Vector degreeVector; Node node; Node neighbor; - EdgeCursor edges; + Iterator edgesIt; Edge edge; double linkageDegree; double neutral; double averageWeight; - while(nodes.ok()) { - degreeVector = new CompressedVector(graph.nodeCount()); - node = nodes.node(); - edges = node.edges(); - while(edges.ok()) { + while(nodesIt.hasNext()) { + degreeVector = new CompressedVector(graph.getNodeCount()); + node = nodesIt.next(); + edgesIt = node.edges().iterator(); + while(edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - neighbor = edges.edge().opposite(node); - linkageDegree = degreeVector.get(neighbor.index()); - linkageDegree += graph.getEdgeWeight(edge) / node.degree(); - degreeVector.set(neighbor.index(), linkageDegree); - edges.next(); + edge = edgesIt.next(); + neighbor = edge.getOpposite(node); + linkageDegree = degreeVector.get(neighbor.getIndex()); + linkageDegree += graph.getEdgeWeight(edge) / node.getDegree(); + degreeVector.set(neighbor.getIndex(), linkageDegree); } /* * Calculates the entry corresponding the node index as the average weight @@ -244,9 +233,8 @@ private List calculateLinkageDegrees(CustomGraph graph) throws Interrupt */ neutral = 0; averageWeight = degreeVector.fold(Vectors.asSumAccumulator(neutral)); - degreeVector.set(node.index(), averageWeight); + degreeVector.set(node.getIndex(), averageWeight); linkageDegrees.add(degreeVector); - nodes.next(); } return linkageDegrees; } @@ -372,18 +360,18 @@ private Matrix updateSimilarities(Matrix similarities, Pair mo */ private void initDendrogramCreation(CustomGraph graph, List> communityEdges, List> communityNodes, List communityLinkDensities) throws InterruptedException { - EdgeCursor edges = graph.edges(); + Iterator edgesIt = graph.edges().iterator(); Set initEdgeSet; Set initNodeSet; Edge edge; Edge reverseEdge; - while(edges.ok()) { + while(edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - reverseEdge = edge.target().getEdgeTo(edge.source()); - if(reverseEdge == null || edge.index() < reverseEdge.index()) { + edge = edgesIt.next(); + reverseEdge = edge.getTargetNode().getEdgeToward(edge.getSourceNode()); + if(reverseEdge == null || edge.getIndex() < reverseEdge.getIndex()) { initEdgeSet = new HashSet(); initEdgeSet.add(edge); if(reverseEdge != null) { @@ -391,12 +379,11 @@ private void initDendrogramCreation(CustomGraph graph, List> community } communityEdges.add(initEdgeSet); initNodeSet = new HashSet(); - initNodeSet.add(edge.source()); - initNodeSet.add(edge.target()); + initNodeSet.add(edge.getSourceNode()); + initNodeSet.add(edge.getTargetNode()); communityNodes.add(initNodeSet); communityLinkDensities.add(0d); } - edges.next(); } } @@ -418,7 +405,7 @@ private double calculateLinkDensity(int edgeCount, int nodeCount) { * @return A normalized cover of the graph. */ private Cover calculatePartitionCover(CustomGraph graph, List> partition) throws InterruptedException { - Matrix memberships = new CCSMatrix(graph.nodeCount(), partition.size()); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), partition.size()); double belongingFactor; double edgeWeight; for(int i=0; i> partiti throw new InterruptedException(); } edgeWeight = graph.getEdgeWeight(edge); - belongingFactor = memberships.get(edge.target().index(), i) + edgeWeight; - memberships.set(edge.target().index(), i, belongingFactor); - belongingFactor = memberships.get(edge.source().index(), i) + edgeWeight; - memberships.set(edge.source().index(), i, belongingFactor); + belongingFactor = memberships.get(edge.getTargetNode().getIndex(), i) + edgeWeight; + memberships.set(edge.getTargetNode().getIndex(), i, belongingFactor); + belongingFactor = memberships.get(edge.getSourceNode().getIndex(), i) + edgeWeight; + memberships.set(edge.getSourceNode().getIndex(), i, belongingFactor); } } return new Cover(graph, memberships); } - private double getSimpleSimilarity(Node nodeA, Node nodeB) { + private double getSimpleSimilarity(CustomGraph graph, Node nodeA, Node nodeB) throws InterruptedException { Set commonNeighbors = new HashSet(); Set totalNeighbors = new HashSet(); - if(nodeB.getEdgeTo(nodeA) != null) { + if(nodeB.getEdgeToward(nodeA) != null) { commonNeighbors.add(nodeA); commonNeighbors.add(nodeB); } @@ -448,23 +435,21 @@ private double getSimpleSimilarity(Node nodeA, Node nodeB) { /* * Check nodeA neighbors. */ - NodeCursor neighbors = nodeA.neighbors(); + Iterator neighborsIt = graph.getNeighbours(nodeA).iterator(); Node neighbor; - while(neighbors.ok()) { - neighbor = neighbors.node(); - if(neighbor.getEdge(nodeB) != null) { + while(neighborsIt.hasNext()) { + neighbor = neighborsIt.next(); + if(neighbor.getEdgeBetween(nodeB) != null) { commonNeighbors.add(neighbor); } totalNeighbors.add(neighbor); - neighbors.next(); } /* * Checks nodeB neighbors. */ - neighbors = nodeB.neighbors(); - while(neighbors.ok()) { - totalNeighbors.add(neighbors.node()); - neighbors.next(); + neighborsIt = graph.getNeighbours(nodeB).iterator(); + while(neighborsIt.hasNext()) { + totalNeighbors.add(neighborsIt.next()); } return (double)commonNeighbors.size() / (double)totalNeighbors.size(); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithm.java index 348146c3..3eed4750 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithm.java @@ -18,20 +18,11 @@ import org.la4j.decomposition.SingularValueDecompositor; import org.la4j.decomposition.EigenDecompositor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.TreeMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import java.util.*; + +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; import org.apache.commons.math3.optim.PointValuePair; import org.apache.commons.math3.optim.linear.LinearConstraint; @@ -244,7 +235,7 @@ public void setParameters(Map parameters) throws IllegalArgument public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithmException, InterruptedException { ArrayList commaSeparatedSeedIndexSet = new ArrayList(commaSeparatedSeedSet.size()); - Node[] graphNodes = graph.getNodeArray(); + Node[] graphNodes = graph.nodes().toArray(Node[]::new); for(String seed : commaSeparatedSeedSet) { boolean found = false; @@ -252,7 +243,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithm { if(graph.getNodeName(node).equals(seed)) { - commaSeparatedSeedIndexSet.add(node.index()); + commaSeparatedSeedIndexSet.add(node.getIndex()); found = true; break; } @@ -318,20 +309,20 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithm */ public Matrix getAdjacencyMatrixWithIdentity(CustomGraph graph) throws InterruptedException { - int size = graph.nodeCount(); + int size = graph.getNodeCount(); Matrix adjacencyMatrix = new CCSMatrix(size, size); //TOD: Maybe CCS is the problem? adjacencyMatrix = adjacencyMatrix.blank(); - - for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) { + Iterator ecIt = graph.edges().iterator(); + while (ecIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - Node source = edge.source(); - Node target = edge.target(); + Edge edge = ecIt.next(); + Node source = edge.getSourceNode(); + Node target = edge.getTargetNode(); - if (source.index() != target.index()) { - adjacencyMatrix.set(source.index(), target.index(), 1); + if (source.getIndex() != target.getIndex()) { + adjacencyMatrix.set(source.getIndex(), target.getIndex(), 1); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LouvainAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LouvainAlgorithm.java index 45d4362b..e36ac552 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LouvainAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/LouvainAlgorithm.java @@ -131,10 +131,19 @@ public void setParameters(Map parameters) throws IllegalArgument */ public Matrix getMembershipMatrix(CustomGraph graph, int[] communitiesPerNode) throws InterruptedException { - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), communitiesPerNode.length); + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), communitiesPerNode.length); membershipMatrix = membershipMatrix.blank(); - - for(int i=0; i graph.getNodeCount()){ + index = graph.getNodeCount(); + } + //////// + + for(int i=0; i getParameters() { + return new HashMap(); + } + + @Override + public void setParameters(Map parameters) throws IllegalArgumentException { + if(parameters.size() > 0) { + throw new IllegalArgumentException(); + } + } + + @Override + public Set compatibleGraphTypes() { + Set compatibilities = new HashSet(); + return compatibilities; + } + /** + * + */ + public Cover detectOverlappingCommunities(CustomGraph graph) throws InterruptedException { + // Global variables + final double initialDiversity; + int treeSize = 13; + int agentSize = 6; + int mutationProbability = 5; + int localSearchProbability = 10; + int genWithoutImprovement = 35; + boolean termination = false; + + Random rand = new Random(); + MLinkPopulation population = new MLinkPopulation(treeSize); + final MLinkIndividual solution; + HashMap> communitySet; + CustomGraph encoding = removeDoubleEdges(graph); + //System.out.println(encoding.edgeCount()); + //System.out.println(encoding.nodeCount()); + + //Initialize population + for(int i = 0; i < treeSize; i++){ + MLinkAgent agent = new MLinkAgent(); + for(int j = 0; j < agentSize; j++){ + int init = rand.nextInt(3); + if(init == 0){ + agent.addIndividual(localExpansion(encoding)); + } else if(init == 1){ + agent.addIndividual(labelPropagation(encoding)); + } else { + agent.addIndividual(localExpansionEigen(encoding)); + } + } + population.addAgent(agent); + } + population.swapUp(); + population.swapUp(); + + // Save the initial diversity to compare to later diversity changes + initialDiversity = population.calcDiversity(); + + // Memetic algorithm + int counter = 0; + int debug = 0; + double lastFitness = population.getAgent(0).getPocket().getFitness(); + while(!termination){ + //System.out.println("iteration: " + debug); + debug++; + for(int i = 0; i < treeSize; i++){ + MLinkAgent curAgent = population.getAgent(i); + SimpleEntry parents; + double diversity = population.calcDiversity(); + if(diversity < initialDiversity/2){ + parents = population.farSelect(i); + } else { + parents = population.closeSelect(i); + } + MLinkIndividual offspring = crossover(parents, encoding); + offspring.mutate(mutationProbability); + + if(rand.nextInt(100) < localSearchProbability){ + // offspring.localSearch(); + } + curAgent.addIndividual(offspring); + population.swapUp(); + //System.out.println("best fit: " + population.getAgent(0).getPocket().getFitness()); + } + // Check if termination criteria is met + double newFitness = population.getAgent(0).getPocket().getFitness(); + if(newFitness == lastFitness){ + counter++; + } else { + counter = 0; + lastFitness = newFitness; + } + if(counter == genWithoutImprovement){ + termination = true; + } + + } + solution = population.getAgent(0).getPocket(); + communitySet = solution.getNodeCommunity(); + communitySet = postProcessing(communitySet, encoding); + Matrix membershipMatrix = getMembershipMatrix(communitySet, encoding, solution.getCommunities().size()); + + return new Cover(graph, membershipMatrix); + + } + /** + * Creates a copy of the original graph and removes the undirected doubled edges + * @param graph the graph to be copied + * @return a copy with max. 1 edge between each node + */ + public CustomGraph removeDoubleEdges(CustomGraph graph){ + CustomGraph encoding = new CustomGraph(graph); + Edge[] edgesArray = encoding.edges().toArray(Edge[]::new); + ArrayList edges = new ArrayList(Arrays.asList(edgesArray)); + while(!edges.isEmpty()){ + Edge tmp = edges.remove(0); + Node source = tmp.getSourceNode(); + Node target = tmp.getTargetNode(); + Edge reversed = target.getEdgeToward(source); + if(reversed != null){ + encoding.removeEdge(reversed); + edges.remove(reversed); + } + } + return encoding; + } + /** + * Uniform Crossover operator + * @param parents tuple of two parents + * @return New individual created out of the two parents + */ + public MLinkIndividual crossover(SimpleEntry parents, CustomGraph graph){ + MLinkIndividual parent1 = parents.getKey(); + MLinkIndividual parent2 = parents.getValue(); + HashMap individual = new HashMap(); + Edge gene; + int crossProbability = 50; + + Random rand = new Random(); + for(Edge key : parent1.getIndividual().keySet()){ + if(rand.nextInt(101) < crossProbability){ + gene = parent1.getIndividual().get(key); + } else { + gene = parent2.getIndividual().get(key); + } + individual.put(key, gene); + } + + return new MLinkIndividual(individual); + } + /** + * Translates the community of nodes to a MLinkIndividual + * @param labels Nodes with the according Community as a label + * @return individual + */ + public MLinkIndividual translateToIndividual(HashMap labels){ + HashMap genes = new HashMap(); + HashMap> labelNodes = new HashMap>(); + + for(Node node : labels.keySet()){ + Integer l = labels.get(node); + if(!labelNodes.keySet().contains(l)){ + labelNodes.put(l, new HashSet()); + } + labelNodes.get(l).add(node); + } + + // Locus based representation + // Assign genes so that they represent the given community of edges + Random rand = new Random(); + Set checkedNodes = new HashSet(); + Set isQueued = new HashSet(); + // Queue for deep first search + Stack> queue = new Stack>(); + + for(Integer l : labelNodes.keySet()){ + Set commNodes = labelNodes.get(l); + Node start = commNodes.iterator().next(); + queue.add(new SimpleEntry(null,start)); + isQueued.add(start); + + while(!queue.empty()){ + + SimpleEntry curEntry = queue.pop(); + Node curNode = curEntry.getValue(); + checkedNodes.add(curNode); + + Edge[] adjEdges = curNode.edges().toArray(Edge[]::new); + int cyclicNext = 0; + Edge last = null; + Edge cur; + Edge first = curEntry.getKey(); + // Set first on an Edge that is inside the current community + if(first == null){ + for(int i = 0; i < adjEdges.length; i++){ + cur = adjEdges[cyclicNext]; + Node other = (curNode == cur.getSourceNode())? cur.getTargetNode():cur.getSourceNode(); + if(labels.get(other).equals(l)){ + first = cur; + // adjEdges.cyclicNext(); + break; + } else if(!genes.keySet().contains(cur)) { + first = cur; + } + cyclicNext++; + if(cyclicNext >= adjEdges.length){ + cyclicNext = 0; + } + } + if(first == null){ + break; + } + // Set edge cursor back on first + cyclicNext = 0; + while(adjEdges[cyclicNext] != first){ + cyclicNext++; + } + + // Put Root edge on itself + genes.put(first,first); + Node other = (curNode == first.getSourceNode())? first.getTargetNode():first.getSourceNode(); + if(labels.get(other).equals(l) && !isQueued.contains(other)){ + queue.add(new SimpleEntry(first, other)); + isQueued.add(other); + } + } + last = first; + + // Create a circle with the last edge pointing on the first + for(int i = 0; i < adjEdges.length; i++){ + cyclicNext++; + if (cyclicNext >= adjEdges.length){ + cyclicNext = 0; + } + cur = adjEdges[cyclicNext]; + Node other = (curNode == cur.getSourceNode())? cur.getTargetNode():cur.getSourceNode(); + if(labels.get(other).equals(l)){ + if(!checkedNodes.contains(other)){ + if(!isQueued.contains(other)){ + queue.add(new SimpleEntry(cur, other)); + isQueued.add(other); + } + if(last != first){ + genes.put(last, cur); + } + last = cur; + } + } else { + // check whether the connected node is the target or source + // then check if adjacent node was already checked and if act accordingly to split the shared edges with 50% chance + if(!checkedNodes.contains(other)){ + if(rand.nextInt(100) < 49){ + genes.put(cur, first); + } + } else if(!genes.keySet().contains(cur)){ + genes.put(cur, first); + } + } + } + if(last != first){ + genes.put(last, first); + } + } + } + + return new MLinkIndividual(genes); + } + + /** + * Label Propagation + * @param graph initial graph + * @return Individual generated with label propagation + */ + public MLinkIndividual labelPropagation(CustomGraph graph){ + HashMap labels = new HashMap(); + Node[] nodes = graph.nodes().toArray(Node[]::new); + // Each node receives a unique label + for(int i = 0; i < nodes.length; i++){ + labels.put(nodes[i], i); + } + boolean stop = false; + while(!stop){ + stop = true; + ArrayList notVisited = new ArrayList(Arrays.asList(nodes)); + // reassign new labels for each node + while(!notVisited.isEmpty()){ + int size = notVisited.size(); + int node = new Random().nextInt(size); + Node selected = notVisited.remove(node); + int newLabel = getMostFrequentLabel(labels, selected); + if(newLabel != labels.get(selected)){ + stop = false; + } + labels.put(selected, newLabel); + } + } + return translateToIndividual(labels); + + } + /** + * returns the label with the highes frequency amongst neighbors + * @param labels current labels + * @param selected selected node + * @return new label + */ + public int getMostFrequentLabel(HashMap labels, Node selected){ + Node[] neighbors = selected.neighborNodes().toArray(Node[]::new); + int size = neighbors.length; + if(size == 0){ + return labels.get(selected); + } + HashMap labelCount = new HashMap(); + ArrayList maxLabels = new ArrayList(); + int maxCount = 0; + // count neighboring labels and save it in a hashmap + for(int i = 0; i < size; i++){ + Node neighbor = neighbors[i]; + Integer label = labels.get(neighbor); + int count = labelCount.containsKey(label)?labelCount.get(label):0; + count++; + if(count == maxCount){ + maxLabels.add(label); + } else if(count > maxCount){ + maxCount = count; + maxLabels.clear(); + maxLabels.add(label); + } + labelCount.put(label, count); + + } + + + + return maxLabels.get(new Random().nextInt(maxLabels.size())); + } + + + /** + * Local Expansion with random seed + * @param graph initial graph + * @return returns new MLinkIndividual + */ + public MLinkIndividual localExpansion(CustomGraph graph){ + HashMap communities = new HashMap(); + Node[] nodeArr = graph.nodes().toArray(Node[]::new); + ArrayList nodes = new ArrayList(Arrays.asList(nodeArr)); + int curComm = 0; + Random rand = new Random(); + + while(!nodes.isEmpty()){ + //select random seed node; + int seedIndex = rand.nextInt(nodes.size()); + Node seed = nodes.get(seedIndex); + communities.put(seed, curComm); + nodes.remove(seed); + + // Create natural community and remove nodes + Node[] neighbors = seed.neighborNodes().toArray(Node[]::new); + for(int i = 0; i < neighbors.length; i++){ + Node cur = neighbors[i]; + communities.put(cur,curComm); + nodes.remove(cur); + } + curComm++; + } + return translateToIndividual(communities); + } + /** + * Create an individual using eigenvecotor centrality + */ + public MLinkIndividual localExpansionEigen(CustomGraph graph){ + try{ + EigenvectorCentrality eigenVectorCentrality = new EigenvectorCentrality(); + CentralityMap centralities = eigenVectorCentrality.getValues(graph); + HashMap communities = new HashMap(); + ArrayList nodes = new ArrayList(Arrays.asList(graph.nodes().toArray(Node[]::new))); + int curComm = 0; + + while(!nodes.isEmpty()){ + // Select seed based on Eigenvector centrality + Node seed = nodes.get(0); + for(int i = 1; i < nodes.size(); i++){ + if(centralities.getNodeValue(seed) < centralities.getNodeValue(nodes.get(i))){ + seed = nodes.get(i); + } + } + communities.put(seed, curComm); + nodes.remove(seed); + // Create natural community and remove nodes + Node[] neighbors = seed.neighborNodes().toArray(Node[]::new); + for(int i = 0; i < neighbors.length; i++){ + Node cur = neighbors[i]; + communities.put(cur,curComm); + nodes.remove(cur); + + } + curComm++; + } + + return translateToIndividual(communities); + + } catch(Exception e){ + e.printStackTrace(); + return null; + } + } + + /** + * Postprocessing step to remove + * @param communitySet + * @param graph + * @return + */ + public HashMap> postProcessing(HashMap> communitySet,CustomGraph graph){ + HashMap> nodes = new HashMap>(); + HashMap> updatedNodes = new HashMap>(); + for(Node n : graph.nodes().toArray(Node[]::new)){ + nodes.put(n, new HashSet()); + updatedNodes.put(n, new HashSet()); + } + for(Integer community : communitySet.keySet()){ + for(Node n : communitySet.get(community)){ + nodes.get(n).add(community); + updatedNodes.get(n).add(community); + } + } + // Look at every node with more than 1 community and check if the node adds to the intra density of the community + + for(Node n : nodes.keySet()){ + // Check if Node is part of more than 1 community + if(nodes.get(n).size() < 2 ){ + continue; + } + // Check for communities consisting of only 1 node + ArrayList delCommunities = new ArrayList(); + for(Integer com : nodes.get(n)){ + if(communitySet.get(com).size() == 1){ + communitySet.remove(com); + delCommunities.add(com); + } + } + for(Integer com : delCommunities){ + nodes.get(n).remove(com); + } + + // Check again if node is part of multiple communities after deletion process + if(nodes.get(n).size() < 2 ){ + continue; + } + + int bestCommunity = -1; + double bestCommunityIntra = -1; + int communityCount = updatedNodes.get(n).size(); + + // Check for every community of Node n if it adds to the intra density and remove if not + for(Integer com : nodes.get(n)){ + HashSet nodeRemoved = new HashSet<>(communitySet.get(com)); + nodeRemoved.remove(n); + HashMap> copyNodes = new HashMap>(updatedNodes); + copyNodes.put(n,new HashSet(copyNodes.get(n))); + copyNodes.get(n).remove(com); + double removedIntra = intraDensity(nodeRemoved, copyNodes); + double normalIntra = intraDensity(communitySet.get(com), updatedNodes); + + + // If the intra Density is greater without the node remove it from the community + if(removedIntra > normalIntra /*|| (communitySet.get(com).size() == 2 && removedIntra == normalIntra)*/){ + communitySet.get(com).remove(n); + updatedNodes.get(n).remove(com); + communityCount = communityCount - 1; + if(bestCommunityIntra < removedIntra){ + bestCommunityIntra = removedIntra; + bestCommunity = com; + } + } + } + + // If the node is now part of no community add it to the one with the least intra density loss + if(updatedNodes.get(n).isEmpty()){ + communitySet.get(bestCommunity).add(n); + updatedNodes.get(n).add(bestCommunity); + } + } + return communitySet; + } + /** + * Calculates the intra density for a graph with community distribution + * @param nodes Set of the current nodes inside the community + * @param communities HashMap with nodes and corresponding communities + * @return intra density + */ + public double intraDensity(HashSet nodes, HashMap> communities){ + double count = 0; + for(Node n : nodes){ + Edge[] edges = n.edges().toArray(Edge[]::new); + for(int i = 0; i < edges.length; i++){ + Node target = edges[i].getTargetNode(); + Node source = edges[i].getSourceNode(); + HashSet intersection = new HashSet(communities.get(source)); + intersection.retainAll(communities.get(target)); + if(!intersection.isEmpty()){ + count++; + } + + } + } + return 2*((count/2)/nodes.size()); + } + /** + * Intra density that puts more weight on the amount of edges + * @param nodes Set of the current nodes inside the community + * @param communities HashMap with nodes and corresponding communities + * @return intra density + */ + public double intraDensity2(HashSet nodes, HashMap> communities){ + double count = 0; + for(Node n : nodes){ + Edge[] edges = n.edges().toArray(Edge[]::new); + for(int i = 0; i < edges.length; i++){ + Node target = edges[i].getTargetNode(); + Node source = edges[i].getSourceNode(); + HashSet intersection = new HashSet(communities.get(source)); + intersection.retainAll(communities.get(target)); + if(!intersection.isEmpty()){ + count++; + } + + } + } + return 2*((count/2)/Math.pow(nodes.size(),1.5)); + } + + + /** + * Creates a membership matrix for the giben Map + * @param communitySet Map with nodes and their communities + * @param graph initial graph + * @param communityNumber amount of communities + * @return membership matrix + */ + public Matrix getMembershipMatrix(HashMap> communitySet, CustomGraph graph, int communityNumber){ + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(),communityNumber); + int counter = 0; + //System.out.println("comm: " + communitySet.size()); + //System.out.println("nr: " + communityNumber); + for(Integer comm : communitySet.keySet()){ + for(Node n : communitySet.get(comm)){ + membershipMatrix.set(n.getIndex(), counter, 1); + } + counter++; + } + return membershipMatrix; + } +} \ No newline at end of file diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesAlgorithm.java index 95946eda..ba571258 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesAlgorithm.java @@ -15,8 +15,9 @@ import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements the Merging of Overlapping Communities Algorithm by F. Havemann, M. Heinz, A. Struck, and J. Glaser: @@ -106,7 +107,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws InterruptedE } if(didDeactivate(graph, communityId, activeCommunities, unactiveCommunities, deactivatedBy)) { deactivatedCommunities.add(communityId); - if(unactiveCommunities.size() > graph.nodeCount() - Math.log(graph.nodeCount())) { + if(unactiveCommunities.size() > graph.getNodeCount() - Math.log(graph.getNodeCount())) { mainCommunities.add(communityId); } } @@ -162,14 +163,14 @@ private Matrix determineMembershipMatrix(CustomGraph graph, Map> entryIt.remove(); } } - Matrix memberships = new CCSMatrix(graph.nodeCount(), unactiveCommunities.size()); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), unactiveCommunities.size()); int communityIndex = 0; for(Set community : unactiveCommunities.values()) { for(Node member : community) { if(Thread.interrupted()) { throw new InterruptedException(); } - memberships.set(member.index(), communityIndex, 1); + memberships.set(member.getIndex(), communityIndex, 1); } communityIndex++; } @@ -200,7 +201,8 @@ private double determineResolutionAlpha(CustomGraph graph, Map determineUnitAlphaSequence(Map> private TreeSet determineCommunityAlphaSequence(CustomGraph graph, Map> inclusionAlphas, Map deactivatedBy, Node communityId) throws InterruptedException { TreeSet alphaSequence = new TreeSet(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; Node currentCommunityId; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); currentCommunityId = communityId; while(!inclusionAlphas.get(currentCommunityId).containsKey(node)) { currentCommunityId = deactivatedBy.get(currentCommunityId); } alphaSequence.add(inclusionAlphas.get(currentCommunityId).get(node)); - nodes.next(); } return alphaSequence; } @@ -313,7 +314,7 @@ private boolean didDeactivate(CustomGraph graph, Node communityId, Map incl Map communityDegrees, Map internalCommunityDegrees, Map> inclusionAlphas, Map alphaBounds) throws InterruptedException { double internalCommunityDegree; double totalCommunityDegree; - NodeCursor successors; + Iterator successorsIt; Node neighbor; double internalNeighborDegree; if(inclusionAlpha > alphaBounds.get(communityId)) { @@ -386,24 +387,23 @@ private void updateCommunity(CustomGraph graph, Node communityId, Set incl communityDegrees.put(communityId, totalCommunityDegree); inclusionAlphas.get(communityId).put(inclusionNode, inclusionAlpha); communities.get(communityId).add(inclusionNode); - successors = inclusionNode.successors(); + successorsIt = graph.getSuccessorNeighbours(inclusionNode).iterator(); /* * Neighborhood update. */ - while(successors.ok()) { - neighbor = successors.node(); + while(successorsIt.hasNext()) { + neighbor = successorsIt.next(); if(communityNeighbors.get(communityId).contains(neighbor)) { internalNeighborDegree = internalNeighborDegrees.get(communityId).get(neighbor); - internalNeighborDegree += graph.getEdgeWeight(inclusionNode.getEdgeTo(neighbor)); + internalNeighborDegree += graph.getEdgeWeight(inclusionNode.getEdgeToward(neighbor)); internalNeighborDegrees.get(communityId).put(neighbor, internalNeighborDegree); } else if(!communities.get(communityId).contains(neighbor)) { communityNeighbors.get(communityId).add(neighbor); - internalNeighborDegree = graph.getEdgeWeight(inclusionNode.getEdgeTo(neighbor)); + internalNeighborDegree = graph.getEdgeWeight(inclusionNode.getEdgeToward(neighbor)); internalNeighborDegrees.get(communityId).put(neighbor, internalNeighborDegree); } - successors.next(); - } + } } } @@ -424,8 +424,8 @@ private void init(CustomGraph graph, Map> communities, Map alphaBounds, Map> communityNeighbors, Map weightedNodeDegrees, Map> internalWeightedNeighborDegrees, Map weightedCommunityDegrees, Map internalWeightedCommunityDegrees) throws InterruptedException { - NodeCursor nodes = graph.nodes(); - NodeCursor successors; + Iterator nodesIt = graph.iterator(); + Iterator successorsIt; Node node; Node neighbor; double edgeWeight; @@ -434,22 +434,21 @@ private void init(CustomGraph graph, Map> communities, Map communityMembers; Map communityAlphas; double weightedDegree; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); weightedDegree = 0; - successors = node.successors(); + successorsIt = graph.getSuccessorNeighbours(node).iterator(); neighbors = new HashSet(); internalWeightedCommunityNeighborDegrees = new HashMap(); - while(successors.ok()) { - neighbor = successors.node(); + while(successorsIt.hasNext()) { + neighbor = successorsIt.next(); neighbors.add(neighbor); - edgeWeight = graph.getEdgeWeight(node.getEdgeTo(neighbor)); + edgeWeight = graph.getEdgeWeight(node.getEdgeToward(neighbor)); weightedDegree += edgeWeight; internalWeightedCommunityNeighborDegrees.put(neighbor, edgeWeight); - successors.next(); } weightedNodeDegrees.put(node, weightedDegree); weightedCommunityDegrees.put(node, weightedDegree); @@ -463,7 +462,6 @@ private void init(CustomGraph graph, Map> communities, Map compatibleGraphTypes() { @Override public Cover detectOverlappingCommunities(CustomGraph graph) throws OcdAlgorithmException, InterruptedException { - Pair biconnctedCoreInformation = filtering(graph); - Graph biconnectedCore = biconnctedCoreInformation.getFirst(); - EdgeList bridges = biconnctedCoreInformation.getSecond(); - NodeList seeds = seeding(biconnectedCore); - NodeList[] lowConductanceSets = expansion(biconnectedCore, seeds); + Pair> biconnectedCoreInformation = filtering(graph); + CustomGraph biconnectedCore = biconnectedCoreInformation.getFirst(); + ArrayList bridges = biconnectedCoreInformation.getSecond(); + ArrayList seeds = seeding(biconnectedCore); + ArrayList> lowConductanceSets = expansion(biconnectedCore, seeds); Matrix memberships = propagation(graph, lowConductanceSets, bridges, biconnectedCore); return new Cover(graph, memberships); } @@ -153,68 +140,73 @@ public CoverCreationType getAlgorithmType() { * @param graph * @return Pair with the biconnectedCore and the bridges */ - private Pair filtering(CustomGraph graph) { - Graph biconnectedCore = graph.createCopy(); + private Pair> filtering(CustomGraph graph) throws InterruptedException { + CustomGraph biconnectedCore = new CustomGraph(graph); //HashMap to get the connection between the nodes of the original graph and the biconnectedCore HashMap edgeMapping = new HashMap(); //Add all edges to the hashmap - EdgeCursor graphCursor = graph.edges(); - EdgeCursor biconnectedCoreCursor = biconnectedCore.edges(); - while(graphCursor.ok()) { - edgeMapping.put(biconnectedCoreCursor.edge(), graphCursor.edge()); - biconnectedCoreCursor.next(); - graphCursor.next(); + Iterator graphCursor = graph.edges().iterator(); + Iterator biconnectedCoreCursor = biconnectedCore.edges().iterator(); + while(graphCursor.hasNext()) { + edgeMapping.put(biconnectedCoreCursor.next(), graphCursor.next()); } //Add all nodes to the hashmap (defined globally) - NodeCursor graphNodeCursor = graph.nodes(); - NodeCursor biconnectedCoreNodeCursor = biconnectedCore.nodes(); - while(graphNodeCursor.ok()) { - nodeMapping.put(biconnectedCoreNodeCursor.node(), graphNodeCursor.node()); - biconnectedCoreNodeCursor.next(); - graphNodeCursor.next(); + Iterator graphNodeCursor = graph.iterator(); + Iterator biconnectedCoreNodeCursor = biconnectedCore.iterator(); + while(graphNodeCursor.hasNext()) { + nodeMapping.put(biconnectedCoreNodeCursor.next(), graphNodeCursor.next()); } - + + //TODO: Check this //Retrieve all biconnected components of the graph and save the bridges - EdgeList[] biconnectedComponents = GraphConnectivity.biconnectedComponents(biconnectedCore); + HopcroftTarjanBiconnectedComponents bccAlgo = new HopcroftTarjanBiconnectedComponents(biconnectedCore); + bccAlgo.compute(); + ArrayList biconnectedComponents = bccAlgo.getBiconnectedComponents(); + ArrayList biconnectedComponentsEdges = new ArrayList(); + for (HopcroftTarjanBiconnectedComponents.BiconnectedComponent bcc : biconnectedComponents) { + biconnectedComponentsEdges.add(bcc.edges().toArray(Edge[]::new)); + } //Remove all biconnected components of size one (as graphs are directed the edgeSize is 2) LinkedList singleEdgeBiconnectedComponents = new LinkedList(); - for (EdgeList edgeList : biconnectedComponents) { - if(edgeList.size() == 2) { - biconnectedCore.removeEdge(edgeList.firstEdge()); - biconnectedCore.removeEdge(edgeList.lastEdge()); - singleEdgeBiconnectedComponents.add(edgeList.firstEdge()); - singleEdgeBiconnectedComponents.add(edgeList.lastEdge()); + for (Edge[] edgeArray : biconnectedComponentsEdges) { + if(edgeArray.length == 2) { + biconnectedCore.removeEdge(edgeArray[0]); + biconnectedCore.removeEdge(edgeArray[edgeArray.length-1]); + singleEdgeBiconnectedComponents.add(edgeArray[0]); + singleEdgeBiconnectedComponents.add(edgeArray[edgeArray.length-1]); } } - + + //TODO: Check this //Find all nodes that are part of the biconnected core - NodeList[] connectedComponents = GraphConnectivity.connectedComponents(biconnectedCore); - NodeList coreNodes = new NodeList(); - for (NodeList nodeList: connectedComponents) { - if(nodeList.size() > coreNodes.size()) { - coreNodes = nodeList; - } - } + ConnectedComponents ccAlgo = new ConnectedComponents(biconnectedCore); + ccAlgo.compute(); + List coreNodes = List.of(ccAlgo.getGiantComponent().nodes().toArray(Node[]::new)); +// for (Node[] nodeList: connectedComponents) { +// if(nodeList.length > coreNodes.size()) { +// coreNodes = nodeList; +// } +// } //Get all bridges (only those from the biconnected core to the whisker) - EdgeList bridges = new EdgeList(); + ArrayList bridges = new ArrayList(); for (Edge edge : singleEdgeBiconnectedComponents) { - if(coreNodes.contains(edge.source()) && !coreNodes.contains(edge.target())) { + if(coreNodes.contains(edge.getSourceNode()) && !coreNodes.contains(edge.getTargetNode())) { //Add the mapped edge (which belongs to graph and not biconnectedCore) to the bridges array bridges.add(edgeMapping.get(edge)); } } //Remove all nodes without neighbors from the biconnected core - Node[] nodes = biconnectedCore.getNodeArray(); + Node[] nodes = biconnectedCore.nodes().toArray(Node[]::new); for (Node node : nodes) { - if(node.neighbors().size() == 0) { + if(graph.getNeighbours(node).size() == 0) { biconnectedCore.removeNode(node); } } - return new Pair(biconnectedCore, bridges); + return new Pair>(biconnectedCore, bridges); } /** @@ -224,8 +216,8 @@ private Pair filtering(CustomGraph graph) { * @param biconnectedCore * @return list of the seed nodes */ - private NodeList seeding(Graph biconnectedCore) { - NodeList seeds = new NodeList(); + private ArrayList seeding(CustomGraph biconnectedCore) throws InterruptedException { + ArrayList seeds = new ArrayList(); seeds = spreadHubs(biconnectedCore); return seeds; } @@ -233,12 +225,12 @@ private NodeList seeding(Graph biconnectedCore) { /** * Algorithm Spread Hubs chooses an independent set of k (= seedCount) seeds by * looking at the vertices in order of decreasing degree - * @param biconnected core + * @param biconnectedCore * @return list of the seed nodes */ - private NodeList spreadHubs(Graph biconnectedCore) { - NodeList seeds = new NodeList(); - Node[] coreNodesArray = biconnectedCore.getNodeArray(); + private ArrayList spreadHubs(CustomGraph biconnectedCore) throws InterruptedException { + ArrayList seeds = new ArrayList(); + Node[] coreNodesArray = biconnectedCore.nodes().toArray(Node[]::new); ConcurrentHashMap coreNodesMap = new ConcurrentHashMap(); for (Node node : coreNodesArray) { // All nodes of the core are unmarked @@ -257,13 +249,13 @@ private NodeList spreadHubs(Graph biconnectedCore) { if(!entry.getValue()) { //Indicate that so far not every node has been marked allMarked = false; - if(entry.getKey().degree() > maxDegree) { - maxDegree = entry.getKey().degree(); + if(entry.getKey().getDegree() > maxDegree) { + maxDegree = entry.getKey().getDegree(); maxDegreeNodes = new LinkedList>(); maxDegreeNodes.add(entry); } else { - if(entry.getKey().degree() == maxDegree) { + if(entry.getKey().getDegree() == maxDegree) { maxDegreeNodes.add(entry); } } @@ -276,11 +268,10 @@ private NodeList spreadHubs(Graph biconnectedCore) { seeds.add(entry.getKey()); entry.setValue(true); //Iterate over all neighbors and mark them as well - NodeCursor neighborsCursor = entry.getKey().neighbors(); - for (int j = 0; j < neighborsCursor.size(); j++) { - Node neighbor = neighborsCursor.node(); + Iterator neighborsIt = biconnectedCore.getNeighbours(entry.getKey()).iterator(); //TODO: previously was .neighbors. Check if behaves the same + while (neighborsIt.hasNext()) { + Node neighbor = neighborsIt.next(); coreNodesMap.put(neighbor, true); - neighborsCursor.next(); } } } @@ -296,11 +287,11 @@ private NodeList spreadHubs(Graph biconnectedCore) { * @param seeds which should be expanded * @return Array of expanded clusters */ - private NodeList[] expansion(Graph biconnectedCore, NodeList seeds) { - Node[] seedsArray = seeds.toNodeArray(); - NodeList[] lowConductanceSets = new NodeList[seedsArray.length]; + private ArrayList> expansion(CustomGraph biconnectedCore, ArrayList seeds) throws InterruptedException { + Node[] seedsArray = seeds.toArray(Node[]::new); + ArrayList> lowConductanceSets = new ArrayList>(seedsArray.length); for(int i = 0; i < seedsArray.length; i++) { - lowConductanceSets[i] = computeLowConductanceSet(biconnectedCore, seedsArray[i]); + lowConductanceSets.add(i, computeLowConductanceSet(biconnectedCore, seedsArray[i])); } return lowConductanceSets; } @@ -311,15 +302,14 @@ private NodeList[] expansion(Graph biconnectedCore, NodeList seeds) { * @param seed to compute the lowConductanceSet for * @return List of nodes belong to the set of low conductance for that seed node */ - private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { + private ArrayList computeLowConductanceSet(CustomGraph biconnectedCore, Node seed) throws InterruptedException { //Set of restart nodes Set restartNodes = new HashSet(); restartNodes.add(seed); //Iterate over all neighbors add them to the restart nodes - NodeCursor neighbors = seed.neighbors(); - for (int j = 0; j < neighbors.size(); j++) { - restartNodes.add(neighbors.node()); - neighbors.next(); + Iterator neighbors = biconnectedCore.getNeighbours(seed).iterator(); + while (neighbors.hasNext()) { + restartNodes.add(neighbors.next()); } HashMap x = new HashMap(); @@ -336,7 +326,7 @@ private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { stop = true; for (Map.Entry entry : r.entrySet()) { Node v = entry.getKey(); - if(r.containsKey(v) && (r.get(v) > (v.degree()*accuracy))) { + if(r.containsKey(v) && (r.get(v) > (v.getDegree()*accuracy))) { stop = false; //Update the value in x for v if(x.containsKey(v)) { @@ -349,19 +339,18 @@ private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { } //Update r of all neighbor nodes - NodeCursor neighborsCursor = v.neighbors(); - while(neighborsCursor.ok()) { - Node neighbor = neighborsCursor.node(); + Iterator neighborsIterator = biconnectedCore.getNeighbours(v).iterator(); + while(neighborsIterator.hasNext()) { + Node neighbor = neighborsIterator.next(); //Update r of the neighbor node if(r.containsKey(neighbor)) { - double newR = r.get(neighbor) + ((probability * r.get(v))/(2*v.neighbors().size())); + double newR = r.get(neighbor) + ((probability * r.get(v))/(2*biconnectedCore.getNeighbours(v).size())); r.put(neighbor, newR); } else { - double newR = 0 + ((probability * r.get(v))/(2*v.neighbors().size())); + double newR = 0 + ((probability * r.get(v))/(2*biconnectedCore.getNeighbours(v).size())); r.put(neighbor, newR); } - neighborsCursor.next(); } //Update r of v @@ -375,7 +364,7 @@ private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { TreeMap sortedNodes = new TreeMap(); for (Map.Entry entry : x.entrySet()) { Node v = entry.getKey(); - sortedNodes.put((x.get(v)/v.degree()), v); + sortedNodes.put((x.get(v)/v.getDegree()), v); } //Calculate the min conductance of the decreasing set @@ -393,8 +382,8 @@ private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { } } - //Parse into NodeList and return minConductanceSet - NodeList minConductanceSet = new NodeList(); + //Parse into ArrayList and return minConductanceSet + ArrayList minConductanceSet = new ArrayList(); for (Node node : currentMinConductanceSet) { minConductanceSet.add(node); } @@ -408,7 +397,7 @@ private NodeList computeLowConductanceSet(Graph biconnectedCore, Node seed) { * @param biconnectedCore * @return calculated conductance */ - private double calculateConductance(HashSet nodeSet, Graph biconnectedCore) { + private double calculateConductance(HashSet nodeSet, CustomGraph biconnectedCore) throws InterruptedException { // Number of edges between the nodeSet and the coreNodes\nodeSet int numberC_V_C = 0; // Number of edges between the nodeSet and the coreNodes @@ -419,10 +408,10 @@ private double calculateConductance(HashSet nodeSet, Graph biconnectedCore int allCoreEdges = 0; //Count the numbers of edges - for (Node node : biconnectedCore.getNodeArray()) { - NodeCursor neighbors = node.neighbors(); - while (neighbors.ok()) { - Node neighbor = neighbors.node(); + for (Node node : biconnectedCore.nodes().toArray(Node[]::new)) { + Iterator neighbors = biconnectedCore.getNeighbours(node).iterator(); + while (neighbors.hasNext()) { + Node neighbor = neighbors.next(); if(nodeSet.contains(node)) { if(!nodeSet.contains(neighbor)) { numberC_V_C++; @@ -430,7 +419,6 @@ private double calculateConductance(HashSet nodeSet, Graph biconnectedCore numberC_V++; } allCoreEdges++; - neighbors.next(); } } @@ -462,22 +450,22 @@ private double calculateConductance(HashSet nodeSet, Graph biconnectedCore * @param biconnectedCore * @return membership matrix */ - private Matrix propagation(CustomGraph graph, NodeList[] lowConductanceSets, EdgeList bridges, Graph biconnectedCore) { - Matrix memberships = new Basic2DMatrix(graph.nodeCount(), lowConductanceSets.length); + private Matrix propagation(CustomGraph graph, ArrayList> lowConductanceSets, ArrayList bridges, CustomGraph biconnectedCore) throws InterruptedException { + Matrix memberships = new Basic2DMatrix(graph.getNodeCount(), lowConductanceSets.size()); memberships = memberships.blank(); //iterate over all communities and set the values for all coreNodes - for (int i = 0; i < lowConductanceSets.length; i++) { - Node[] currentCommunity = lowConductanceSets[i].toNodeArray(); + for (int i = 0; i < lowConductanceSets.size(); i++) { + Node[] currentCommunity = lowConductanceSets.get(i).toArray(Node[]::new); //iterate over all the nodes in that community for (Node node : currentCommunity) { - memberships.set(nodeMapping.get(node).index(), i, 1); + memberships.set(nodeMapping.get(node).getIndex(), i, 1); } } //Determine the whiskers and copy the value of the corresponding coreNodes to the whiskerNodes while (!bridges.isEmpty()) { - Edge bridge = bridges.firstEdge(); + Edge bridge = bridges.get(0); //Remove the bridge bridges.remove(0); @@ -485,8 +473,8 @@ private Matrix propagation(CustomGraph graph, NodeList[] lowConductanceSets, Edg //Bridges are saved so that the source is the coreNode Node coreNode; Node whiskerNode; - coreNode = bridge.source(); - whiskerNode = bridge.target(); + coreNode = bridge.getSourceNode(); + whiskerNode = bridge.getTargetNode(); //Determine the whole whisker HashSet whisker = new HashSet(); @@ -498,21 +486,20 @@ private Matrix propagation(CustomGraph graph, NodeList[] lowConductanceSets, Edg if(!whisker.contains(currentNode)) { whisker.add(currentNode); //Add all neighbors to toSearch - NodeCursor neighbors = currentNode.neighbors(); - for(int j = 0; j < neighbors.size(); j++) { - Node neighbor = neighbors.node(); + Iterator neighbors = biconnectedCore.getNeighbours(currentNode).iterator(); + while (neighbors.hasNext()) { + Node neighbor = neighbors.next(); if(!toSearch.contains(neighbor) && !whisker.contains(neighbor) && !coreNode.equals(neighbor)) { toSearch.add(neighbor); } - neighbors.next(); } } } //Copy the values of the coreNode to the whisker nodes - Vector coreRow = memberships.getRow(coreNode.index()); + Vector coreRow = memberships.getRow(coreNode.getIndex()); for (Node currentWhiskerNode: whisker) { - memberships.setRow(currentWhiskerNode.index(), coreRow); + memberships.setRow(currentWhiskerNode.getIndex(), coreRow); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/OcdAlgorithmExecutor.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/OcdAlgorithmExecutor.java index 7e125c19..b01db0d0 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/OcdAlgorithmExecutor.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/OcdAlgorithmExecutor.java @@ -18,7 +18,7 @@ import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; +import org.graphstream.graph.Node; /** * Manages the execution of an OcdAlgorithm. @@ -85,7 +85,7 @@ private List>> calculateComponentCovers(List> pair : components) { component = pair.getFirst(); - if(component.nodeCount() < componentNodeCountFilter) { + if(component.getNodeCount() < componentNodeCountFilter) { componentCover = computeSingleCommunityCover(component, algorithm); } else { @@ -107,7 +107,7 @@ private List>> calculateComponentCovers(List edgesIt = graph.edges().iterator(); double disassortativity; Edge edge; - while (edges.ok()) { + while (edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edgesIt.next(); disassortativity = Math - .abs(graph.getWeightedInDegree(edge.target()) - - graph.getWeightedInDegree(edge.source())); - disassortativities.set(edge.target().index(), - edge.source().index(), disassortativity); - edges.next(); + .abs(graph.getWeightedInDegree(edge.getTargetNode()) + - graph.getWeightedInDegree(edge.getSourceNode())); + disassortativities.set(edge.getTargetNode().getIndex(), + edge.getSourceNode().getIndex(), disassortativity); } /* * Column normalizes transposed disassortativity matrix. @@ -248,23 +247,22 @@ protected Vector executeRandomWalk(Matrix disassortativityMatrix) */ protected Vector getLeadershipValues(CustomGraph graph, Vector disassortativityVector) throws InterruptedException { - Vector leadershipVector = new BasicVector(graph.nodeCount()); - NodeCursor nodes = graph.nodes(); + Vector leadershipVector = new BasicVector(graph.getNodeCount()); + Iterator nodesIt = graph.iterator(); Node node; double leadershipValue; - while (nodes.ok()) { + while (nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); /* * Note: degree normalization is left out since it * does not influence the outcome. */ leadershipValue = graph.getWeightedInDegree(node) - * disassortativityVector.get(node.index()); - leadershipVector.set(node.index(), leadershipValue); - nodes.next(); + * disassortativityVector.get(node.getIndex()); + leadershipVector.set(node.getIndex(), leadershipValue); } return leadershipVector; } @@ -283,12 +281,12 @@ protected Vector getLeadershipValues(CustomGraph graph, protected Map getFollowerDegrees(CustomGraph graph, Vector leadershipVector) throws InterruptedException { Map followerMap = new HashMap(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); /* * Iterates over all nodes to detect their local leader */ Node node; - NodeCursor successors; + Iterator successorsIt; double maxInfluence; List leaders = new ArrayList(); Node successor; @@ -296,21 +294,21 @@ protected Map getFollowerDegrees(CustomGraph graph, double successorInfluence; Edge nodeEdge; double followerDegree; - while (nodes.ok()) { + while (nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - successors = node.successors(); + node = nodesIt.next(); + successorsIt = graph.getSuccessorNeighbours(node).iterator(); maxInfluence = Double.NEGATIVE_INFINITY; leaders.clear(); /* * Checks all successors for possible leader */ - while (successors.ok()) { - successor = successors.node(); - successorEdge = node.getEdgeTo(successor); - successorInfluence = leadershipVector.get(successor.index()) + while (successorsIt.hasNext()) { + successor = successorsIt.next(); + successorEdge = node.getEdgeToward(successor); + successorInfluence = leadershipVector.get(successor.getIndex()) * graph.getEdgeWeight(successorEdge); if (successorInfluence >= maxInfluence) { nodeEdge = node.getEdgeFrom(successor); @@ -319,7 +317,7 @@ protected Map getFollowerDegrees(CustomGraph graph, */ if (nodeEdge == null || successorInfluence > leadershipVector.get(node - .index()) * graph.getEdgeWeight(nodeEdge)) { + .getIndex()) * graph.getEdgeWeight(nodeEdge)) { if (successorInfluence > maxInfluence) { /* * Other nodes have lower influence @@ -330,7 +328,6 @@ protected Map getFollowerDegrees(CustomGraph graph, maxInfluence = successorInfluence; } } - successors.next(); } if (!leaders.isEmpty()) { for (Node leader : leaders) { @@ -342,7 +339,6 @@ protected Map getFollowerDegrees(CustomGraph graph, followerDegree += 1d / leaders.size()); } } - nodes.next(); } return followerMap; } @@ -439,7 +435,7 @@ protected Map executeLabelPropagation(CustomGraph graph, Iterator nodeIt; Node node; double profitability; - NodeCursor nodeSuccessors; + Iterator nodeSuccessorsIt; Node nodeSuccessor; do { iterationCount++; @@ -456,15 +452,15 @@ protected Map executeLabelPropagation(CustomGraph graph, } node = nodeIt.next(); profitability = 0; - nodeSuccessors = node.successors(); - while (nodeSuccessors.ok()) { - nodeSuccessor = nodeSuccessors.node(); + Set nodeSuccessors = graph.getSuccessorNeighbours(node); + nodeSuccessorsIt = nodeSuccessors.iterator(); + while (nodeSuccessorsIt.hasNext()) { + nodeSuccessor = nodeSuccessorsIt.next(); Integer joinIteration = memberships.get(nodeSuccessor); if (nodeSuccessor.equals(leader) || ( joinIteration != null && joinIteration < iterationCount)) { profitability++; } - nodeSuccessors.next(); } if (profitability / nodeSuccessors.size() > profitabilityThreshold) { memberships.put(node, iterationCount); @@ -494,29 +490,27 @@ protected Map executeLabelPropagation(CustomGraph graph, protected Set getBehaviorPredecessors(CustomGraph graph, Map memberships, Node leader) throws InterruptedException { Set neighbors = new HashSet(); - NodeCursor leaderPredecessors = leader.predecessors(); + Iterator leaderPredecessorsIt = graph.getPredecessorNeighbours(leader).iterator(); Node leaderPredecessor; - while (leaderPredecessors.ok()) { - leaderPredecessor = leaderPredecessors.node(); + while (leaderPredecessorsIt.hasNext()) { + leaderPredecessor = leaderPredecessorsIt.next(); if (!memberships.containsKey(leaderPredecessor)) { neighbors.add(leaderPredecessor); } - leaderPredecessors.next(); } - NodeCursor memberPredecessors; + Iterator memberPredecessorsIt; Node memberPredecessor; for (Node member : memberships.keySet()) { if(Thread.interrupted()) { throw new InterruptedException(); } - memberPredecessors = member.predecessors(); - while (memberPredecessors.ok()) { - memberPredecessor = memberPredecessors.node(); + memberPredecessorsIt = graph.getPredecessorNeighbours(member).iterator(); + while (memberPredecessorsIt.hasNext()) { + memberPredecessor = memberPredecessorsIt.next(); if (!memberPredecessor.equals(leader) && !memberships.containsKey(memberPredecessor)) { neighbors.add(memberPredecessor); } - memberPredecessors.next(); } } return neighbors; @@ -538,15 +532,15 @@ protected Set getBehaviorPredecessors(CustomGraph graph, protected boolean areAllNodesAssigned(CustomGraph graph, Map> communities) throws InterruptedException { boolean allNodesAreAssigned = true; - NodeCursor nodes = graph.nodes(); + Iterator nodes = graph.iterator(); boolean nodeIsAssigned; Node node; - while (nodes.ok()) { + while (nodes.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } nodeIsAssigned = false; - node = nodes.node(); + node = nodes.next(); for (Map.Entry> entry : communities .entrySet()) { if (entry.getValue().containsKey(node)) { @@ -558,7 +552,6 @@ protected boolean areAllNodesAssigned(CustomGraph graph, allNodesAreAssigned = false; break; } - nodes.next(); } return allNodesAreAssigned; } @@ -577,19 +570,19 @@ protected boolean areAllNodesAssigned(CustomGraph graph, */ protected Cover getMembershipDegrees(CustomGraph graph, Map> communities) throws InterruptedException { - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), communities.size()); int communityIndex = 0; double membershipDegree; for (Node leader : communities.keySet()) { - membershipMatrix.set(leader.index(), communityIndex, 1.0); + membershipMatrix.set(leader.getIndex(), communityIndex, 1.0); for (Map.Entry entry : communities.get(leader) .entrySet()) { if(Thread.interrupted()) { throw new InterruptedException(); } membershipDegree = 1.0 / Math.pow(entry.getValue(), 2); - membershipMatrix.set(entry.getKey().index(), communityIndex, + membershipMatrix.set(entry.getKey().getIndex(), communityIndex, membershipDegree); } communityIndex++; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithm.java index c09d8883..c19a770e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithm.java @@ -6,20 +6,17 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import org.graphstream.graph.implementations.MultiNode; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; import org.la4j.vector.Vector; import org.la4j.vector.dense.BasicVector; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements SignedDMID algorithm by M. Shahriari, S. Krott, and R. Klamma: @@ -170,23 +167,23 @@ protected List getGlobalLeader(Map localLeader) throws Inte protected Map getLocalLeader(CustomGraph graph, Vector leadershipVector) throws InterruptedException { Map followerMap = new HashMap(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; /* * Iterates over all nodes to detect their local leader */ - while (nodes.ok()) { + while (nodesIt.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - double leadershipValue = leadershipVector.get(node.index()); + node = nodesIt.next(); + double leadershipValue = leadershipVector.get(node.getIndex()); boolean beingLeader = true; int followerDegree = 0; Set neighbours = graph.getNeighbours(node); for (Node neighbour : neighbours) { - if (leadershipValue < leadershipVector.get(neighbour.index())) { + if (leadershipValue < leadershipVector.get(neighbour.getIndex())) { beingLeader = false; break; } @@ -204,8 +201,8 @@ protected Map getLocalLeader(CustomGraph graph, Vector leadership } } if (ignoreReverse == false) { - if (node.getEdgeTo(neighbour) != null) { - if (graph.getEdgeWeight(node.getEdgeTo(neighbour)) > 0) { + if (node.getEdgeToward(neighbour) != null) { + if (graph.getEdgeWeight(node.getEdgeToward(neighbour)) > 0) { followerDegree++; ignoreReverse = true; } @@ -216,7 +213,6 @@ protected Map getLocalLeader(CustomGraph graph, Vector leadership followerMap.put(node, followerDegree); } - nodes.next(); } return followerMap; @@ -231,17 +227,17 @@ protected Map getLocalLeader(CustomGraph graph, Vector leadership * @throws InterruptedException if the thread was interrupted */ protected Vector getLeadershipVector(CustomGraph graph) throws InterruptedException { - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); Matrix nodeEDandDASS = new CCSMatrix(nodeCount, 3); Vector leadershipVector = new BasicVector(nodeCount); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; double effectiveDegreeValue; - while (nodes.ok()) { + while (nodesIt.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if (graph.getPositiveInDegree(node) + Math.abs(graph.getNegativeInDegree(node)) != 0) { if (graph.getPositiveInDegree(node) - Math.abs(graph.getNegativeInDegree(node)) < 0) { effectiveDegreeValue = 0; @@ -253,17 +249,16 @@ protected Vector getLeadershipVector(CustomGraph graph) throws InterruptedExcept } else { effectiveDegreeValue = 0; } - nodeEDandDASS.set(node.index(), 0, effectiveDegreeValue); + nodeEDandDASS.set(node.getIndex(), 0, effectiveDegreeValue); // Disassortativity, put denominator and nominator in different matrix columns. Set neighbours = graph.getNeighbours(node); - double nodeDegree = graph.getAbsoluteNodeDegree(node); + double nodeDegree = graph.getAbsoluteNodeDegree((MultiNode) node); double neighbourDegree = 0; for (Node neighbour : neighbours) { - neighbourDegree = graph.getAbsoluteNodeDegree(neighbour); - nodeEDandDASS.set(node.index(), 1, nodeEDandDASS.get(node.index(), 1) + nodeDegree + neighbourDegree); - nodeEDandDASS.set(node.index(), 2, nodeEDandDASS.get(node.index(), 2) + nodeDegree - neighbourDegree); + neighbourDegree = graph.getAbsoluteNodeDegree((MultiNode) neighbour); + nodeEDandDASS.set(node.getIndex(), 1, nodeEDandDASS.get(node.getIndex(), 1) + nodeDegree + neighbourDegree); + nodeEDandDASS.set(node.getIndex(), 2, nodeEDandDASS.get(node.getIndex(), 2) + nodeDegree - neighbourDegree); } - nodes.next(); } for (int i = 0; i < nodeCount; i++) { leadershipVector.set(i, @@ -357,7 +352,7 @@ protected Map executeLabelPropagation(CustomGraph graph, Node lea } else { profitability = 0; } - if (profitability >= profitabilityThreshold.get(neighbour.index())) { + if (profitability >= profitabilityThreshold.get(neighbour.getIndex())) { NodesAssumingNewLabel.add(neighbour); membershipsToAdd.put(neighbour, iterationCount); } @@ -388,7 +383,7 @@ protected Map executeLabelPropagation(CustomGraph graph, Node lea protected int getPosNodesWithNewLabel(CustomGraph graph, Node node, Set nodesNewLabel) throws InterruptedException { Set positiveNeighboursWithNewLabel = new HashSet(); - Set positiveNeighbours = graph.getPositiveNeighbours(node); + Set positiveNeighbours = graph.getPositiveNeighbours((MultiNode) node); for (Node positiveNeighbour : positiveNeighbours) { if (Thread.interrupted()) { throw new InterruptedException(); @@ -418,7 +413,7 @@ protected int getPosNodesWithNewLabel(CustomGraph graph, Node node, Set no protected int getNegNodesWithNewLabel(CustomGraph graph, Node node, Set nodesNewLabel) throws InterruptedException { Set negativeNeighboursWithNewLabel = new HashSet(); - Set negativeNeighbours = graph.getNegativeNeighbours(node); + Set negativeNeighbours = graph.getNegativeNeighbours((MultiNode) node); for (Node negativeNeighbour : negativeNeighbours) { if (Thread.interrupted()) { throw new InterruptedException(); @@ -443,17 +438,17 @@ protected int getNegNodesWithNewLabel(CustomGraph graph, Node node, Set no */ protected Cover getMembershipDegrees(CustomGraph graph, Map> communities) throws InterruptedException { - Matrix membershipMatrix = new CCSMatrix(graph.nodeCount(), communities.size()); + Matrix membershipMatrix = new CCSMatrix(graph.getNodeCount(), communities.size()); int communityIndex = 0; double membershipDegree; for (Node leader : communities.keySet()) { - membershipMatrix.set(leader.index(), communityIndex, 1.0); + membershipMatrix.set(leader.getIndex(), communityIndex, 1.0); for (Map.Entry entry : communities.get(leader).entrySet()) { if (Thread.interrupted()) { throw new InterruptedException(); } membershipDegree = 1.0 / Math.pow(entry.getValue(), 2); - membershipMatrix.set(entry.getKey().index(), communityIndex, membershipDegree); + membershipMatrix.set(entry.getKey().getIndex(), communityIndex, membershipDegree); } communityIndex++; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithm.java index 839bd051..f0b7cf59 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithm.java @@ -22,9 +22,9 @@ import i5.las2peer.services.ocd.graphs.CoverCreationType; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; import java.security.SecureRandom; @@ -201,7 +201,7 @@ public void initialProbabilitiesRandom(CustomGraph graph) { Random rndGenerator = new Random(); edgeProbabilities = new CCSMatrix(communityCount,communityCount); - nodeProbabilities = new CCSMatrix(communityCount,graph.nodeCount()); + nodeProbabilities = new CCSMatrix(communityCount,graph.getNodeCount()); // Set w_rs for(int r=0; r posEdgeHiddenCommProbs = new HashMap(); //q_ijr HashMap negEdgeHiddenCommProbs = new HashMap(); //Q_ijrs (r!=s), 0 (r=s) - for(Edge edge : graph.getEdgeArray()) { + for(Edge edge : graph.edges().toArray(Edge[]::new)) { if(graph.getEdgeWeight(edge) >= 0) { Vector positiveProbabilities = new BasicVector(communityCount); double previousEdgeProbsSum = 0.0; for(int r=0; r= 0) { edgeHiddenProbSums.set(r,r, edgeHiddenProbSums.get(r, r) + posEdgeHiddenCommProbs.get(edge).get(r) * graph.getEdgeWeight(edge)); // E_ij(q_ijr * A^+_ij) for w_rr - nodeHiddenProbSums.set(r, edge.source().index(), nodeHiddenProbSums.get(r, edge.source().index()) + posEdgeHiddenCommProbs.get(edge).get(r) * graph.getEdgeWeight(edge)); // E_j(q_ijr * A^+_ij) for 0_ri + nodeHiddenProbSums.set(r, edge.getSourceNode().getIndex(), nodeHiddenProbSums.get(r, edge.getSourceNode().getIndex()) + posEdgeHiddenCommProbs.get(edge).get(r) * graph.getEdgeWeight(edge)); // E_j(q_ijr * A^+_ij) for 0_ri } } } @@ -337,8 +337,8 @@ else if(r==s && graph.getEdgeWeight(edge) >= 0) } for(int r=0; r= 0) public double calculateLikelihood(CustomGraph graph) { double logLikelihood = 0.0; - for(Edge edge : graph.getEdgeArray()) { + for(Edge edge : graph.edges().toArray(Edge[]::new)) { double communityProbSum = 0.0; if(graph.getEdgeWeight(edge) < 0) { @@ -360,7 +360,7 @@ public double calculateLikelihood(CustomGraph graph) { for(int s=0; s 0 ? graph.getEdgeWeight(edge) : -graph.getEdgeWeight(edge)) * (communityProbSum == 0.0 ? -Double.MAX_VALUE : Math.log(communityProbSum)); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationAlgorithm.java index 46e9d1db..4d810988 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationAlgorithm.java @@ -24,8 +24,9 @@ import org.la4j.vector.Vector; import org.la4j.vector.sparse.CompressedVector; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements the original version of the Speaker Listener Label Propagation Algorithm by J. Xie, B. K. Szymanski, and X. Liu: @@ -132,12 +133,12 @@ public Cover detectOverlappingCommunities( List memory; for(int t=0; t+1> memories, List nodeOrder) { List memory; - for(int i=0; i(); memory.add(i); memories.add(memory); - nodeOrder.add(graph.getNodeArray()[i]); + nodeOrder.add(nodes[i]); } } @@ -164,15 +166,15 @@ protected void initializeCommunityDetection(CustomGraph graph, List> memories, Node listener) { + protected int getNextLabel(CustomGraph graph, List> memories, Node listener) throws InterruptedException { Map receivedLabels = new HashMap(); - NodeCursor speakers = listener.successors(); + Iterator speakersIt = graph.getSuccessorNeighbours(listener).iterator(); Node speaker; - while(speakers.ok()) { - speaker = speakers.node(); - receivedLabels.put(speaker, speakerRule.getLabel(graph, speaker, memories.get(speaker.index()))); - speakers.next(); + while(speakersIt.hasNext()) { + speaker = speakersIt.next(); + receivedLabels.put(speaker, speakerRule.getLabel(graph, speaker, memories.get(speaker.getIndex()))); } return listenerRule.getLabel(graph, listener, receivedLabels); } @@ -207,7 +209,7 @@ protected Cover calculateMembershipDegrees(CustomGraph graph, List /* * Adapts matrix size for new communities. */ - membershipMatrix = membershipMatrix.resize(graph.nodeCount(), nodeMembershipDegrees.length()); + membershipMatrix = membershipMatrix.resize(graph.getNodeCount(), nodeMembershipDegrees.length()); } membershipMatrix.setRow(i, nodeMembershipDegrees); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SskAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SskAlgorithm.java index 147e237e..06bc4400 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SskAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/SskAlgorithm.java @@ -5,13 +5,7 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; @@ -21,10 +15,9 @@ import org.la4j.vector.functor.VectorAccumulator; import org.la4j.vector.sparse.CompressedVector; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implement the algorithm by A. Stanoev, D. Smilkov, and L. Kocarev: @@ -160,38 +153,36 @@ protected Matrix calculateMemberships(CustomGraph graph, Map lead Matrix updatedMemberships = initMembershipMatrix(graph, leaders); Vector membershipContributionVector; Vector updatedMembershipVector; - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; - NodeCursor successors; + Iterator successorsIt; Node successor; double coefficient; int iteration = 0; do { memberships = updatedMemberships; updatedMemberships = new CCSMatrix(memberships.rows(), memberships.columns()); - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if(!leaders.keySet().contains(node)) { - successors = node.successors(); + successorsIt = graph.getSuccessorNeighbours(node).iterator(); updatedMembershipVector = new CompressedVector(memberships.columns()); - while(successors.ok()) { - successor = successors.node(); - coefficient = coefficients.get(successor.index(), node.index()); - membershipContributionVector = memberships.getRow(successor.index()).multiply(coefficient); + while(successorsIt.hasNext()) { + successor = successorsIt.next(); + coefficient = coefficients.get(successor.getIndex(), node.getIndex()); + membershipContributionVector = memberships.getRow(successor.getIndex()).multiply(coefficient); updatedMembershipVector = updatedMembershipVector.add(membershipContributionVector); - successors.next(); } - updatedMemberships.setRow(node.index(), updatedMembershipVector); + updatedMemberships.setRow(node.getIndex(), updatedMembershipVector); } else { - updatedMemberships.set(node.index(), leaders.get(node), 1); + updatedMemberships.set(node.getIndex(), leaders.get(node), 1); } - nodes.next(); } - nodes.toFirst(); + nodesIt = graph.iterator(); iteration++; } while (getMaxDifference(updatedMemberships, memberships) > membershipsPrecisionFactor && iteration < membershipsIterationBound); @@ -235,23 +226,22 @@ protected double getMaxDifference(Matrix matA, Matrix matB) throws InterruptedEx */ protected Matrix initMembershipMatrix(CustomGraph graph, Map leaders) throws InterruptedException { int communityCount = Collections.max(leaders.values()) + 1; - Matrix memberships = new CCSMatrix(graph.nodeCount(), communityCount); - NodeCursor nodes = graph.nodes(); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), communityCount); + Iterator nodesIt = graph.iterator(); Node node; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); + node = nodesIt.next(); if(leaders.keySet().contains(node)) { - memberships.set(node.index(), leaders.get(node), 1); + memberships.set(node.getIndex(), leaders.get(node), 1); } else { for(int i=0; i lead * @throws InterruptedException if the thread was interrupted */ protected Matrix initMembershipCoefficientMatrix(CustomGraph graph, Map leaders) throws InterruptedException { - Matrix coefficients = new CCSMatrix(graph.nodeCount(), graph.nodeCount()); - EdgeCursor edges = graph.edges(); + Matrix coefficients = new CCSMatrix(graph.getNodeCount(), graph.getNodeCount()); + Iterator edgesIt = graph.edges().iterator(); Edge edge; - while(edges.ok()) { + while(edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - coefficients.set(edge.target().index(), edge.source().index(), graph.getEdgeWeight(edge)); - edges.next(); + edge = edgesIt.next(); + coefficients.set(edge.getTargetNode().getIndex(), edge.getSourceNode().getIndex(), graph.getEdgeWeight(edge)); } Vector column; double norm; @@ -303,9 +292,9 @@ protected Matrix initMembershipCoefficientMatrix(CustomGraph graph, Map determineGlobalLeaders(CustomGraph graph, Matrix transitionMatrix, Vector totalInfluences) throws InterruptedException{ - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; - NodeCursor successors; + Iterator successorsIt; Node successor; double relativeInfluence; double maxRelativeInfluence; @@ -315,17 +304,17 @@ protected Map determineGlobalLeaders(CustomGraph graph, Matrix tr double nodeInfluenceOnNeighbor; double neighborInfluenceOnNode; int communityCount = 0; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - successors = node.successors(); + node = nodesIt.next(); + successorsIt = graph.getSuccessorNeighbours(node).iterator(); maxRelativeInfluence = Double.NEGATIVE_INFINITY; maxRelativeInfluenceNeighbors = new ArrayList(); - while(successors.ok()) { - successor = successors.node(); - relativeInfluence = transitionMatrix.get(successor.index(), node.index()); + while(successorsIt.hasNext()) { + successor = successorsIt.next(); + relativeInfluence = transitionMatrix.get(successor.getIndex(), node.getIndex()); if(relativeInfluence >= maxRelativeInfluence) { if(relativeInfluence > maxRelativeInfluence) { maxRelativeInfluenceNeighbors.clear(); @@ -333,15 +322,14 @@ protected Map determineGlobalLeaders(CustomGraph graph, Matrix tr } maxRelativeInfluenceNeighbors.add(successor); } - successors.next(); } currentCommunityLeaders = new ArrayList(); currentCommunityLeaders.add(node); for(int i=0; i nodeInfluenceOnNeighbor) { /* @@ -354,7 +342,7 @@ else if (neighborInfluenceOnNode == nodeInfluenceOnNeighbor) { /* * There are potentially several community leaders. */ - if(maxRelativeInfluenceNeighbor.index() < node.index()) { + if(maxRelativeInfluenceNeighbor.getIndex() < node.getIndex()) { /* * Will detected community leaders only once in the iteration over the * node with the lowest index. @@ -377,7 +365,6 @@ else if (neighborInfluenceOnNode == nodeInfluenceOnNeighbor) { if(currentCommunityLeaders.size() > 0) { communityCount++; } - nodes.next(); } return communityLeaders; } @@ -412,23 +399,21 @@ protected Vector executeRandomWalk(Matrix transitionMatrix) throws InterruptedEx * @throws InterruptedException if the thread was interrupted */ protected Matrix calculateTransitionMatrix(CustomGraph graph) throws InterruptedException { - Matrix transitionMatrix = new CCSMatrix(graph.nodeCount(), graph.nodeCount()); - NodeCursor nodes = graph.nodes(); + Matrix transitionMatrix = new CCSMatrix(graph.getNodeCount(), graph.getNodeCount()); + Iterator nodesIt = graph.iterator(); Node node; - NodeCursor predecessors; + Iterator predecessorsIt; Node predecessor; - while(nodes.ok()) { + while(nodesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - node = nodes.node(); - predecessors = node.predecessors(); - while(predecessors.ok()) { - predecessor = predecessors.node(); - transitionMatrix.set(node.index(), predecessor.index(), calculateTransitiveLinkWeight(graph, node, predecessor)); - predecessors.next(); + node = nodesIt.next(); + predecessorsIt = graph.getPredecessorNeighbours(node).iterator(); + while(predecessorsIt.hasNext()) { + predecessor = predecessorsIt.next(); + transitionMatrix.set(node.getIndex(), predecessor.getIndex(), calculateTransitiveLinkWeight(graph, node, predecessor)); } - nodes.next(); } Vector column; double norm; @@ -452,31 +437,31 @@ protected Matrix calculateTransitionMatrix(CustomGraph graph) throws Interrupted * @param target The link target. * @param source The link source. * @return The transitive link weight from source to target. + * @throws InterruptedException If the executing thread was interrupted. */ - protected double calculateTransitiveLinkWeight(CustomGraph graph, Node target, Node source) { - NodeCursor successors = source.successors(); + protected double calculateTransitiveLinkWeight(CustomGraph graph, Node target, Node source) throws InterruptedException { + Iterator successorsIt = graph.getSuccessorNeighbours(source).iterator(); Node successor; double transitiveLinkWeight = 0; double linkWeight; Edge targetEdge; - while(successors.ok()) { - successor = successors.node(); + while(successorsIt.hasNext()) { + successor = successorsIt.next(); if(successor != target) { - targetEdge = successor.getEdgeTo(target); + targetEdge = successor.getEdgeToward(target); if(targetEdge != null) { /* * Contribution to the transitive link weight is chosen as the minimum weight * of the two triangle edges. */ - linkWeight = graph.getEdgeWeight(source.getEdgeTo(successor)); + linkWeight = graph.getEdgeWeight(source.getEdgeToward(successor)); linkWeight = Math.min(linkWeight, graph.getEdgeWeight(targetEdge)); transitiveLinkWeight += linkWeight; } } else { - transitiveLinkWeight += graph.getEdgeWeight(source.getEdgeTo(target)); + transitiveLinkWeight += graph.getEdgeWeight(source.getEdgeToward(target)); } - successors.next(); } return transitiveLinkWeight; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithm.java index 90140ec9..9510a853 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithm.java @@ -12,13 +12,12 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.metrics.OcdMetricException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import y.base.Edge; -import y.base.EdgeCursor; + +import java.util.*; + +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * This class holds weak clique percolation algorithm, implementation of which @@ -91,7 +90,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) Cover resulting_cover = new Cover(graph, community_matrix); - System.out.println("****** Number of found communities: " + identified_communities.size() + " ******"); + //System.out.println("****** Number of found communities: " + identified_communities.size() + " ******"); return resulting_cover; } @@ -594,19 +593,17 @@ public Map.Entry findMaxEntryKey(HashMap map) */ public Matrix createAdjacencyMatrix(CustomGraph graph) { - Matrix A = new Basic2DMatrix(graph.nodeCount(), graph.nodeCount()); + Matrix A = new Basic2DMatrix(graph.getNodeCount(), graph.getNodeCount()); A = A.blank(); // create an empty matrix of size n - EdgeCursor edge_list = graph.edges(); // added - - while (edge_list.ok()) { + Iterator edge_list = graph.edges().iterator(); // added - Edge edge = edge_list.edge(); + while (edge_list.hasNext()) { - A.set(edge.source().index(), edge.target().index(), graph.getEdgeWeight(edge)); + Edge edge = edge_list.next(); - edge_list.next(); + A.set(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), graph.getEdgeWeight(edge)); } return A; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithm.java index 66b6b3c2..81075019 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithm.java @@ -6,14 +6,8 @@ import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.utils.Pair; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; @@ -21,10 +15,9 @@ import org.la4j.vector.Vectors; import org.la4j.vector.sparse.CompressedVector; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * The original weighted version of the Link Communities Algorithm by Y.-Y. Ahn, J. P. Bagrow, and S. Lehmann: @@ -142,7 +135,7 @@ public Cover detectOverlappingCommunities(CustomGraph graph) throws InterruptedE * the entry S_ij. */ private Matrix calculateEdgeSimilarities(CustomGraph graph, List linkageDegrees) throws InterruptedException { - Matrix similarities = new CCSMatrix(graph.edgeCount(), graph.edgeCount()); + Matrix similarities = new CCSMatrix(graph.getEdgeCount(), graph.getEdgeCount()); List squaredNorms = new ArrayList(); double norm; Vector vec; @@ -151,12 +144,12 @@ private Matrix calculateEdgeSimilarities(CustomGraph graph, List linkage norm = vec.fold(Vectors.mkEuclideanNormAccumulator()); squaredNorms.add(Math.pow(norm, 2)); } - EdgeCursor rowEdges = graph.edges(); + Iterator rowEdgesIt = graph.edges().iterator(); Edge rowEdge; Node source; Node target; Vector rowEdgeVec; - EdgeCursor columnEdges; + Iterator columnEdgesIt; Edge columnEdge; Edge reverseRowEdge; Edge reverseColumnEdge; @@ -165,61 +158,58 @@ private Matrix calculateEdgeSimilarities(CustomGraph graph, List linkage double innerProduct; double similarity; int columnEdgeNodeIndex; - while(rowEdges.ok()) { + while(rowEdgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - rowEdge = rowEdges.edge(); - source = rowEdge.source(); - target = rowEdge.target(); - rowEdgeVec = linkageDegrees.get(source.index()); - reverseRowEdge = target.getEdgeTo(source); + rowEdge = rowEdgesIt.next(); + source = rowEdge.getSourceNode(); + target = rowEdge.getTargetNode(); + rowEdgeVec = linkageDegrees.get(source.getIndex()); + reverseRowEdge = target.getEdgeToward(source); /* * Sets similarities only if they have not been set already for the reverse Edge. */ - if(reverseRowEdge == null || rowEdge.index() < reverseRowEdge.index()) { + if(reverseRowEdge == null || rowEdge.getIndex() < reverseRowEdge.getIndex()) { /* * Sets similarities for in and out edges of the row edge target node. */ - edgeIndices.add(rowEdge.index()); - columnEdges = target.edges(); - while(columnEdges.ok()) { - columnEdge = columnEdges.edge(); - if(columnEdge.index() < rowEdge.index()) { - reverseColumnEdge = columnEdge.target().getEdgeTo(columnEdge.source()); - if(reverseColumnEdge == null || columnEdge.index() < reverseColumnEdge.index()) { - columnEdgeNodeIndex = columnEdge.opposite(target).index(); + edgeIndices.add(rowEdge.getIndex()); + columnEdgesIt = target.edges().iterator(); + while(columnEdgesIt.hasNext()) { + columnEdge = columnEdgesIt.next(); + if(columnEdge.getIndex() < rowEdge.getIndex()) { + reverseColumnEdge = columnEdge.getTargetNode().getEdgeToward(columnEdge.getSourceNode()); + if(reverseColumnEdge == null || columnEdge.getIndex() < reverseColumnEdge.getIndex()) { + columnEdgeNodeIndex = columnEdge.getOpposite(target).getIndex(); columnEdgeVec = linkageDegrees.get(columnEdgeNodeIndex); innerProduct = rowEdgeVec.innerProduct(columnEdgeVec); - similarity = innerProduct / (squaredNorms.get(source.index()) + similarity = innerProduct / (squaredNorms.get(source.getIndex()) + squaredNorms.get(columnEdgeNodeIndex) - innerProduct); - similarities.set(rowEdge.index(), columnEdge.index(), similarity); + similarities.set(rowEdge.getIndex(), columnEdge.getIndex(), similarity); } } - columnEdges.next(); } /* * Sets similarities for in edges of the row edge source node. * If a reverse edge of the row edge exists, it is set for the out edges also. */ - columnEdges = source.edges(); - while(columnEdges.ok()) { - columnEdge = columnEdges.edge(); - if(columnEdge.index() < rowEdge.index() && columnEdge.source() != target) { - reverseColumnEdge = columnEdge.target().getEdgeTo(columnEdge.source()); - if(reverseColumnEdge == null || columnEdge.index() < reverseColumnEdge.index()) { - columnEdgeNodeIndex = columnEdge.opposite(source).index(); + columnEdgesIt = source.edges().iterator(); + while(columnEdgesIt.hasNext()) { + columnEdge = columnEdgesIt.next(); + if(columnEdge.getIndex() < rowEdge.getIndex() && columnEdge.getSourceNode() != target) { + reverseColumnEdge = columnEdge.getTargetNode().getEdgeToward(columnEdge.getSourceNode()); + if(reverseColumnEdge == null || columnEdge.getIndex() < reverseColumnEdge.getIndex()) { + columnEdgeNodeIndex = columnEdge.getOpposite(source).getIndex(); columnEdgeVec = linkageDegrees.get(columnEdgeNodeIndex); innerProduct = rowEdgeVec.innerProduct(columnEdgeVec); - similarity = innerProduct / (squaredNorms.get(target.index()) + similarity = innerProduct / (squaredNorms.get(target.getIndex()) + squaredNorms.get(columnEdgeNodeIndex) - innerProduct); - similarities.set(rowEdge.index(), columnEdge.index(), similarity); + similarities.set(rowEdge.getIndex(), columnEdge.getIndex(), similarity); } } - columnEdges.next(); } } - rowEdges.next(); } int[] indices = new int[edgeIndices.size()]; for(int i=0; i linkage */ private List calculateLinkageDegrees(CustomGraph graph) throws InterruptedException { List linkageDegrees = new ArrayList(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Vector degreeVector; Node node; Node neighbor; - EdgeCursor edges; + Iterator edgesIt; Edge edge; double linkageDegree; double neutral; double averageWeight; - while(nodes.ok()) { - degreeVector = new CompressedVector(graph.nodeCount()); - node = nodes.node(); - edges = node.edges(); - while(edges.ok()) { + while(nodesIt.hasNext()) { + degreeVector = new CompressedVector(graph.getNodeCount()); + node = nodesIt.next(); + edgesIt = node.edges().iterator(); + while(edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - neighbor = edges.edge().opposite(node); - linkageDegree = degreeVector.get(neighbor.index()); - linkageDegree += graph.getEdgeWeight(edge) / node.degree(); - degreeVector.set(neighbor.index(), linkageDegree); - edges.next(); + edge = edgesIt.next(); + neighbor = edge.getOpposite(node); + linkageDegree = degreeVector.get(neighbor.getIndex()); + linkageDegree += graph.getEdgeWeight(edge) / node.getDegree(); + degreeVector.set(neighbor.getIndex(), linkageDegree); } /* * Calculates the entry corresponding the node index as the average weight @@ -274,9 +263,8 @@ private List calculateLinkageDegrees(CustomGraph graph) throws Interrupt */ neutral = 0; averageWeight = degreeVector.fold(Vectors.asSumAccumulator(neutral)); - degreeVector.set(node.index(), averageWeight); + degreeVector.set(node.getIndex(), averageWeight); linkageDegrees.add(degreeVector); - nodes.next(); } return linkageDegrees; } @@ -402,18 +390,18 @@ private Matrix updateSimilarities(Matrix similarities, Pair mo */ private void initDendrogramCreation(CustomGraph graph, List> communityEdges, List> communityNodes, List communityLinkDensities) throws InterruptedException { - EdgeCursor edges = graph.edges(); + Iterator edgesIt = graph.edges().iterator(); Set initEdgeSet; Set initNodeSet; Edge edge; Edge reverseEdge; - while(edges.ok()) { + while(edgesIt.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - reverseEdge = edge.target().getEdgeTo(edge.source()); - if(reverseEdge == null || edge.index() < reverseEdge.index()) { + edge = edgesIt.next(); + reverseEdge = edge.getTargetNode().getEdgeToward(edge.getSourceNode()); + if(reverseEdge == null || edge.getIndex() < reverseEdge.getIndex()) { initEdgeSet = new HashSet(); initEdgeSet.add(edge); if(reverseEdge != null) { @@ -421,12 +409,11 @@ private void initDendrogramCreation(CustomGraph graph, List> community } communityEdges.add(initEdgeSet); initNodeSet = new HashSet(); - initNodeSet.add(edge.source()); - initNodeSet.add(edge.target()); + initNodeSet.add(edge.getSourceNode()); + initNodeSet.add(edge.getTargetNode()); communityNodes.add(initNodeSet); communityLinkDensities.add(0d); } - edges.next(); } } @@ -448,7 +435,7 @@ private double calculateLinkDensity(int edgeCount, int nodeCount) { * @return A normalized cover of the graph. */ private Cover calculatePartitionCover(CustomGraph graph, List> partition) throws InterruptedException { - Matrix memberships = new CCSMatrix(graph.nodeCount(), partition.size()); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), partition.size()); double belongingFactor; double edgeWeight; for(int i=0; i> partiti throw new InterruptedException(); } edgeWeight = graph.getEdgeWeight(edge); - belongingFactor = memberships.get(edge.target().index(), i) + edgeWeight; - memberships.set(edge.target().index(), i, belongingFactor); - belongingFactor = memberships.get(edge.source().index(), i) + edgeWeight; - memberships.set(edge.source().index(), i, belongingFactor); + belongingFactor = memberships.get(edge.getTargetNode().getIndex(), i) + edgeWeight; + memberships.set(edge.getTargetNode().getIndex(), i, belongingFactor); + belongingFactor = memberships.get(edge.getSourceNode().getIndex(), i) + edgeWeight; + memberships.set(edge.getSourceNode().getIndex(), i, belongingFactor); } } return new Cover(graph, memberships); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WordClusteringRefinementAlgorithm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WordClusteringRefinementAlgorithm.java index 7472e403..5970f298 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WordClusteringRefinementAlgorithm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/WordClusteringRefinementAlgorithm.java @@ -22,7 +22,8 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.metrics.ExecutionTime; -import y.base.Node; + +import org.graphstream.graph.Node; /** * Implements one of the algorithms by Sabrina Haefele conceived in the thesis: diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Individual.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Individual.java index 7fd8e6ac..15ba8ac8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Individual.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Individual.java @@ -61,7 +61,7 @@ public static void eval_individual(Individual ind){ * as the genotype here is the label * the genotype array will NOT be copied * @param gene Gene array - * @return The newly created individual + * @return Newly created individual instance */ public static Individual new_individual(int[] gene){ diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Random.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Random.java index bd707630..19f7abcb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Random.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/mea/Random.java @@ -5,7 +5,7 @@ public class Random { /** * @param p Input array * @param n Input index - * @return The shuffled array + * @return Shuffled input array */ public static int[] shuffle(int[] p, int n) { int i; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Cluster.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Cluster.java index a364ee31..1f4b0f68 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Cluster.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Cluster.java @@ -6,7 +6,7 @@ import org.apache.commons.math3.linear.ArrayRealVector; -import y.base.Node; +import org.graphstream.graph.Node; public class Cluster { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Clustering.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Clustering.java index aafd3862..515dbc07 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Clustering.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Clustering.java @@ -7,7 +7,7 @@ import org.la4j.matrix.dense.Basic2DMatrix; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; +import org.graphstream.graph.Node; public class Clustering { private double costs; @@ -54,14 +54,14 @@ public void addCluster(Cluster c){ /////////////////////////// public Matrix createMembershipMatrix(CustomGraph graph) { - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), this.cluster.size()); int communityIndex = 0; for(Iterator it = cluster.iterator(); it.hasNext();){ Cluster curr = it.next(); for(Iterator itp = curr.getPoints().iterator(); itp.hasNext();){ Point p = itp.next(); - membershipMatrix.set(p.getNode().index(), communityIndex, 1.0); + membershipMatrix.set(p.getNode().getIndex(), communityIndex, 1.0); } communityIndex++; } @@ -69,12 +69,12 @@ public Matrix createMembershipMatrix(CustomGraph graph) { } public Matrix createMembershipMatrixNode(CustomGraph graph){ - Matrix membershipMatrix = new Basic2DMatrix(graph.nodeCount(), this.cluster.size()); + Matrix membershipMatrix = new Basic2DMatrix(graph.getNodeCount(), this.cluster.size()); int communityIndex = 0; for(Iterator it = cluster.iterator(); it.hasNext();){ Cluster curr = it.next(); for(Node node: curr.getNodes()){ - membershipMatrix.set(node.index(), communityIndex, 1.0); + membershipMatrix.set(node.getIndex(), communityIndex, 1.0); } communityIndex++; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/LouvainGraphBuilder.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/LouvainGraphBuilder.java index 54ab24d9..16c841ea 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/LouvainGraphBuilder.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/LouvainGraphBuilder.java @@ -23,9 +23,9 @@ of this software and associated documentation files (the "Software"), to deal import i5.las2peer.services.ocd.algorithms.utils.LouvainSparseIntMatrix; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; import java.util.ArrayList; import java.util.Iterator; @@ -56,20 +56,20 @@ public class LouvainGraphBuilder { */ public LouvainGraph fromGraph(CustomGraph graph) throws InterruptedException, OcdAlgorithmException{ - order = graph.nodeCount(); + order = graph.getNodeCount(); initialise(); - - for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) { + Iterator ec = graph.edges().iterator(); + while (ec.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - Node source = edge.source(); - Node target = edge.target(); + Edge edge = ec.next(); + Node source = edge.getSourceNode(); + Node target = edge.getTargetNode(); - if (matrix.get(source.index(), target.index()) == 0) { - insertEdgeSym(source.index(), target.index(), (int) graph.getEdgeWeight(edge)); + if (matrix.get(source.getIndex(), target.getIndex()) == 0) { + insertEdgeSym(source.getIndex(), target.getIndex(), (int) graph.getEdgeWeight(edge)); } } @@ -139,7 +139,7 @@ public LouvainGraphBuilder setSize(int order) * @return This LouvaingraphBuilder * @throws OcdAlgorithmException if the execution failed */ - public LouvainGraphBuilder addEdge(int n1, int n2, int weight) + public LouvainGraphBuilder addEdge(int n1, int n2, int weight) throws OcdAlgorithmException { if (n1 >= order) { throw new OcdAlgorithmException("" + n1 + " >= " + order); @@ -172,6 +172,7 @@ public LouvainGraph coarseGrain(LouvainGraph g, HashMap map) this.layer = g.layer() + 1; initialise(); int sum = 0; + int negatives = 0; for (final Iterator> it = g.partitioning().commWeightIterator(); it.hasNext(); ) { if(Thread.interrupted()) { @@ -181,15 +182,21 @@ public LouvainGraph coarseGrain(LouvainGraph g, HashMap map) Entry entry = it.next(); final int weight = entry.getValue(); long cmMatrixSize = g.partitioning().cMatrix().size(); - if (weight != 0) { + if (weight > 0) { final int n1 = map.get(g.partitioning().cMatrix().sparseX(entry, cmMatrixSize)); final int n2 = map.get(g.partitioning().cMatrix().sparseY(entry, cmMatrixSize)); insertEdge(n1, n2, (int)weight); sum += weight; } + else{ + // TODO: is this is correct? This part is necessary to avoid crash + if ( weight < 0){ + negatives += weight; + } + } } - if (sum != g.size() * 2) { + if ((sum + negatives) != g.size() * 2) { throw new OcdAlgorithmException("Louvain graph builder recieved wrong weights: " + sum + " " + (g.size() * 2)); } if (sum != sizeDbl) { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkAgent.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkAgent.java new file mode 100644 index 00000000..c2bfb9b4 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkAgent.java @@ -0,0 +1,48 @@ +package i5.las2peer.services.ocd.algorithms.utils; + +import java.util.ArrayList; +import java.util.Random; + +/** + * An Agent consists of 6 Individuals with 1 Pocket individual which is the best one of the agent + */ +public class MLinkAgent{ + + private ArrayList individuals; + private MLinkIndividual pocket; + + public MLinkAgent(){ + individuals = new ArrayList(); + pocket = new MLinkIndividual(); + } + public MLinkIndividual getPocket(){ + return pocket; + } + public void setPocket(MLinkIndividual pocket){ + this.pocket = pocket; + } + + public ArrayList getIndividuals(){ + return individuals; + } + + /** + * New Offspring is added to the agent either as the pocket individual or just a normal individual + * @param individual New Offspring + */ + public void addIndividual(MLinkIndividual individual){ + if(this.individuals.isEmpty() || individual.getFitness() > pocket.getFitness()){ + this.pocket = individual; + individuals.add(0, individual); + } else { + individuals.add(1, individual); + } + if(this.individuals.size() > individuals.size()){ + this.individuals.remove(this.individuals.size() - 1); + } + } + + public MLinkIndividual getRandomIndividual(){ + return this.individuals.get(new Random().nextInt(individuals.size())); + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkIndividual.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkIndividual.java new file mode 100644 index 00000000..c58abb62 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkIndividual.java @@ -0,0 +1,379 @@ +package i5.las2peer.services.ocd.algorithms.utils; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +import org.apache.jena.sparql.pfunction.library.assign; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + +import java.util.ArrayList; + +/** + * An Individual is displayed as a set of edges with the genes and the fitnes of that individual + */ +public class MLinkIndividual { + + private HashMap individual; + private double fitness; + private HashMap edges; + private HashMap> communities; + private HashMap> nodeCommunity; + private double edgeNr; + + // Constructors + public MLinkIndividual(){ + individual = new HashMap(); + communities = new HashMap>(); + edges = new HashMap(); + nodeCommunity = new HashMap>(); + edgeNr = 0; + fitness = 0; + } + public MLinkIndividual(HashMap individual){ + this.individual = new HashMap(); + communities = new HashMap>(); + nodeCommunity = new HashMap>(); + edges = new HashMap(); + this.individual = individual; + edgeNr = individual.size(); + calcCommunities(); + calcFitness(); + } + // Getter and Setter + public HashMap getIndividual(){ + return individual; + } + public void addGene(Edge locus, Edge geneValue){ + this.individual.put(locus, geneValue); + this.edgeNr = this.individual.size(); + } + public double getFitness(){ + return fitness; + } + public void setFitness(double fitness){ + this.fitness = fitness; + } + + public void setIndividual(HashMap individual){ + this.individual = individual; + this.edgeNr = this.individual.size(); + } + public HashMap> getCommunities(){ + return this.communities; + } + public HashMap> getNodeCommunity(){ + return this.nodeCommunity; + } + + // Public methods for Individuals + /** + * Claculates fitness + */ + public void calcFitness(){ + double fit = 0; + double nodeNr; + for(Integer i : this.communities.keySet()){ + double edges = this.communities.get(i).size(); + nodeNr = this.nodeCommunity.get(i).size(); + if(nodeNr < 3){ + fit = fit + 0; + } else { + fit = fit + edges*( (edges-(nodeNr - 1.0 )) / ((nodeNr - 2.0) * (nodeNr - 1.0)) ); + } + + } + if(this.edgeNr != 0){ + this.fitness = (2.0/this.edgeNr)*fit; + } else { + this.fitness = 0; + } + + } + private double deltaFitness(HashMap> uCommunities, HashMap> uNodeCommunity){ + double fit = 0; + double nodeNr; + double uFitness = 0; + for(Integer i : uCommunities.keySet()){ + double edges = uCommunities.get(i).size(); + nodeNr = uNodeCommunity.get(i).size(); + if(nodeNr < 3){ + fit = fit + 0; + } else { + fit = fit + edges*( (edges-(nodeNr - 1.0 )) / ((nodeNr - 2.0) * (nodeNr - 1.0)) ); + } + + } + if(this.edgeNr != 0){ + uFitness = (2.0/this.edgeNr)*fit; + } else { + uFitness = 0; + } + return uFitness; + } + /** + * Saves the communities as ArrayLists + */ + public void calcCommunities(){ + this.communities.clear(); + this.nodeCommunity.clear(); + // Initialize every edge with -1 as community + HashMap assignCommunity = new HashMap(); + // System.out.println("ind Edges: " + this.individual.keySet().size()); + for(Edge e : this.individual.keySet()){ + assignCommunity.put(e,-1); + } + // Backtracking algorithm + int current = 0; + this.communities.put(current, new HashSet()); + this.nodeCommunity.put(current, new HashSet()); + for(Edge e : this.individual.keySet()){ + ArrayList previous = new ArrayList(); + int tracing = 0; + + // If edge is not assigned yet + if(assignCommunity.get(e).equals(-1)){ + assignCommunity.put(e, current); + // Fill in different versions of community representation + this.communities.get(current).add(e); + this.nodeCommunity.get(current).add(e.getTargetNode()); + this.nodeCommunity.get(current).add(e.getSourceNode()); + Edge neighbor = this.individual.get(e); + previous.add(e); + tracing++; + + // Assign gene to the locus community + while(assignCommunity.get(neighbor).equals(-1)){ + previous.add(neighbor); + assignCommunity.put(neighbor,current); + + this.communities.get(current).add(neighbor); + this.nodeCommunity.get(current).add(neighbor.getTargetNode()); + this.nodeCommunity.get(current).add(neighbor.getSourceNode()); + + neighbor = this.individual.get(neighbor); + tracing++; + } + int neighborCommunity = assignCommunity.get(neighbor); + // If gene is in different community -> assign the whole community to the gene's + if(neighborCommunity != current){ + tracing = tracing - 1; + this.communities.get(current).clear(); + this.nodeCommunity.get(current).clear(); + while(tracing >= 0){ + Edge prev = previous.get(tracing); + assignCommunity.put(prev, neighborCommunity); + + this.communities.get(neighborCommunity).add(prev); + this.nodeCommunity.get(neighborCommunity).add(prev.getTargetNode()); + this.nodeCommunity.get(neighborCommunity).add(prev.getSourceNode()); + + tracing = tracing - 1; + } + } else { + current++; + this.communities.put(current, new HashSet()); + this.nodeCommunity.put(current, new HashSet()); + } + } + } + this.edges = assignCommunity; + this.communities.remove(current); + this.nodeCommunity.remove(current); + + } + + /** + * Mutates the individual with a mutation probability + * @param mutationProbability mutation probability + */ + public void mutate(int mutationProbability){ + HashMap genes = this.individual; + Random rand = new Random(); + for(Edge key : genes.keySet()){ + if(rand.nextInt(100) < mutationProbability){ + Edge gene = genes.get(key); + Set neighbors = new HashSet(); + Edge[] targetEdges = key.getTargetNode().edges().toArray(Edge[]::new); + int nghbSizeTrgt = targetEdges.length; + for(int i = 0; i < nghbSizeTrgt; i++){ + if(targetEdges[i] != key && targetEdges[i] != gene){ + neighbors.add(targetEdges[i]); + } + + } + Edge[] srcEdges = key.getSourceNode().edges().toArray(Edge[]::new); + int nghbSizeSrc = srcEdges.length; + for(int i = 0; i < nghbSizeSrc; i++){ + if(srcEdges[i] != key && srcEdges[i] != gene){ + neighbors.add(srcEdges[i]); + } + + } + int indSize = neighbors.size(); + if(indSize > 0){ + int edge = new Random().nextInt(indSize); + int i = 0; + for(Edge e : neighbors){ + if(i == edge){ + if(e != null){ + genes.put(key, e); + } + + } + i++; + } + } + } + } + this.individual = genes; + this.calcCommunities(); + this.calcFitness(); + } + /** + * If the fitness increases with a community change, update the communities. + * @param edge1 edge that changes community + * @param edge2 community where edge 1 will be inserted + * @return true if it updated false if not + */ + private boolean updateCommunities(Edge edge1, Edge edge2){ + // Copy current communities and code communities + HashMap> uCommunities = new HashMap<>(this.communities); + HashMap> uNodeCommunity = new HashMap<>(this.nodeCommunity); + + int community1 = this.edges.get(edge1); + int community2 = this.edges.get(edge2); + + for(Integer i : this.communities.keySet()){ + uCommunities.put(i, new HashSet(this.communities.get(i))); + uNodeCommunity.put(i, new HashSet(this.nodeCommunity.get(i))); + } + + // remove edge from its community and add to neighbor community + boolean deleted = false; + uCommunities.get(community1).remove(edge1); + if(uCommunities.get(community1).isEmpty()){ + uCommunities.remove(community1); + deleted = true; + } + uCommunities.get(community2).add(edge1); + + + Edge[] edges = edge1.getSourceNode().edges().toArray(Edge[]::new); + int cyclicNext = 0; + for(int i = 0; i < edges.length; i++){ + Edge e = edges[cyclicNext]; + if(e != edge1 && this.edges.get(e) == community1){ + break; + } + if(i == edges.length-1){ + uNodeCommunity.get(community1).remove(edge1.getSourceNode()); + } + cyclicNext++; + if (cyclicNext >= edges.length){ + cyclicNext = 0; + } + } + edges = edge1.getTargetNode().edges().toArray(Edge[]::new); + cyclicNext = 0; + for(int i = 0; i < edges.length; i++){ + Edge e = edges[cyclicNext]; + if(e != edge1 && this.edges.get(e) == community1){ + break; + } + if(i == edges.length-1){ + uNodeCommunity.get(community1).remove(edge1.getTargetNode()); + } + cyclicNext++; + if (cyclicNext >= edges.length){ + cyclicNext = 0; + } + } + + HashSet tmp = uNodeCommunity.get(community1); + tmp = uNodeCommunity.get(community2); + tmp.add(edge1.getSourceNode()); + tmp.add(edge1.getTargetNode()); + + // if the fitness improves rearrange the genes + double uFitness = deltaFitness(uCommunities, uNodeCommunity); + if(uFitness - this.fitness > 0){ + this.edges.put(edge1, community2); + this.communities = uCommunities; + this.nodeCommunity = uNodeCommunity; + this.individual.put(edge1, edge2); + this.fitness = uFitness; + if(!deleted){ + rearrange: + for(Edge e : this.communities.get(community1)){ + if(this.individual.get(e) == edge1){ + Edge[] srcNgh = e.getSourceNode().edges().toArray(Edge[]::new); + Edge[] trgNgh = e.getTargetNode().edges().toArray(Edge[]::new); + + if(this.communities.get(community1).size() == 1){ + this.individual.put(e,e); + break; + } + + for(int i = 0; i < srcNgh.length; i++){ + Edge srcEdge = trgNgh[i]; + if(this.edges.get(srcEdge) == community1 && srcEdge != e){ + this.individual.put(e,srcEdge); + continue rearrange; + } + + } + + for(int i = 0; i < trgNgh.length; i++){ + Edge trgEdge = trgNgh[i]; + if(this.edges.get(trgEdge) == community1 && trgEdge != e){ + this.individual.put(e, trgEdge); + continue rearrange; + } + + } + } + } + } + return true; + } else { + return false; + } + } + + /** + * Local Search to improve fitness by checking for every edge if changing + * the gene would improve fitness + */ + public void localSearch(){ + Genes: + for(Edge key : this.individual.keySet()){ + Edge[] tgtNeighbors = key.getTargetNode().edges().toArray(Edge[]::new); + Edge[] srcNeighbors = key.getSourceNode().edges().toArray(Edge[]::new); + // Run through every target edge + for(int i = 0; i < tgtNeighbors.length; i++){ + Edge cur = tgtNeighbors[i]; + if(edges.get(cur) != edges.get(key)){ + if(updateCommunities(key, cur)){ + continue Genes; + } + } + + } + + // Run through every source edge + for(int i = 0; i < srcNeighbors.length; i++){ + Edge cur = srcNeighbors[i]; + if(edges.get(cur) != edges.get(key)){ + if(updateCommunities(key, cur)){ + continue Genes; + } + } + + } + } + + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkPopulation.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkPopulation.java new file mode 100644 index 00000000..72838873 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MLinkPopulation.java @@ -0,0 +1,135 @@ +package i5.las2peer.services.ocd.algorithms.utils; + +import i5.las2peer.services.ocd.algorithms.utils.MLinkAgent; +import java.lang.Math; +import java.util.Random; +import java.util.AbstractMap.SimpleEntry; + + + +/** + * The Population is displayed as an array where position 0 equals the root of the tree + * and k*3+1 the first child of the entry k + */ +public class MLinkPopulation { + + private MLinkAgent[] tree; + private double diversity; + + public MLinkPopulation(int treeSize){ + tree = new MLinkAgent[treeSize]; + } + // Getter and Setter for MLinkPopulation + public void setTree(MLinkAgent[] tree){ + this.tree = tree; + } + public MLinkAgent[] getTree(){ + return this.tree; + } + public double getDiversity(){ + return this.diversity; + } + public MLinkAgent getAgent(int index){ + return this.tree[index]; + } + // public methods + public double calcDiversity(){ + double mean = 0; + int totalIndividuals = (this.tree.length * this.tree[0].getIndividuals().size()); + double sum = 0; + for(int i = 0; i < this.tree.length; i++){ + MLinkAgent curAgent = this.tree[i]; + for(int j = 0; j < curAgent.getIndividuals().size(); j++){ + mean += curAgent.getIndividuals().get(j).getFitness()/totalIndividuals; + } + } + for(int i = 0; i < this.tree.length; i++){ + MLinkAgent curAgent = this.tree[i]; + for(int j = 0; j < curAgent.getIndividuals().size(); j++){ + double fitness = curAgent.getIndividuals().get(j).getFitness(); + sum += Math.pow(fitness - mean, 2); + } + } + this.diversity = Math.sqrt(sum/(totalIndividuals - 1)); + return this.diversity; + } + public void addAgent(MLinkAgent agent){ + for(int i = 0; i < this.tree.length; i++){ + if(this.tree[i] == null){ + this.tree[i] = agent; + break; + } + } + } + /** + * Swaps up the Agent with the fittest Pocket Individual + */ + public void swapUp(){ + for(int i = 0; i < 4; i++){ + for(int j = 1; j <= 3; j++){ + if(tree[i].getPocket().getFitness() < tree[i*3+j].getPocket().getFitness()){ + MLinkAgent temp = tree[i*3+j]; + tree[i*3+j] = tree[i]; + tree[i] = temp; + } + } + } + for(int i = 1; i < 4; i++){ + if(tree[0].getPocket().getFitness() < tree[i].getPocket().getFitness()){ + MLinkAgent temp = tree[0]; + tree[0] = tree[i]; + tree[i] = temp; + } + } + } + /** + * Selects 2 parents from the same branch of the tree + * @param index Index of first parent + * @return tuple of 2 parents + */ + public SimpleEntry closeSelect(int index){ + Random rand = new Random(); + // Select Random first parent + MLinkAgent firstAgent = this.tree[index]; + MLinkIndividual firstParent = firstAgent.getRandomIndividual(); + // Select second parent from the same branch as first parent + MLinkAgent closeAgent; + if(index < 4){ + closeAgent = this.tree[rand.nextInt(3)+(index*3)+1]; + } else { + if(index%3 == 0){ + closeAgent = this.tree[index-1]; + } else { + closeAgent = this.tree[index+1]; + } + } + MLinkIndividual secondParent = closeAgent.getRandomIndividual(); + + return new SimpleEntry(firstParent,secondParent); + } + /** + * Selects a second parent in another branch of the index + * @param index index of the first parent + * @return returns a tuple of the first parent and a second one + */ + public SimpleEntry farSelect(int index){ + Random rand = new Random(); + // Select Random first parent + MLinkAgent randomAgent = this.tree[index]; + MLinkIndividual firstParent = randomAgent.getRandomIndividual(); + MLinkAgent farAgent; + if(index == 0){ + farAgent = this.tree[rand.nextInt(12)+1]; + } else if(index < 4) { + farAgent = this.tree[(index + rand.nextInt(11))%12 + 1]; + } else { + farAgent = this.tree[(index + rand.nextInt(7)+4)%12 + 1]; + } + MLinkIndividual secondParent = farAgent.getRandomIndividual(); + + return new SimpleEntry(firstParent,secondParent); + } + + +} + diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MaximalCliqueSearch.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MaximalCliqueSearch.java index 4640e202..cea8fdaa 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MaximalCliqueSearch.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/MaximalCliqueSearch.java @@ -10,8 +10,9 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; @@ -35,29 +36,33 @@ public MaximalCliqueSearch() { /** * Method to find all maximal cliques of a graph. - * @param graph: the graph in which to find the all maximal cliques + * @param graph + * the graph in which to find the all maximal cliques * * @return the maximal cliques in a hashmap + * @throws InterruptedException If the executing thread was interrupted. */ - public HashMap> cliques(CustomGraph graph) { - List nodes = Arrays.asList(graph.getNodeArray()); + public HashMap> cliques(CustomGraph graph) throws InterruptedException { + List nodes = Arrays.asList(graph.nodes().toArray(Node[]::new)); List subg = new ArrayList(nodes); List cand = new ArrayList(nodes); maxClq = new HashSet(); maxCliques = new HashMap>(); clqNr = 0; - expand(subg,cand); + expand(graph, subg,cand); return maxCliques; } /** * Recursive function to find all the maximal cliques in depth-first search approach with pruning * to make it more usable on big graphs - * @param subg: set of vertices in which is needed to find a complete subgraph. It is defined as - * the set of all vertices with are not neighbors of the current largest complete subgraph. - * @param cand: All the vertices which not have been processed by the algorithm + * @param graph Input custom graph + * @param subg set of vertices in which is needed to find a complete subgraph. It is defined as + * the set of all vertices with are not neighbors of the current largest complete subgraph. + * @param cand All the vertices which not have been processed by the algorithm + * @throws InterruptedException If the executing thread was interrupted. */ - protected void expand(List subg, List cand){ + protected void expand(CustomGraph graph, List subg, List cand) throws InterruptedException { if(subg.isEmpty() == true) {// found a maximal connected subgraph if(maxClq.size() < 3) { return; @@ -71,16 +76,13 @@ protected void expand(List subg, List cand){ int maxcount = 0; HashSet maxOverlap = new HashSet(); for(Node v: subg) { - NodeCursor neighbors = v.neighbors(); HashSet overlap = new HashSet(); // find nodes that are neighbors of the current node and the current subset - while(neighbors.ok()) { - Node u = neighbors.node(); + for(Node u : graph.getNeighbours(v).toArray(Node[]::new)) { if(cand.contains(u)) { overlap.add(u); } - neighbors.next(); } // to find the maximum neighborhood overlap with the current subgraph if(overlap.size() >= maxcount){ @@ -94,27 +96,24 @@ protected void expand(List subg, List cand){ Ext_u.removeAll(maxOverlap); for(Node q: Ext_u) { - List q_neighbors = new ArrayList(); - - maxClq.add(q); // current clique (not maximal yet) - NodeCursor n = q.neighbors(); - - while(n.ok()) { // find neighbors - q_neighbors.add(n.node()); - n.next(); - } - - //update the candidate and the subgraph set to the neighbors of q - List subgr2 = new ArrayList(subg); - List cand2 = new ArrayList(cand); - subgr2.retainAll(q_neighbors); - cand2.retainAll(q_neighbors); - cand2.remove(q); - - expand(subgr2,cand2); // process the neighbors of q + List q_neighbors = new ArrayList(); + + maxClq.add(q); // current clique (not maximal yet) + + // find neighbors + q_neighbors.addAll(Arrays.asList(graph.getNeighbours(q).toArray(Node[]::new))); - cand.remove(q); // make sure that the node to processed twice - maxClq.remove(q); // prepare a clique set + //update the candidate and the subgraph set to the neighbors of q + List subgr2 = new ArrayList(subg); + List cand2 = new ArrayList(cand); + subgr2.retainAll(q_neighbors); + cand2.retainAll(q_neighbors); + cand2.remove(q); + + expand(graph, subgr2,cand2); // process the neighbors of q + + cand.remove(q); // make sure that the node to processed twice + maxClq.remove(q); // prepare a clique set } } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Point.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Point.java index 03e00308..2298c676 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Point.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Point.java @@ -2,7 +2,8 @@ import org.apache.commons.math3.linear.ArrayRealVector; -import y.base.Node; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; public class Point { private Node node; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaListenerRuleCommand.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaListenerRuleCommand.java index f819f22d..ac2d5b5e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaListenerRuleCommand.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaListenerRuleCommand.java @@ -4,7 +4,7 @@ import java.util.Map; -import y.base.Node; +import org.graphstream.graph.Node; /** * Abstract Class for the Listener Rule used by the Speaker Listener diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaPopularityListenerRule.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaPopularityListenerRule.java index 90377084..84dc71fe 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaPopularityListenerRule.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaPopularityListenerRule.java @@ -8,8 +8,9 @@ import java.util.List; import java.util.Map; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implements a concrete Listener Rule for the Speaker Listener @@ -28,7 +29,7 @@ public int getLabel(CustomGraph graph, Node listener, Map receive Map histogram = new HashMap(); for (Map.Entry entry : receivedLabels.entrySet()) { int label = entry.getValue(); - Edge edge = listener.getEdgeTo(entry.getKey()); + Edge edge = listener.getEdgeToward(entry.getKey()); double influence = graph.getEdgeWeight(edge); if(histogram.containsKey(label)) { double popularity = histogram.get(label); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaSpeakerRuleCommand.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaSpeakerRuleCommand.java index 59aa5608..235fdc4c 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaSpeakerRuleCommand.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaSpeakerRuleCommand.java @@ -4,7 +4,7 @@ import java.util.List; -import y.base.Node; +import org.graphstream.graph.Node; /** * Abstract Class for the Speaker Rule used by the Speaker Listener diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaUniformSpeakerRule.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaUniformSpeakerRule.java index 2bd855e7..ea7884c8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaUniformSpeakerRule.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/SlpaUniformSpeakerRule.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Random; -import y.base.Node; +import org.graphstream.graph.Node; /** * Implements a concrete Speaker Rule for the Speaker Listener diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Termmatrix.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Termmatrix.java index 806ed4ae..f1e3e751 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Termmatrix.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/algorithms/utils/Termmatrix.java @@ -27,8 +27,8 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; public class Termmatrix { @@ -45,7 +45,7 @@ public Termmatrix(){ public Termmatrix(CustomGraph graph) throws OcdAlgorithmException{ - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); Node node; this.wordlist = new LinkedList(); @@ -70,8 +70,8 @@ public Termmatrix(CustomGraph graph) throws OcdAlgorithmException{ ArrayRealVector vector = new ArrayRealVector(wordlist.size()); this.matrix = new Array2DRowRealMatrix(indexMap.size(),wordlist.size() ); - while(nodes.ok()){ - node = nodes.node(); + while(nodesIt.hasNext()){ + node = nodesIt.next(); this.addNode(node); name = graph.getNodeName(node); valueMap = indexMap.get(name); @@ -82,7 +82,6 @@ public Termmatrix(CustomGraph graph) throws OcdAlgorithmException{ } this.matrix.setRowVector(row, vector); row++; - nodes.next(); } /*while(nodes.ok()){ node = nodes.node(); @@ -323,7 +322,7 @@ public RealMatrix SVD(){ private HashMap> computeTFIDF(CustomGraph graph){ HashMap> res = new HashMap>(); - int noOfDocs = graph.nodes().size(); + int noOfDocs = graph.getNodeCount(); String indexPath = graph.getPath(); //NodeCursor nodes = graph.nodes(); TermsEnum termEnum = null; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/MyTest.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/MyTest.java deleted file mode 100644 index 01f409da..00000000 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/MyTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package i5.las2peer.services.ocd.benchmarks; - -import i5.las2peer.services.ocd.graphs.Cover; - -public class MyTest { - public static void main(String [ ] args) throws OcdBenchmarkException, InterruptedException - { - - LfrBenchmark myLfr=new LfrBenchmark(); - Cover cover = myLfr.createGroundTruthCover(); - System.out.println(cover.getName()); - System.out.println(cover.getMemberships()); - } - -} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmark.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmark.java index 5dbd799c..1e36e467 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmark.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmark.java @@ -6,20 +6,13 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; +import java.util.*; +import org.graphstream.graph.Edge; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Edge; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * Implements the Newman Benchmark Model. @@ -86,8 +79,8 @@ public Cover createGroundTruthCover() throws InterruptedException { */ List nodeOrder = new ArrayList(); for(int i=0; i<128; i++) { - Node node = graph.createNode(); - graph.setNodeName(node, Integer.toString(node.index())); + Node node = graph.addNode(Integer.toString(i)); + graph.setNodeName(node, Integer.toString(node.getIndex())); nodeOrder.add(node); } Collections.shuffle(nodeOrder); @@ -101,7 +94,7 @@ public Cover createGroundTruthCover() throws InterruptedException { */ List group = nodeOrder.subList(i*32, (i+1)*32); for(Node node : group) { - membershipMatrix.set(node.index(), i, 1); + membershipMatrix.set(node.getIndex(), i, 1); groupMap.put(node, i); } /* @@ -155,18 +148,18 @@ private boolean generateRandomInternalEdge(CustomGraph graph, List unsatis while(potentialNeighbors.size() > 0 && !edgeCreated) { int nodeBListIndex = rand.nextInt(potentialNeighbors.size()); Node nodeB = potentialNeighbors.get(nodeBListIndex); - if(!graph.containsEdge(nodeA, nodeB)) { + if(!nodeA.hasEdgeBetween(nodeB)) { edgeCreated = true; - graph.createEdge(nodeA, nodeB); - graph.createEdge(nodeB, nodeA); + graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); + graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeA); /* * Nodes are removed from the unsatisfied nodes when they have reached * the bound for the amount of internal edges. */ - if(nodeA.outDegree() == 16 - externalEdges) { + if(nodeA.getOutDegree() == 16 - externalEdges) { unsatisfiedNodes.remove(nodeA); } - if(nodeB.outDegree() == 16 - externalEdges) { + if(nodeB.getOutDegree() == 16 - externalEdges) { unsatisfiedNodes.remove(nodeB); } } @@ -198,7 +191,7 @@ private void redesignInternalEdges(CustomGraph graph, List group, List group, List while(potentialNeighbors.size() > 0 && !edgeCreated) { int nodeBListIndex = rand.nextInt(potentialNeighbors.size()); Node nodeB = potentialNeighbors.get(nodeBListIndex); - if(!graph.containsEdge(nodeA, nodeB) && groupMap.get(nodeA) != groupMap.get(nodeB)) { + if(!nodeA.hasEdgeBetween(nodeB) && groupMap.get(nodeA) != groupMap.get(nodeB)) { edgeCreated = true; - graph.createEdge(nodeA, nodeB); - graph.createEdge(nodeB, nodeA); + graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); + graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeA); /* * Nodes are removed from the unsatisfied nodes when they have reached * the bound for the amount of total edges. */ - if(nodeA.outDegree() == 16) { + if(nodeA.getOutDegree() == 16) { unsatisfiedNodes.remove(nodeA); } - if(nodeB.outDegree() == 16) { + if(nodeB.getOutDegree() == 16) { unsatisfiedNodes.remove(nodeB); } } @@ -275,7 +268,7 @@ private boolean generateRandomExternalEdge(CustomGraph graph, Map * @param nodeA The node for which a new edge will be created. * @param rand A generator for random numbers, included for performance. */ - private void redesignExternalEdges(CustomGraph graph, Map groupMap, List nodes, List unsatisfiedNodes, Node nodeA, Random rand) { + private void redesignExternalEdges(CustomGraph graph, Map groupMap, List nodes, List unsatisfiedNodes, Node nodeA, Random rand) throws InterruptedException { List potentialNeighbors = new ArrayList(nodes); potentialNeighbors.removeAll(unsatisfiedNodes); /* @@ -286,7 +279,7 @@ private void redesignExternalEdges(CustomGraph graph, Map groupMa while(!nodeBFound) { int nodeBListIndex = rand.nextInt(potentialNeighbors.size()); nodeB = potentialNeighbors.get(nodeBListIndex); - if(!graph.containsEdge(nodeA, nodeB) && groupMap.get(nodeA) != groupMap.get(nodeB)) { + if(!nodeA.hasEdgeBetween(nodeB) && groupMap.get(nodeA) != groupMap.get(nodeB)) { nodeBFound = true; } else { @@ -297,26 +290,25 @@ private void redesignExternalEdges(CustomGraph graph, Map groupMa * Deletes an external edge incident to B and creates * a new edge between A and B */ - NodeCursor neighbors = nodeB.successors(); + Iterator neighbors = graph.getSuccessorNeighbours(nodeB).iterator(); Node neighbor = null; boolean externalNeighborFound = false; - while(neighbors.ok() && !externalNeighborFound) { - neighbor = neighbors.node(); + while(neighbors.hasNext() && !externalNeighborFound) { + neighbor = neighbors.next(); if(groupMap.get(nodeB) != groupMap.get(neighbor)) { externalNeighborFound = true; } - neighbors.next(); } - Edge outEdge = nodeB.getEdgeTo(neighbor); + Edge outEdge = nodeB.getEdgeToward(neighbor); Edge inEdge = nodeB.getEdgeFrom(neighbor); graph.removeEdge(outEdge); graph.removeEdge(inEdge); - graph.createEdge(nodeA, nodeB); - graph.createEdge(nodeB, nodeA); + graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); + graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeA); if(!unsatisfiedNodes.contains(neighbor)) { unsatisfiedNodes.add(neighbor); } - if(nodeA.outDegree() == 16) { + if(nodeA.getOutDegree() == 16) { unsatisfiedNodes.remove(nodeA); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmark.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmark.java index d0585bbb..9222a9bb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmark.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmark.java @@ -6,14 +6,9 @@ import i5.las2peer.services.ocd.graphs.CoverCreationType; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Edge; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import org.apache.commons.exec.DefaultExecutor; import org.la4j.matrix.Matrix; @@ -392,24 +387,24 @@ protected Cover setWeightSign(Cover cover, double pos, double neg) throws Interr List interEdgeList = new ArrayList(); List intraNegativeList = new ArrayList(); int communityCount = membership.columns(); - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; /* * negate the weight of all edges connecting two nodes in different * communities. */ - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edges.next(); boolean beingIntraEdge = false; /* * If two nodes are residing in at least one common community, the * edge connecting them is regarded as an intra-edge. */ for (int i = 0; i < communityCount; i++) { - if (membership.get(edge.source().index(), i) * membership.get(edge.target().index(), i) != 0) { + if (membership.get(edge.getSourceNode().getIndex(), i) * membership.get(edge.getTargetNode().getIndex(), i) != 0) { intraEdgeList.add(edge); beingIntraEdge = true; break; @@ -419,7 +414,6 @@ protected Cover setWeightSign(Cover cover, double pos, double neg) throws Interr interEdgeList.add(edge); graph.setEdgeWeight(edge, graph.getEdgeWeight(edge) * (-1)); } - edges.next(); } /* * randomly negate the weight of intra-edges depending on the parameter diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/lfr/benchm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/lfr/benchm.java index 7c9bb8e8..96a957b4 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/lfr/benchm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/lfr/benchm.java @@ -10,6 +10,7 @@ import java.util.Date; import java.util.Iterator; import java.util.Map; +import java.util.UUID; import java.util.TreeMap; import java.util.TreeSet; @@ -26,8 +27,8 @@ import i5.las2peer.services.ocd.benchmarks.lfrAlgorithms.util.Random; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; import java.util.Map.Entry; @@ -951,7 +952,7 @@ public static Cover weighted_directed_network_benchmark(boolean excess, boolean * create graph nodes */ for (int u = 0; u < Eout.size(); u++) { - Node node = graph.createNode(); + Node node = graph.addNode(Integer.toString(u)); graph.setNodeName(node, Integer.toString(u)); @@ -961,12 +962,12 @@ public static Cover weighted_directed_network_benchmark(boolean excess, boolean /* * create edges between the nodes */ - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); for (int u = 0; u < Eout.size(); u++) { for (Iterator itb = Eout.get(u).iterator(); itb.hasNext();) { Integer itb_current = itb.next(); - Edge edge = graph.createEdge(nodes[u], nodes[itb_current]); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), nodes[u], nodes[itb_current]); graph.setEdgeWeight(edge, neigh_weigh_out.get(u).get(itb_current)); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/signedlfr/benchm.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/signedlfr/benchm.java index 89c3ef64..a6954658 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/signedlfr/benchm.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/benchmarks/lfrAlgorithms/signedlfr/benchm.java @@ -9,6 +9,8 @@ import java.util.Iterator; import java.util.TreeSet; +import java.util.UUID; + import org.la4j.matrix.Matrix; import org.la4j.matrix.dense.Basic2DMatrix; @@ -25,8 +27,8 @@ import i5.las2peer.services.ocd.benchmarks.lfrAlgorithms.util.Random; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * This class is Java implementation of directed networks which is equivalent to signed LFR algorithm @@ -1797,7 +1799,7 @@ public static Cover directed_network_benchmark(boolean excess, boolean defect, i * create graph nodes */ for (int u = 0; u < Eout.size(); u++) { - Node node = graph.createNode(); + Node node = graph.addNode(Integer.toString(u)); graph.setNodeName(node, Integer.toString(u)); } @@ -1805,12 +1807,12 @@ public static Cover directed_network_benchmark(boolean excess, boolean defect, i /* * create weighted edges between the nodes */ - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); for (int u = 0; u < Eout.size(); u++) { for (Iterator itb = Eout.get(u).iterator(); itb.hasNext();) { Integer itb_current = itb.next(); - Edge edge = graph.createEdge(nodes[u], nodes[itb_current]); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), nodes[u], nodes[itb_current]); //TODO: Check naming here as no weight given but description states weighted method } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityCreationLog.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityCreationLog.java index 20f6f0dc..23951d40 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityCreationLog.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityCreationLog.java @@ -1,5 +1,6 @@ package i5.las2peer.services.ocd.centrality.data; +import i5.las2peer.services.ocd.graphs.GraphCreationLog; import i5.las2peer.services.ocd.graphs.GraphType; import i5.las2peer.services.ocd.utils.ExecutionStatus; @@ -15,6 +16,14 @@ import javax.persistence.GenerationType; import javax.persistence.Id; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * A log representation for a CentralityCreationMethod. * @@ -27,10 +36,13 @@ public class CentralityCreationLog { */ private static final String idColumnName = "ID"; private static final String centralityTypeColumnName = "CENTRALITY_TYPE"; - private static final String creationTypeColumnName = "CREATION_TYPE"; - private static final String statusIdColumnName = "STATUS"; - private static final String executionTimeColumnName = "EXECUTION_TIME"; - + public static final String creationTypeColumnName = "CREATION_TYPE"; + public static final String statusIdColumnName = "STATUS"; + public static final String executionTimeColumnName = "EXECUTION_TIME"; + //ArangoDB + public static final String collectionName = "centralitycreationlog"; + private static final String parameterColumnName = "PARAMETER"; + private static final String compatibleGraphTypesColumnName = "COMPATIBLE_GRAPH_TYPES"; /* * Field names. */ @@ -43,6 +55,10 @@ public class CentralityCreationLog { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) private long id; + /** + * System generated persistence key. + */ + private String key; /** * Parameters used by the creation method. */ @@ -161,7 +177,15 @@ public Map getParameters() { public long getId() { return id; } - + + /** + * Returns the log key. + * @return The key. + */ + public String getKey() { + return key; + } + /** * Returns the graph types the corresponding creation method is compatible with. * @return The graph types. @@ -197,4 +221,82 @@ public long getExecutionTime() { public void setExecutionTime(long time) { executionTime = time; } + + //persistence functions + public void persist(ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(centralityTypeColumnName, this.centralityTypeId); + bd.addAttribute(creationTypeColumnName, this.creationTypeId); + bd.addAttribute(parameterColumnName, this.parameters); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(executionTimeColumnName, this.executionTime); + bd.addAttribute(compatibleGraphTypesColumnName, this.compatibleGraphTypes); + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public void updateDB(ArangoDatabase db, String transId) { + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(centralityTypeColumnName, this.centralityTypeId); + bd.addAttribute(creationTypeColumnName, this.creationTypeId); + bd.addAttribute(parameterColumnName, this.parameters); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(executionTimeColumnName, this.executionTime); + bd.addAttribute(compatibleGraphTypesColumnName, this.compatibleGraphTypes); + collection.updateDocument(this.key, bd, updateOptions); + } + + public static CentralityCreationLog load(String key, ArangoDatabase db, DocumentReadOptions opt) { + CentralityCreationLog ccl = new CentralityCreationLog(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + ObjectMapper om = new ObjectMapper(); + String centralityTypeString = bd.getAttribute(centralityTypeColumnName).toString(); + String creationTypeString = bd.getAttribute(creationTypeColumnName).toString(); + String statusIdString = bd.getAttribute(statusIdColumnName).toString(); + String executionTimeString = bd.getAttribute(executionTimeColumnName).toString(); + Object objParam = bd.getAttribute(parameterColumnName); + Object objCompGraph = bd.getAttribute(compatibleGraphTypesColumnName); + + ccl.key = key; + if(objParam != null) { + ccl.parameters = om.convertValue(objParam, Map.class); + } + if(centralityTypeString != null) { + ccl.centralityTypeId = Integer.parseInt(centralityTypeString); + } + if(creationTypeString != null) { + ccl.creationTypeId = Integer.parseInt(creationTypeString); + } + if(statusIdString != null) { + ccl.statusId = Integer.parseInt(statusIdString); + } + if(executionTimeString != null) { + ccl.executionTime= Long.parseLong(executionTimeString); + } + ccl.compatibleGraphTypes = om.convertValue(objCompGraph, Set.class); + } + else { + System.out.println("empty CentralityCreationLog document"); + } + return ccl; + } + public String String() { + String n = System.getProperty("line.separator"); + String ret = "CentralityCreationLog: " + n; + ret += "Key : " + this.key +n ; + ret += "parameters : " + this.parameters.toString() + n; + ret += "centralityTypeId :" + this.centralityTypeId + n ; + ret += "creationTypeId : " + this.creationTypeId +n; + ret += "statusId : " + this.statusId + n; + ret += "executionTime : " + this.executionTime +n; + ret += "GraphTypes : " + this.compatibleGraphTypes.toString() + n; + return ret; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMap.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMap.java index 65128ed5..dfa9c12a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMap.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMap.java @@ -20,12 +20,27 @@ import javax.persistence.JoinColumns; import javax.persistence.OneToOne; +import com.fasterxml.jackson.core.type.TypeReference; +import org.graphstream.graph.Node; import org.w3c.dom.Element; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentDeleteOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import i5.las2peer.services.ocd.graphs.Community; +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.CoverCreationLog; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; + @Entity @IdClass(CentralityMapId.class) @@ -38,21 +53,29 @@ public class CentralityMap { public static final String graphUserColumnName = "USER_NAME"; public static final String idColumnName = "ID"; private static final String creationMethodColumnName = "CREATION_METHOD"; - + //ArangoDB + public static final String collectionName = "centralitymap"; + private static final String mapColumnName = "MAP"; + public static final String creationMethodKeyColumnName = "CREATION_METHOD"; + public static final String graphKeyColumnName = "GRAPH_KEY"; /* * Field name definitions for JPQL queries. */ public static final String GRAPH_FIELD_NAME = "graph"; public static final String CREATION_METHOD_FIELD_NAME = "creationMethod"; - public static final String ID_FIELD_NAME = "id"; + public static final String ID_FIELD_NAME = "key"; /** * System generated persistence id. */ + private long id; + /** + * System generated persistence key. + */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) - private long id; + private String key = ""; /** * The name of the CentralityMap. */ @@ -97,6 +120,14 @@ public long getId() { return id; } + /** + * Getter for the key. + * @return The key. + */ + public String getKey() { + return key; + } + /** * Getter for the CentralityMap name. * @@ -146,8 +177,8 @@ public void setMap(Map map) { * @param node The node whose value is set. * @param value The centrality value that is assigned to the node. */ - public void setNodeValue(Node node, double value) { - if(graph.contains(node)) { + public void setNodeValue(Node node, double value) { //TODO: Check If original functionality maintained + if(graph.getNode(node.getId()) != null) { // TODO: should be key not id? map.put(graph.getNodeName(node), value); } } @@ -237,6 +268,77 @@ public void setCreationMethod(CentralityCreationLog creationMethod) { } } + //persistence functions + public void persist(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + + if(this.graph == null) { + throw new IllegalArgumentException("graph attribute of the centralityMap to be persisted does not exist"); + } + else if(this.graph.getKey().equals("")) { + throw new IllegalArgumentException("the graph of the centralityMap is not persisted yet"); + } + bd.addAttribute(graphKeyColumnName, this.graph.getKey()); + bd.addAttribute(nameColumnName, this.name); + this.creationMethod.persist(db, createOptions); + bd.addAttribute(creationMethodKeyColumnName, this.creationMethod.getKey()); + bd.addAttribute(mapColumnName, this.map); + collection.insertDocument(bd, createOptions); + this.key = bd.getKey(); + + } + + public void updateDB(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + BaseDocument bd = new BaseDocument(); + if(this.graph == null) { + throw new IllegalArgumentException("graph attribute of the map to be updated does not exist"); + } + else if(this.graph.getKey().equals("")) { + throw new IllegalArgumentException("the graph of the map is not persisted yet"); + } + bd.addAttribute(graphKeyColumnName, this.graph.getKey()); + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(creationMethodKeyColumnName, this.creationMethod.getKey()); + bd.addAttribute(mapColumnName, this.map); + + this.creationMethod.updateDB(db, transId); + + collection.updateDocument(this.key, bd, updateOptions); + } + + public static CentralityMap load(String key, CustomGraph g, ArangoDatabase db, String transId) { + CentralityMap cm = null; + ArangoCollection collection = db.collection(collectionName); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + BaseDocument bd = collection.getDocument(key, BaseDocument.class, readOpt); + if (bd != null) { + cm = new CentralityMap(g); + ObjectMapper om = new ObjectMapper(); //prepair attributes + String graphKey = bd.getAttribute(graphKeyColumnName).toString(); + if(!graphKey.equals(g.getKey())) { + System.out.println("graph with key: " + g.getKey() + " does not fit to centralityMap with GraphKey: " + graphKey); + return null; + } + String creationMethodKey = bd.getAttribute(creationMethodKeyColumnName).toString(); + Object objMap = bd.getAttribute(mapColumnName); + + //restore all attributes + cm.key = key; + cm.name = bd.getAttribute(nameColumnName).toString(); + cm.creationMethod = CentralityCreationLog.load(creationMethodKey, db, readOpt); + cm.map = om.convertValue(objMap,new TypeReference>() { }); + } + else { + System.out.println("empty CentralityMap document"); + } + return cm; + } + @Override public String toString() { String centralityMapString = "Centrality Map: " + getName() + "\n"; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMapId.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMapId.java index 351e589f..39840d3c 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMapId.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMapId.java @@ -9,9 +9,9 @@ public class CentralityMapId { /** - * The map-specific id. + * The map-specific key. */ - private long id; + private String key; /** * The id of the graph the CentralityMap is based on. @@ -20,11 +20,11 @@ public class CentralityMapId { /** * Creates a new instance. - * @param id The map-specific id. + * @param key The map-specific key. * @param graphId The id of the graph the CentralityMap is based on. */ - public CentralityMapId(long id, CustomGraphId graphId) { - this.id = id; + public CentralityMapId(String key, CustomGraphId graphId) { + this.key = key; this.graph = graphId; } @@ -32,7 +32,7 @@ public CentralityMapId(long id, CustomGraphId graphId) { public boolean equals(Object object) { if (object instanceof CentralityMapId) { CentralityMapId pk = (CentralityMapId)object; - return graph.equals(graph) && id == pk.id; + return graph.equals(graph) && key.equals(pk.key); } else { return false; } @@ -40,7 +40,7 @@ public boolean equals(Object object) { @Override public int hashCode() { - return (int)(id + graph.hashCode()); + return (int)(key.hashCode() + graph.hashCode()); } /** @@ -50,4 +50,11 @@ public int hashCode() { public CustomGraphId getGraphId() { return graph; } + /** + * Getter for the map key. + * @return The map key. + */ + public String getKey() { + return key; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMeta.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMeta.java new file mode 100644 index 00000000..101a9c81 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/data/CentralityMeta.java @@ -0,0 +1,159 @@ +package i5.las2peer.services.ocd.centrality.data; + +import i5.las2peer.services.ocd.graphs.CoverCreationType; +import i5.las2peer.services.ocd.utils.ExecutionStatus; + +import java.beans.ConstructorProperties; + +/** + * Instance of this class holds meta information about a centrality and is used + * for efficient requests that don't require accessing full centrality data + */ +public class CentralityMeta { + + /** + * The key of the CentralityMap. + */ + private String centralityKey; + + /** + * The name of the CentralityMap. + */ + private String centralityName; + + /** + * The key of the graph centrality is based on. + */ + private String graphKey; + + /** + * The name of the graph centrality is based on. + */ + private String graphName; + + + /** + * The type corresponding to the centrality creation log. + */ + private int creationTypeId; + + /** + * The type corresponding to the graph creation log status. + */ + private int creationStatusId; + + /** + * The execution time of the centrality in ms. + */ + private long executionTime; + + @ConstructorProperties({"centralityKey","centralityName","graphKey","graphName", "creationTypeId", "creationStatusId", "executionTime"}) + public CentralityMeta(String centralityKey, String centralityName, String graphKey, String graphName, + int creationTypeId, int creationStatusId, long executionTime) { + this.centralityKey = centralityKey; + this.centralityName = centralityName; + this.graphKey = graphKey; + this.graphName = graphName; + this.creationTypeId = creationTypeId; + this.creationStatusId = creationStatusId; + this.executionTime = executionTime; + } + + /** + * Finds and returns name of the centrality creation type of the + * centrality to which this meta data belongs. + * @return Centrality creation type name. + */ + public String getCreationTypeName(){ + return CentralityCreationType.lookupType(this.creationTypeId).name(); + } + + /** + * Finds and returns display name of the centrality creation log of the + * centrality to which this meta data belongs. + * @return Centrality creation log display name. + */ + public String getCreationTypeDisplayName(){ + return CentralityCreationType.lookupType(this.creationTypeId).getDisplayName(); + } + + /** + * Finds and returns name of the execution status of the + * centrality to which this meta data belongs. + * @return Centrality execution status name. + */ + public String getCreationStatusName(){ + + return ExecutionStatus.lookupStatus(this.creationStatusId).name(); + } + + public String getCentralityKey() { + return centralityKey; + } + + public void setCentralityKey(String centralityKey) { + this.centralityKey = centralityKey; + } + + public String getCentralityName() { + return centralityName; + } + + public void setCentralityName(String centralityName) { + this.centralityName = centralityName; + } + + public String getGraphKey() { + return graphKey; + } + + public void setGraphKey(String graphKey) { + this.graphKey = graphKey; + } + + public String getGraphName() { + return graphName; + } + + public void setGraphName(String graphName) { + this.graphName = graphName; + } + + public int getCreationTypeId() { + return creationTypeId; + } + + public void setCreationTypeId(int creationTypeId) { + this.creationTypeId = creationTypeId; + } + + public int getCreationStatusId() { + return creationStatusId; + } + + public void setCreationStatusId(int creationStatusId) { + this.creationStatusId = creationStatusId; + } + + public long getExecutionTime() { + return executionTime; + } + + public void setExecutionTime(long executionTime) { + this.executionTime = executionTime; + } + + @Override + public String toString() { + return "CentralityMeta{" + + "centralityKey='" + centralityKey + '\'' + + ", centralityName='" + centralityName + '\'' + + ", graphKey='" + graphKey + '\'' + + ", graphName='" + graphName + '\'' + + ", creationTypeId=" + creationTypeId + + ", creationStatusId=" + creationStatusId + + ", executionTime=" + executionTime + + '}'; + } + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/evaluation/StatisticalProcessor.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/evaluation/StatisticalProcessor.java index c2fb4dfa..ae679251 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/evaluation/StatisticalProcessor.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/evaluation/StatisticalProcessor.java @@ -2,6 +2,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.Iterator; import java.util.List; import org.apache.commons.math3.linear.RealMatrix; @@ -11,8 +12,7 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * Calculates statistical measures on centrality maps. @@ -31,15 +31,14 @@ public static CentralityMap getAverageMap(CustomGraph graph, List CentralityMap resultMap = new CentralityMap(graph); int mapListSize = maps.size(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - Node currentNode = nc.node(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + Node currentNode = nc.next(); double currentNodeAverage = 0.0; for(CentralityMap currentMap : maps) { currentNodeAverage += currentMap.getNodeValue(graph.getNodeName(currentNode)); } resultMap.setNodeValue(currentNode, currentNodeAverage/mapListSize); - nc.next(); } return resultMap; } @@ -107,20 +106,19 @@ public static RealMatrix kendallCorrelation(CustomGraph graph, List maps) { - int n = graph.nodeCount(); + int n = graph.getNodeCount(); int m = maps.size(); double[][] mapsValues = new double[n][m]; - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); int i = 0; - while(nc.ok()) { - Node currentNode = nc.node(); + while(nc.hasNext()) { + Node currentNode = nc.next(); for(int j = 0; j < m; j++) { // Round to 8 decimal places so nodes with marginally different values are not put into different "classes" Double complete = maps.get(j).getNodeValue(graph.getNodeName(currentNode)); Double rounded = BigDecimal.valueOf(complete).setScale(8, RoundingMode.HALF_UP).doubleValue(); mapsValues[i][j] = rounded; } - nc.next(); i++; } return mapsValues; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/AlphaCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/AlphaCentrality.java index 7dff5d7e..35db5bb9 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/AlphaCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/AlphaCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.inversion.GaussJordanInverter; import org.la4j.inversion.MatrixInverter; @@ -19,8 +16,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; /** * Implementation of Alpha Centrality. @@ -41,7 +38,7 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.ALPHA_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - int n = graph.nodeCount(); + int n = graph.getNodeCount(); Matrix A_tr = graph.getNeighbourhoodMatrix().transpose(); // Create identity matrix and vector of external status @@ -63,14 +60,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Matrix inverse = gauss.inverse(); Vector resultVector = inverse.multiply(eVector); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, resultVector.get(node.index())); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, resultVector.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BargainingCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BargainingCentrality.java index 3d891d96..3213e6b6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BargainingCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BargainingCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.vector.Vector; @@ -17,8 +14,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; /** * Implementation of Bargaining Centrality. @@ -39,50 +36,40 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.BARGAINING_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Node[] nc = graph.nodes().toArray(Node[]::new); // If the graph contains no edges - if(graph.edgeCount() == 0) { - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + for(Node node : nc) { res.setNodeValue(node, 0); - nc.next(); } return res; } - int n = nc.size(); + int n = nc.length; Matrix R = graph.getNeighbourhoodMatrix(); Vector c = new BasicVector(n); for(int k = 0; k < 50; k++) { - while(nc.ok()) { + for(Node i : nc) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node i = nc.node(); double sum = 0.0; - NodeCursor neighbors = i.successors(); - while(neighbors.ok()) { - Node j = neighbors.node(); - double Rij = R.get(i.index(), j.index()); - double cj = c.get(j.index()); + Set neighbors = graph.getSuccessorNeighbours(i); + for(Node j : neighbors) { + double Rij = R.get(i.getIndex(), j.getIndex()); + double cj = c.get(j.getIndex()); sum += (alpha + beta * cj) * Rij; - neighbors.next(); - } - c.set(i.index(), sum); - nc.next(); + } + c.set(i.getIndex(), sum); } - nc.toFirst(); } double norm = MatrixOperations.norm(c); c = c.multiply(n/norm); - - nc.toFirst(); - while(nc.ok()) { - Node node = nc.node(); - res.setNodeValue(node, c.get(node.index())); - nc.next(); + + for(Node node : nc) { + res.setNodeValue(node, c.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BetweennessCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BetweennessCentrality.java index 94021897..7d2f20ab 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BetweennessCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BetweennessCentrality.java @@ -1,12 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.Queue; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -15,9 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implementation of Betweenness Centrality. @@ -35,18 +29,17 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.BETWEENNESS_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } - nc.toFirst(); + nc = graph.iterator(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node s = nc.node(); + Node s = nc.next(); // Variable declaration Queue Q = new LinkedList(); @@ -57,15 +50,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Map delta = new HashMap(); // Initialization - NodeCursor iterator = graph.nodes(); - while(iterator.ok()) { - Node w = iterator.node(); + Iterator iterator = graph.iterator(); + while(iterator.hasNext()) { + Node w = iterator.next(); Pred.put(w, new LinkedList()); dist.put(w, Double.POSITIVE_INFINITY); sigma.put(w, 0); - iterator.next(); } dist.put(s, 0.0); sigma.put(s, 1); @@ -75,9 +67,9 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { while(!Q.isEmpty()) { Node v = Q.poll(); S.push(v); - NodeCursor outNeighbors = v.successors(); - while(outNeighbors.ok()) { - Node w = outNeighbors.node(); + Iterator outNeighbors = graph.getSuccessorNeighbours(v).iterator(); + while(outNeighbors.hasNext()) { + Node w = outNeighbors.next(); // Path discovery if(dist.get(w) == Double.POSITIVE_INFINITY) { @@ -91,16 +83,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Pred.get(w).add(v); } - outNeighbors.next(); } } // Accumulation - iterator.toFirst(); - while(iterator.ok()) { - Node v = iterator.node(); + iterator = graph.iterator(); + while(iterator.hasNext()) { + Node v = iterator.next(); delta.put(v, 0.0); - iterator.next(); } while(!S.isEmpty()) { @@ -112,15 +102,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { res.setNodeValue(w, res.getNodeValue(w) + delta.get(w)); } } - nc.next(); } // If graph is undirected, divide centrality values by 2 if(!graph.getTypes().contains(GraphType.DIRECTED)) { - nc.toFirst(); - while(nc.ok()) { - res.setNodeValue(nc.node(), res.getNodeValue(nc.node())/2); - nc.next(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, res.getNodeValue(node)/2); } } return res; @@ -130,18 +119,17 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.BETWEENNESS_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } - nc.toFirst(); + nc = graph.iterator(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node s = nc.node(); + Node s = nc.next(); // Variable declaration Queue Q = new LinkedList(); @@ -152,15 +140,13 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc Map delta = new HashMap(); // Initialization - NodeCursor iterator = graph.nodes(); - while(iterator.ok()) { - Node w = iterator.node(); + Iterator iterator = graph.iterator(); + while(iterator.hasNext()) { + Node w = iterator.next(); Pred.put(w, new LinkedList()); dist.put(w, Double.POSITIVE_INFINITY); sigma.put(w, 0); - - iterator.next(); } dist.put(s, 0.0); sigma.put(s, 1); @@ -177,13 +163,14 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc S.push(v); Q.remove(v); - EdgeCursor outEdges = v.outEdges(); - while(outEdges.ok()) { - Node w = outEdges.edge().target(); + Iterator outEdges = v.leavingEdges().iterator(); + while(outEdges.hasNext()) { + Edge edge = outEdges.next(); + Node w = edge.getTargetNode(); // Path discovery - if(dist.get(w) > dist.get(v) + graph.getEdgeWeight(outEdges.edge())) { - dist.put(w, dist.get(v) + graph.getEdgeWeight(outEdges.edge())); + if(dist.get(w) > dist.get(v) + graph.getEdgeWeight(edge)) { + dist.put(w, dist.get(v) + graph.getEdgeWeight(edge)); if(!Q.contains(w)) Q.add(w); sigma.put(w, 0); @@ -191,20 +178,18 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc } // Path counting - if(dist.get(w) == dist.get(v) + graph.getEdgeWeight(outEdges.edge())) { + if(dist.get(w) == dist.get(v) + graph.getEdgeWeight(edge)) { sigma.put(w, sigma.get(w) + sigma.get(v)); Pred.get(w).add(v); - } - outEdges.next(); + } } } // Accumulation - iterator.toFirst(); - while(iterator.ok()) { - Node v = iterator.node(); + iterator = graph.iterator(); + while(iterator.hasNext()) { + Node v = iterator.next(); delta.put(v, 0.0); - iterator.next(); } while(!S.isEmpty()) { @@ -216,15 +201,14 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc res.setNodeValue(w, res.getNodeValue(w) + delta.get(w)); } } - nc.next(); } // If graph is undirected, divide centrality values by 2 if(!graph.getTypes().contains(GraphType.DIRECTED)) { - nc.toFirst(); - while(nc.ok()) { - res.setNodeValue(nc.node(), res.getNodeValue(nc.node())/2); - nc.next(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, res.getNodeValue(node)/2); } } return res; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCentrality.java index 7a0d31e8..c3bfe59e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCentrality.java @@ -1,10 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -14,8 +10,8 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphProcessor; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Bridging Centrality. @@ -28,7 +24,7 @@ public class BridgingCentrality implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.BRIDGING_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - int n = graph.nodeCount(); + int n = graph.getNodeCount(); // Determine bridging coefficient ranks BridgingCoefficient bridgingCoefficientAlgorithm = new BridgingCoefficient(); @@ -70,16 +66,15 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } } - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); int bridgingRank = bridgingCoefficientValueToRankMap.get(bridgingCoefficientMap.getNodeValue(node)); int betweennessRank = betweennessCentralityValueToRankMap.get(betweennessCentralityMap.getNodeValue(node)); res.setNodeValue(node, bridgingRank * betweennessRank); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCoefficient.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCoefficient.java index 17d0fd50..aefcaa79 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCoefficient.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/BridgingCoefficient.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of the Bridging Coefficient. @@ -27,36 +25,29 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.UNDEFINED, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); // Calculate the probability of leaving the direct neighborhood subgraph in two steps double leavingProbability = 0.0; - double nodeWeightedOutDegree = graph.getWeightedOutDegree(node); - NodeCursor neighbors = node.successors(); - while(neighbors.ok()) { - Node neighbor = neighbors.node(); - double nodeEdgeWeight = graph.getEdgeWeight(node.getEdgeTo(neighbor)); - if(nodeEdgeWeight > 0) { - double neighborWeightedOutDegree = graph.getWeightedOutDegree(neighbor); - NodeCursor twoStepNeighbors = neighbor.successors(); - while(twoStepNeighbors.ok()) { - Node twoStepNeighbor = twoStepNeighbors.node(); - double neighborEdgeWeight = graph.getEdgeWeight(neighbor.getEdgeTo(twoStepNeighbor)); - if(twoStepNeighbor != node && node.getEdgeTo(twoStepNeighbor) == null) { + double nodeWeightedOutDegree = graph.getWeightedOutDegree((MultiNode) node); + for (Node neighbor : graph.getSuccessorNeighbours(node)) { + double nodeEdgeWeight = graph.getEdgeWeight(node.getEdgeToward(neighbor)); + if (nodeEdgeWeight > 0) { + double neighborWeightedOutDegree = graph.getWeightedOutDegree((MultiNode) neighbor); + for (Node twoStepNeighbor : graph.getSuccessorNeighbours(neighbor)) { + double neighborEdgeWeight = graph.getEdgeWeight(neighbor.getEdgeToward(twoStepNeighbor)); + if (twoStepNeighbor != node && node.getEdgeToward(twoStepNeighbor) == null) { // If twoStepNeighbor is not in the direct neighborhood graph - leavingProbability += nodeEdgeWeight/nodeWeightedOutDegree * neighborEdgeWeight/neighborWeightedOutDegree; + leavingProbability += nodeEdgeWeight / nodeWeightedOutDegree * neighborEdgeWeight / neighborWeightedOutDegree; } - twoStepNeighbors.next(); } } - neighbors.next(); - } + } res.setNodeValue(node, leavingProbability); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CentroidValue.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CentroidValue.java index 0061ed61..fee388a6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CentroidValue.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CentroidValue.java @@ -1,10 +1,8 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; +import org.graphstream.graph.Edge; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; import org.la4j.vector.Vector; @@ -17,9 +15,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.algo.ShortestPaths; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.algorithm.Dijkstra; + /** * Implementation of Centroid Value. @@ -33,39 +31,59 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CENTROID_VALUE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - int n = graph.nodeCount(); - double[] edgeWeights = graph.getEdgeWeights(); + Iterator nc = graph.iterator(); + int n = graph.getNodeCount(); + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + while (edges.hasNext()) { + edge = edges.next(); + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + } + Matrix dist = new CCSMatrix(n, n); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); // Create matrix containing all the distances between nodes double[] distArray = new double[n]; - ShortestPaths.dijkstra(graph, node, true, edgeWeights, distArray); + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + + Iterator iterator = graph.iterator(); + int k = 0; + while(iterator.hasNext()) { + distArray[k] = dijkstra.getPathLength(iterator.next()); + k++; + } + Vector distVector = new BasicVector(distArray); - dist.setRow(node.index(), distVector); - nc.next(); + dist.setRow(node.getIndex(), distVector); } - - nc.toFirst(); - while(nc.ok()) { + + nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node v = nc.node(); + Node v = nc.next(); int min = n; - NodeCursor nc2 = graph.nodes(); - while(nc2.ok()) { - Node w = nc2.node(); + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()) { + Node w = nc2.next(); if(v != w) { int gammaVW = 0; int gammaWV = 0; for(int i = 0; i < n; i++) { - double distV = dist.get(v.index(), i); - double distW = dist.get(w.index(), i); + double distV = dist.get(v.getIndex(), i); + double distW = dist.get(w.getIndex(), i); if(distV < distW) gammaVW++; else if(distW < distV) @@ -75,10 +93,8 @@ else if(distW < distV) if(fVW < min) min = fVW; } - nc2.next(); - } + } res.setNodeValue(v, min); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClosenessCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClosenessCentrality.java index 0c9b21a6..24e067ca 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClosenessCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClosenessCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; -import y.algo.ShortestPaths; +import org.graphstream.algorithm.Dijkstra; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * Implementation of Closeness Centrality. @@ -28,27 +25,48 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CLOSENESS_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If there is only a single node - if(graph.nodeCount() == 1) { - res.setNodeValue(nc.node(), 0); + if(graph.getNodeCount() == 1) { + res.setNodeValue(nc.next(), 0); return res; } - + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + HashMap edgeweights = new HashMap(); + while (edges.hasNext()) { + edge = edges.next(); + + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + } + double[] edgeWeights = graph.getEdgeWeights(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - ShortestPaths.dijkstra(graph, node, true, edgeWeights, dist); + Node node = nc.next(); + double[] distArray = new double[graph.getNodeCount()]; + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + + Iterator iterator = graph.iterator(); + int k = 0; double distSum = 0.0; - for(double d : dist) { + while(iterator.hasNext()) { + double d = dijkstra.getPathLength(iterator.next()); + distArray[k] = d; distSum += d; + k++; } - res.setNodeValue(node, (graph.nodeCount()-1)/distSum); - nc.next(); + + res.setNodeValue(node, (graph.getNodeCount()-1)/distSum); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClusterRank.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClusterRank.java index 7af33581..1fcb54c6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClusterRank.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ClusterRank.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of ClusterRank. @@ -25,17 +23,17 @@ public class ClusterRank implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CLUSTER_RANK, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); // Calculate clustering coefficient - int maxEdges = node.successors().size() * (node.successors().size() - 1); + int maxEdges = graph.getSuccessorNeighbours(node).size() * (graph.getSuccessorNeighbours(node).size() - 1); int edgeCount = 0; double clusteringCoefficient = 0; @@ -44,33 +42,27 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } else { Set outNeighborSet = new HashSet(); - NodeCursor successors = node.successors(); - while(successors.ok()) { - outNeighborSet.add(successors.node()); - successors.next(); - } + Iterator successors = graph.getSuccessorNeighbours(node).iterator(); + while(successors.hasNext()) { + outNeighborSet.add(successors.next()); + } for(Node j : outNeighborSet) { - EdgeCursor edges = j.outEdges(); - while(edges.ok()) { - Node k = edges.edge().target(); + Iterator edgeIterator = j.leavingEdges().iterator(); + while(edgeIterator.hasNext()) { + Node k = edgeIterator.next().getTargetNode(); if(outNeighborSet.contains(k)) edgeCount++; - edges.next(); } } clusteringCoefficient = (double) edgeCount/maxEdges; } // Calculate sum of neighbors out-degrees (+1) - int degreeSum = 0; - NodeCursor neighbors = node.successors(); - while(neighbors.ok()) { - Node neighbor = neighbors.node(); - degreeSum += neighbor.outDegree() + 1; - neighbors.next(); - } + int degreeSum = 0; + for (Node neighbor : graph.getSuccessorNeighbours(node)) { + degreeSum += neighbor.getOutDegree() + 1; + } res.setNodeValue(node, f(clusteringCoefficient)*degreeSum); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Coreness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Coreness.java index a4804fdf..bc8b0c6f 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Coreness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Coreness.java @@ -1,11 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -14,8 +9,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Coreness. @@ -23,6 +18,7 @@ * @author Tobias * */ +//TODO: Check if algorithm should not create extra own copy to remove nodes on public class Coreness implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { @@ -32,25 +28,30 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CORENESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // Execute k-core decomposition int k = 0; - while(!graph.isEmpty()) { + while(graph.getNodeCount() > 0) { if(Thread.interrupted()) { throw new InterruptedException(); } boolean nodeRemoved = true; while(nodeRemoved == true) { nodeRemoved = false; - nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); - if(node.inDegree() <= k) { + + nc = graph.iterator(); + ArrayList nodesToRemove = new ArrayList(); // List for nodes to be removed, cant remove during iteration + while(nc.hasNext()) { + Node node = nc.next(); + if(node.getInDegree() <= k) { res.setNodeValue(node, k); - graph.removeNode(node); + nodesToRemove.add(node); nodeRemoved = true; } - nc.next(); + } + + for(Node node : nodesToRemove) { // Remove nodes + graph.removeNode(node); } } k++; @@ -62,10 +63,10 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CORENESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc; + Iterator nc; // Execute k-core decomposition int k = 1; - while(!graph.isEmpty()) { + while(graph.getNodeCount() > 0) { if(Thread.interrupted()) { throw new InterruptedException(); } @@ -76,13 +77,12 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc nodeRemoved = false; // Find nodes with minimum degree List nodeRemoveList = new ArrayList(); - nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); if(graph.getWeightedInDegree(node) <= minDegree) { nodeRemoveList.add(node); } - nc.next(); } if(!nodeRemoveList.isEmpty()) { nodeRemoved = true; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowBetweenness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowBetweenness.java index 118bff68..abce5ca6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowBetweenness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowBetweenness.java @@ -1,9 +1,7 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.lang.reflect.Array; +import java.util.*; import org.la4j.inversion.GaussJordanInverter; import org.la4j.inversion.MatrixInverter; @@ -17,10 +15,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; + +import org.graphstream.graph.Node; + /** * Implementation of Current-Flow Betweenness. @@ -34,38 +32,35 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CURRENT_FLOW_BETWEENNESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } - int n = nc.size(); + int n = graph.getNodeCount(); Matrix L = new CCSMatrix(n, n); // Create laplacian matrix - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - int i = node.index(); + Node node = nc.next(); + int i = node.getIndex(); L.set(i, i, graph.getWeightedInDegree(node)); - nc.next(); } - EdgeCursor ec = graph.edges(); - while(ec.ok()) { + Iterator ec = graph.edges().iterator(); + while(ec.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - L.set(edge.source().index(), edge.target().index(), -graph.getEdgeWeight(edge)); - ec.next(); + Edge edge = ec.next(); + L.set(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), -graph.getEdgeWeight(edge)); } // Remove the first row and column @@ -73,7 +68,7 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { MatrixInverter gauss = new GaussJordanInverter(L); Matrix L_inverse = gauss.inverse(); - + // Create matrix C Matrix C = new CCSMatrix(n, n); for(int i = 0; i < n-1; i++) { @@ -81,76 +76,80 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { C.set(i+1, j+1, L_inverse.get(i, j)); } } - + /* * Each (undirected) edge must have an arbitrary but fixed orientation, * here it points from the node with the smaller index to the one with the higher index. * The edge in the opposite direction is removed. */ - ec.toFirst(); - while(ec.ok()) { + HashSet revEdgesToRemove = new HashSet(); + ec = graph.edges().iterator(); + while(ec.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - Node s = edge.source(); - Node t = edge.target(); - if(s.index() < t.index()) { - Edge reverseEdge = t.getEdgeTo(s); - graph.removeEdge(reverseEdge); + Edge edge = ec.next(); + if(!revEdgesToRemove.contains(edge)) { + Node s = edge.getSourceNode(); + Node t = edge.getTargetNode(); + if (s.getIndex() < t.getIndex()) { + Edge reverseEdge = t.getEdgeToward(s); + revEdgesToRemove.add(reverseEdge); + } } - ec.next(); + } + Iterator ecRem = revEdgesToRemove.iterator(); + while(ecRem.hasNext()) { + graph.removeEdge(ecRem.next()); } // Create matrix B - ec.toFirst(); - int m = ec.size(); + ec = graph.edges().iterator(); + int m = graph.getEdgeCount(); Matrix B = new CCSMatrix(m, n); int edgeIndex = 0; - while(ec.ok()) { + while(ec.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - int s = edge.source().index(); - int t = edge.target().index(); + Edge edge = ec.next(); + int s = edge.getSourceNode().getIndex(); + int t = edge.getTargetNode().getIndex(); B.set(edgeIndex, s, graph.getEdgeWeight(edge)); B.set(edgeIndex, t, -graph.getEdgeWeight(edge)); - ec.next(); edgeIndex++; } Matrix F = B.multiply(C); int normalizationFactor = (n-2)*(n-1); - Node[] nodeArray = graph.getNodeArray(); - nc.toFirst(); + + Node[] nodeArray = graph.nodes().toArray(Node[]::new); + nc = graph.nodes().iterator(); // Calculate centrality value for each node - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); double throughputSum = 0.0; for(int sourceIndex = 0; sourceIndex < n; sourceIndex++) { for(int targetIndex = sourceIndex+1; targetIndex < n; targetIndex++) { - if(sourceIndex != node.index() && targetIndex != node.index()) { + if(sourceIndex != node.getIndex() && targetIndex != node.getIndex()) { Node s = nodeArray[sourceIndex]; Node t = nodeArray[targetIndex]; - ec.toFirst(); + ec = graph.edges().iterator(); edgeIndex = 0; - while(ec.ok()) { - Edge edge = ec.edge(); - if(edge.target() == node || edge.source() == node) { - throughputSum += Math.abs(F.get(edgeIndex, s.index()) - F.get(edgeIndex, t.index())); + while(ec.hasNext()) { + Edge edge = ec.next(); + if(edge.getTargetNode() == node || edge.getSourceNode() == node) { + throughputSum += Math.abs(F.get(edgeIndex, s.getIndex()) - F.get(edgeIndex, t.getIndex())); } - ec.next(); edgeIndex++; } } } } res.setNodeValue(node, 1.0/normalizationFactor * throughputSum/2); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowCloseness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowCloseness.java index a8974acc..e32dffcb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowCloseness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/CurrentFlowCloseness.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.inversion.GaussJordanInverter; import org.la4j.inversion.MatrixInverter; @@ -17,10 +14,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; + +import org.graphstream.graph.Node; + /** * Implementation of Current-flow Closeness. @@ -34,43 +31,40 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.CURRENT_FLOW_CLOSENESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); res.setNodeValue(node, 0.0); - nc.next(); } // If the graph contains no edges - if(graph.edgeCount() == 0) { + if(graph.getEdgeCount() == 0) { return res; } - int n = nc.size(); + int n = graph.getNodeCount(); Matrix L = new CCSMatrix(n, n); // Create laplacian matrix - nc.toFirst(); - while(nc.ok()) { + nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - int i = node.index(); + Node node = nc.next(); + int i = node.getIndex(); L.set(i, i, graph.getWeightedInDegree(node)); - nc.next(); } - EdgeCursor ec = graph.edges(); - while(ec.ok()) { + Iterator ec = graph.edges().iterator(); + while(ec.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Edge edge = ec.edge(); - L.set(edge.source().index(), edge.target().index(), -graph.getEdgeWeight(edge)); - ec.next(); + Edge edge = ec.next(); + L.set(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), -graph.getEdgeWeight(edge)); } // Remove the first row and column @@ -87,35 +81,32 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } } - nc.toFirst(); - while(nc.ok()) { + nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node v = nc.node(); - NodeCursor nc2 = graph.nodes(); - while(nc2.ok()) { + Node v = nc.next(); + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node w = nc2.node(); - double increaseW = C.get(v.index(), v.index()); - double increaseV = increaseW - 2 * C.get(w.index(), v.index()); + Node w = nc2.next(); + double increaseW = C.get(v.getIndex(), v.getIndex()); + double increaseV = increaseW - 2 * C.get(w.getIndex(), v.getIndex()); res.setNodeValue(v, res.getNodeValue(v) + increaseV); res.setNodeValue(w, res.getNodeValue(w) + increaseW); - nc2.next(); - } - nc.next(); + } } - nc.toFirst(); - while(nc.ok()) { + nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); res.setNodeValue(node, (double)1/res.getNodeValue(node)); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/DegreeCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/DegreeCentrality.java index 420e79fc..19b57557 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/DegreeCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/DegreeCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of Degree Centrality. @@ -26,19 +24,18 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.DEGREE_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); /** * In an undirected graph each edge corresponds to two edges (a->b and b->a) and * directed graphs are made undirected before the execution. * Since each edge should only be counted once, the degree is divided by 2. **/ - res.setNodeValue(node, graph.getWeightedNodeDegree(node)/2); - nc.next(); + res.setNodeValue(node, graph.getWeightedNodeDegree((MultiNode) node)/2); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Eccentricity.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Eccentricity.java index 0c6d4c17..112d28d5 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Eccentricity.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Eccentricity.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,11 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; -import y.algo.ShortestPaths; +import org.graphstream.algorithm.Dijkstra; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + + /** * Implementation of Eccentricity. @@ -27,28 +26,47 @@ public class Eccentricity implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.ECCENTRICITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - - NodeCursor nc = graph.nodes(); + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + HashMap edgeweights = new HashMap(); + while (edges.hasNext()) { + edge = edges.next(); + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + + } + + Iterator nc = graph.iterator(); double[] edgeWeights = graph.getEdgeWeights(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - ShortestPaths.dijkstra(graph, node, true, edgeWeights, dist); + Node node = nc.next(); + double[] dist = new double[graph.getNodeCount()]; + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + double max = 0.0; - for(double d : dist) { - if(d > max) + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()){ + double d = dijkstra.getPathLength(nc2.next()); + if(d > max) { max = d; + } } + if(max == 0) { res.setNodeValue(node, 0); } else { res.setNodeValue(node, 1/max); } - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/EigenvectorCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/EigenvectorCentrality.java index e4b035b1..64d3d58a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/EigenvectorCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/EigenvectorCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.vector.Vector; @@ -16,8 +13,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Eigenvector Centrality. @@ -31,13 +28,12 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.EIGENVECTOR_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } @@ -45,13 +41,12 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Matrix A = graph.getNeighbourhoodMatrix(); Vector eigenvector = MatrixOperations.calculatePrincipalEigenvector(A); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, eigenvector.get(node.index())); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, eigenvector.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweenness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweenness.java index 293d6415..4ffc98d6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweenness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweenness.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,14 +9,14 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.algo.NetworkFlows; -import y.base.DataProvider; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.EdgeMap; -import y.base.Node; -import y.base.NodeCursor; -import y.util.Maps; +import org.graphstream.algorithm.flow.FlowAlgorithmBase; +import org.graphstream.algorithm.flow.FordFulkersonAlgorithm; +import org.graphstream.graph.Edge; + + +import org.graphstream.graph.Node; + + /** * Implementation of Flow Centrality. @@ -32,21 +29,32 @@ public class FlowBetweenness implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.FLOW_BETWEENNESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - - Node[] nodeArray = graph.getNodeArray(); - // The flow capacities are given by the edge weights, only integers are supported - double[] weights = graph.getEdgeWeights(); - int[] intWeights = new int[weights.length]; - for(int i = 0; i < graph.getEdgeWeights().length; i++) { - intWeights[i] = (int) weights[i]; + + Node[] nodeArray = graph.nodes().toArray(Node[]::new); + + FordFulkersonAlgorithm fordFulkerson = new FordFulkersonAlgorithm(); + fordFulkerson.init(graph); + + + + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + if(graph.isWeighted()) { + double modifiedWeight = 0.0f; + modifiedWeight = graph.getEdgeWeight(edge); + + fordFulkerson.setCapacity(edge.getSourceNode(), edge.getTargetNode(), fordFulkerson.getCapacity(edge.getSourceNode(), edge.getTargetNode()) + modifiedWeight); + } + else { + fordFulkerson.setCapacity(edge.getSourceNode(), edge.getTargetNode(), 1.0); + } } - DataProvider capacities = Maps.createIndexEdgeMap(intWeights); // Set initial values to 0 - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0.0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0.0); } // For each pair (i,j) of nodes calculate the maximum flow and add flows through the individual nodes to their centrality values @@ -59,29 +67,41 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { if(i != j) { Node sink = nodeArray[j]; - // Instantiate data structures - Map flowMap = new HashMap(); - EdgeMap flowEdgeMap = Maps.createEdgeMap(flowMap); // Calculate maximum flows with given source and sink - int maximumFlow = NetworkFlows.calcMaxFlow(graph, source, sink, capacities, flowEdgeMap); - + //TODO: Check whether yFiles and graphstream work differently with calculating flow when there are multi-edges or simply forward/backward edges + //int maximumFlow = NetworkFlows.calcMaxFlow(graph, source, sink, capacities, flowEdgeMap); + fordFulkerson.setSourceId(source.getId()); + fordFulkerson.setSinkId(sink.getId()); + + if(Objects.equals(source.getId(), "1") && Objects.equals(sink.getId(), "0")) { //TODO: Remove + System.out.println(); + } + + fordFulkerson.compute(); + double maximumFlow = fordFulkerson.getMaximumFlow(); + // Measure flow through all the nodes - nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); if(node != source && node != sink && maximumFlow != 0) { // Calculate flow through node int maximumFlowThroughNode = 0; - EdgeCursor inEdges = node.inEdges(); - while(inEdges.ok()) { - maximumFlowThroughNode += flowEdgeMap.getInt(inEdges.edge()); - inEdges.next(); + Set inNeighborsCheck = graph.getPredecessorNeighbours(node); + Iterator inNeighbors = graph.getPredecessorNeighbours(node).iterator(); + while(inNeighbors.hasNext()) { + Node nextneighbor = inNeighbors.next(); + if (!graph.isDirected()) { + maximumFlowThroughNode += fordFulkerson.getFlow(nextneighbor, node) < 0 ? -fordFulkerson.getFlow(nextneighbor, node) : fordFulkerson.getFlow(nextneighbor, node); //counter-act negative flows from graphstream for back edges in undirected graphs + } + else { + maximumFlowThroughNode += fordFulkerson.getFlow(nextneighbor, node) < 0 ? 0 : fordFulkerson.getFlow(nextneighbor, node); //TODO: Check this with graph that have forth/back edges + } } res.setNodeValue(node, res.getNodeValue(node) + maximumFlowThroughNode/maximumFlow); } - nc.next(); - } + } } } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HIndex.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HIndex.java index a3ae1eee..8e5ca053 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HIndex.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HIndex.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of the H-index. @@ -28,24 +26,23 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.H_INDEX, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); int h = 0; boolean checkNext = true; - NodeCursor neighbors = node.successors(); - while(graph.getWeightedNodeDegree(node)/2 >= h && checkNext) { + Iterator neighbors = graph.getSuccessorNeighbours(node).iterator(); + while(graph.getWeightedNodeDegree((MultiNode) node)/2 >= h && checkNext) { checkNext = false; - neighbors.toFirst(); + neighbors = graph.getSuccessorNeighbours(node).iterator(); int counter = 0; - while(neighbors.ok() && counter < h) { - if(graph.getWeightedNodeDegree(neighbors.node())/2 >= h) { + while(neighbors.hasNext() && counter < h) { + if(graph.getWeightedNodeDegree((MultiNode) neighbors.next())/2 >= h) { counter++; } - neighbors.next(); } if(counter >= h) { h++; @@ -53,7 +50,6 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } } res.setNodeValue(node, h-1); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HarmonicCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HarmonicCentrality.java index af87dbae..11fe70a4 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HarmonicCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HarmonicCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,11 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.algo.ShortestPaths; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.algorithm.Dijkstra; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of Harmonic Centrality. @@ -28,30 +27,46 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.HARMONIC_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If there is only a single node - if(graph.nodeCount() == 1) { - res.setNodeValue(nc.node(), 0); + if(graph.getNodeCount() == 1) { + res.setNodeValue(nc.next(), 0); return res; } - - double[] edgeWeights = graph.getEdgeWeights(); - while(nc.ok()) { + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + + while (edges.hasNext()) { + edge = edges.next(); + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + } + + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - ShortestPaths.dijkstra(graph, node, true, edgeWeights, dist); + Node node = nc.next(); + double[] dist = new double[graph.getNodeCount()]; + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + double inverseDistSum = 0.0; - for(double d : dist) { + + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()){ + double d = dijkstra.getPathLength(nc2.next()); if(d != 0.0) { inverseDistSum += 1.0/d; } } - res.setNodeValue(node, 1.0/(graph.nodeCount()-1.0)*inverseDistSum); - nc.next(); - } + res.setNodeValue(node, 1.0/(graph.getNodeCount()-1.0)*inverseDistSum); + } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsAuthorityScore.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsAuthorityScore.java index d3156cc4..23cf367c 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsAuthorityScore.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsAuthorityScore.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.vector.Vector; @@ -17,8 +14,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of the HITS authority score. @@ -32,14 +29,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.HITS_AUTHORITY_SCORE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - int n = graph.nodeCount(); + Iterator nc = graph.iterator(); + int n = graph.getNodeCount(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } @@ -90,9 +86,9 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } // Set centrality values to the authority weights - while(nc.ok()) { - res.setNodeValue(nc.node(), authorityWeights.get(nc.node().index())); - nc.next(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, authorityWeights.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsHubScore.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsHubScore.java index 5b3a7f18..c1ed7438 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsHubScore.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/HitsHubScore.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; import org.la4j.vector.Vector; @@ -17,8 +14,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of the HITS hub score. @@ -32,14 +29,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.HITS_HUB_SCORE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - int n = graph.nodeCount(); + Iterator nc = graph.iterator(); + int n = graph.getNodeCount(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } @@ -90,9 +86,9 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } // Set centrality values to the hub weights - while(nc.ok()) { - res.setNodeValue(nc.node(), hubWeights.get(nc.node().index())); - nc.next(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, hubWeights.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/InDegree.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/InDegree.java index b31449dc..78351d30 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/InDegree.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/InDegree.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of In-Degree. @@ -26,14 +23,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.IN_DEGREE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); res.setNodeValue(node, graph.getWeightedInDegree(node)); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Integration.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Integration.java index 6edeed35..0550f44a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Integration.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Integration.java @@ -24,7 +24,7 @@ public class Integration implements CentralityAlgorithm { public CentralityMap getValues(CustomGraph graph) throws InterruptedException { // The edge directions were reversed in the CentralityAlgorithmExecutor Radiality radialityAlgorithm = new Radiality(); - CentralityMap res = radialityAlgorithm.getValues(graph); + CentralityMap res = radialityAlgorithm.getValues(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.INTEGRATION, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/KatzCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/KatzCentrality.java index 988f3a5d..0306da8e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/KatzCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/KatzCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.inversion.GaussJordanInverter; import org.la4j.inversion.MatrixInverter; @@ -19,8 +16,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Katz Centrality. @@ -39,7 +36,7 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.KATZ_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - int n = graph.nodeCount(); + int n = graph.getNodeCount(); Matrix A_tr = graph.getNeighbourhoodMatrix().transpose(); // Create identity matrix and vector consisting of only ones @@ -55,14 +52,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Matrix inverse = gauss.inverse(); Vector resultVector = inverse.multiply(ones); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, resultVector.get(node.index())); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, resultVector.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LaplacianCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LaplacianCentrality.java index 8a51b34a..af04e658 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LaplacianCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LaplacianCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Laplacian Centrality. @@ -27,43 +24,42 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.LAPLACIAN_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); // Count closed 2-walks that contain the node double nwc = 0; Set neighbors = graph.getNeighbours(node); for(Node neighbor : neighbors) { - double edgeWeight = graph.getEdgeWeight(node.getEdgeTo(neighbor)); + double edgeWeight = graph.getEdgeWeight(node.getEdgeToward(neighbor)); nwc += edgeWeight * edgeWeight; } // Count 2-walks with node as an end point double nwe = 0; for(Node neighbor : neighbors) { - double edgeWeight1 = graph.getEdgeWeight(node.getEdgeTo(neighbor)); + double edgeWeight1 = graph.getEdgeWeight(node.getEdgeToward(neighbor)); Set twoStepNeighbors = graph.getNeighbours(neighbor); twoStepNeighbors.remove(node); for(Node twoStepNeighbor : twoStepNeighbors) { - double edgeWeight2 = graph.getEdgeWeight(neighbor.getEdgeTo(twoStepNeighbor)); + double edgeWeight2 = graph.getEdgeWeight(neighbor.getEdgeToward(twoStepNeighbor)); nwe += edgeWeight1 * edgeWeight2; } } // Count 2-walks with node in the middle double nwm = 0; for(Node neighbor : neighbors) { - double edgeWeight1 = graph.getEdgeWeight(neighbor.getEdgeTo(node)); + double edgeWeight1 = graph.getEdgeWeight(neighbor.getEdgeToward(node)); for(Node neighbor2 : neighbors) { if(neighbor != neighbor2) { - double edgeWeight2 = graph.getEdgeWeight(node.getEdgeTo(neighbor2)); + double edgeWeight2 = graph.getEdgeWeight(node.getEdgeToward(neighbor2)); nwm += edgeWeight1 * edgeWeight2; } } } res.setNodeValue(node, 4 * nwc + 2 * nwe + 2 * nwm); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LeaderRank.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LeaderRank.java index 6efe6f8a..563be5d1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LeaderRank.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LeaderRank.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,10 +9,11 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; + +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of LeaderRank. @@ -29,60 +27,57 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.LEADERRANK, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - int n = graph.nodeCount(); + Iterator nc = graph.iterator(); + int n = graph.getNodeCount(); // Set initial LeaderRank of all nodes to 1 - while(nc.ok()) { - res.setNodeValue(nc.node(), 1.0); - nc.next(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 1.0); } - nc.toFirst(); // Add ground node - Node groundNode = graph.createNode(); - while(nc.ok()) { - Node node = nc.node(); + Node groundNode = graph.addNode("groundNode"); + + nc = graph.iterator(); + + while(nc.hasNext()) { + Node node = nc.next(); if(node != groundNode) { // Add bidirectional edges - Edge e1 = graph.createEdge(groundNode, node); - Edge e2 = graph.createEdge(node, groundNode); + Edge e1 = graph.addEdge(UUID.randomUUID().toString(), groundNode, node); + Edge e2 = graph.addEdge(UUID.randomUUID().toString(), node, groundNode); graph.setEdgeWeight(e1, 1.0); graph.setEdgeWeight(e2, 1.0); } - nc.next(); } - nc.toFirst(); + nc = graph.iterator(); res.setNodeValue(groundNode, 0.0); - for(int k = 0; k < 50; k++) { if(Thread.interrupted()) { throw new InterruptedException(); } - while(nc.ok()) { - Node i = nc.node(); + while(nc.hasNext()) { + Node i = nc.next(); double weightedRankSum = 0.0; - EdgeCursor inLinks = i.inEdges(); - while(inLinks.ok()) { - Edge eji = inLinks.edge(); - Node j = eji.source(); - weightedRankSum += graph.getEdgeWeight(eji) * res.getNodeValue(j) / graph.getWeightedOutDegree(j); - inLinks.next(); - } + Iterator inLinks = i.enteringEdges().iterator(); + while(inLinks.hasNext()) { + Edge eji = inLinks.next(); + Node j = eji.getSourceNode(); + weightedRankSum += graph.getEdgeWeight(eji) * res.getNodeValue(j) / graph.getWeightedOutDegree((MultiNode) j); + } double newValue = weightedRankSum; res.setNodeValue(i, newValue); - nc.next(); } - nc.toFirst(); + nc = graph.iterator(); } // Distribute score of ground node evenly double share = res.getNodeValue(groundNode) / n; - while(nc.ok()) { - res.setNodeValue(nc.node(), res.getNodeValue(nc.node()) + share); - nc.next(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, res.getNodeValue(node) + share); } - + res.getMap().remove(null); // this is needed to avoid storing groundNode (used for calculations) in the database return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LocalRank.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LocalRank.java index 016fd38a..982a2a14 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LocalRank.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/LocalRank.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of LocalRank. @@ -29,40 +26,35 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { int localrank = 0; Set oneOrTwoStepNeighbors = new HashSet(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); localrank = 0; - NodeCursor c1 = node.successors(); - while(c1.ok()) { - Node n1 = c1.node(); - NodeCursor c2 = n1.successors(); - while(c2.ok()) { - Node n2 = c2.node(); + Iterator c1 = graph.getSuccessorNeighbours(node).iterator(); + while(c1.hasNext()) { + Node n1 = c1.next(); + Iterator c2 = graph.getSuccessorNeighbours(n1).iterator(); + while(c2.hasNext()) { + Node n2 = c2.next(); oneOrTwoStepNeighbors = new HashSet(); - NodeCursor c3 = n2.successors(); - while(c3.ok()) { - Node n3 = c3.node(); - oneOrTwoStepNeighbors.add(n3.index()); - NodeCursor c4 = n3.successors(); - while(c4.ok()) { - Node n4 = c4.node(); - oneOrTwoStepNeighbors.add(n4.index()); - c4.next(); + Iterator c3 =graph.getSuccessorNeighbours(n2).iterator(); + while(c3.hasNext()) { + Node n3 = c3.next(); + oneOrTwoStepNeighbors.add(n3.getIndex()); + Iterator c4 = graph.getSuccessorNeighbours(n3).iterator(); + while(c4.hasNext()) { + Node n4 = c4.next(); + oneOrTwoStepNeighbors.add(n4.getIndex()); } - c3.next(); } - oneOrTwoStepNeighbors.remove(n2.index()); + oneOrTwoStepNeighbors.remove(n2.getIndex()); localrank += oneOrTwoStepNeighbors.size(); - c2.next(); } - c1.next(); } res.setNodeValue(node, localrank); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/NeighborhoodCoreness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/NeighborhoodCoreness.java index dc323549..ee17a0b7 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/NeighborhoodCoreness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/NeighborhoodCoreness.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Neighborhood Coreness. @@ -32,21 +29,19 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Coreness corenessAlgorithm = new Coreness(); CentralityMap corenessMap = corenessAlgorithm.getValues(graphCopy); Map nameCorenessMap = corenessMap.getMap(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); + Node node = nc.next(); double neighborCorenessSum = 0.0; - NodeCursor neighbors = node.successors(); - while(neighbors.ok()) { - String nodeName = graph.getNodeName(neighbors.node()); + Iterator neighbors = graph.getSuccessorNeighbours(node).iterator(); + while(neighbors.hasNext()) { + String nodeName = graph.getNodeName(neighbors.next()); neighborCorenessSum += nameCorenessMap.get(nodeName); - neighbors.next(); - } + } res.setNodeValue(node, neighborCorenessSum); - nc.next(); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/OutDegree.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/OutDegree.java index 5bd207de..f22d78ea 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/OutDegree.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/OutDegree.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,8 +9,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of Out-Degree. @@ -26,14 +24,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.OUT_DEGREE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, graph.getWeightedOutDegree(node)); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, graph.getWeightedOutDegree((MultiNode) node)); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/PageRank.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/PageRank.java index daa9f225..e91830f6 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/PageRank.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/PageRank.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,10 +9,11 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; + +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; + /** * Implementation of PageRank. @@ -34,49 +32,45 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.PAGERANK, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // Set initial PageRank of all nodes to 1 - while(nc.ok()) { - res.setNodeValue(nc.node(), 1.0); - nc.next(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 1.0); } - nc.toFirst(); + nc = graph.iterator(); - int n = nc.size(); + int n = graph.getNodeCount(); for(int k = 0; k < 50; k++) { if(Thread.interrupted()) { throw new InterruptedException(); } - while(nc.ok()) { - Node i = nc.node(); + while(nc.hasNext()) { + Node i = nc.next(); double weightedRankSum = 0.0; - EdgeCursor inLinks = i.inEdges(); - while(inLinks.ok()) { - Edge eji = inLinks.edge(); - Node j = eji.source(); - weightedRankSum += graph.getEdgeWeight(eji) * res.getNodeValue(j) / graph.getWeightedOutDegree(j); - inLinks.next(); - } + Iterator inLinks = i.enteringEdges().iterator(); + while(inLinks.hasNext()) { + Edge eji = inLinks.next(); + Node j = eji.getSourceNode(); + weightedRankSum += graph.getEdgeWeight(eji) * res.getNodeValue(j) / graph.getWeightedOutDegree((MultiNode) j); + } double newValue = d * weightedRankSum + (1-d) * 1/n; res.setNodeValue(i, newValue); - nc.next(); } - nc.toFirst(); + nc = graph.iterator(); } // Scale the values, so they sum to 1 double sum = 0.0; - while(nc.ok()) { - sum += res.getNodeValue(nc.node()); - nc.next(); + while(nc.hasNext()) { + sum += res.getNodeValue(nc.next()); } - nc.toFirst(); + nc = graph.iterator(); double factor = 1/sum; - while(nc.ok()) { - res.setNodeValue(nc.node(), factor * res.getNodeValue(nc.node())); - nc.next(); - } + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, factor * res.getNodeValue(node)); + } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Radiality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Radiality.java index 982fb63a..fe24528b 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Radiality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/Radiality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.algo.ShortestPaths; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.algorithm.Dijkstra; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of Radiality. @@ -23,33 +21,50 @@ * */ public class Radiality implements CentralityAlgorithm { - + public CentralityMap getValues(CustomGraph graph) throws InterruptedException { + CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.RADIALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If there is only a single node - if(graph.nodeCount() == 1) { - res.setNodeValue(nc.node(), 0); + if(graph.getNodeCount() == 1) { + res.setNodeValue(nc.next(), 0); return res; } - + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + HashMap edgeweights = new HashMap(); + while (edges.hasNext()) { + edge = edges.next(); + + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + } + // Calculate the sum of distances and the number of reachable nodes for all nodes and find the diameter of the graph - double[] edgeWeights = graph.getEdgeWeights(); Map reachableNodes = new HashMap(); double maxDistance = 0; - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - - ShortestPaths.dijkstra(graph, node, true, edgeWeights, dist); + Node node = nc.next(); + double[] dist = new double[graph.getNodeCount()]; + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null,"edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + double distSum = 0.0; int reachableNodesCounter = 0; - for(double d : dist) { + + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()){ + double d = dijkstra.getPathLength(nc2.next()); if(d != Double.POSITIVE_INFINITY && d != 0) { distSum += d; reachableNodesCounter++; @@ -59,20 +74,18 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } reachableNodes.put(node, reachableNodesCounter); res.setNodeValue(node, distSum); - nc.next(); } - + // Reverse distances - nc.toFirst(); - while(nc.ok()) { - Node node = nc.node(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); double distSum = res.getNodeValue(node); /* - * Each distance in the sum is reversed which is equivalent to multiplying the number of reachable nodes with the + * Each distance in the sum is reversed which is equivalent to multiplying the number of reachable nodes with the * diameter of the graph and subtracting the sum of distances (+ 1 added to differentiate disconnected nodes). */ - res.setNodeValue(node, (reachableNodes.get(node) * (1 + maxDistance) - distSum)/(graph.nodeCount()-1)); - nc.next(); + res.setNodeValue(node, (reachableNodes.get(node) * (1 + maxDistance) - distSum)/(graph.getNodeCount()-1)); } return res; } @@ -89,12 +102,12 @@ public Set compatibleGraphTypes() { public CentralityMeasureType getCentralityMeasureType() { return CentralityMeasureType.RADIALITY; } - + @Override public HashMap getParameters() { return new HashMap(); } - + @Override public void setParameters(Map parameters) throws IllegalArgumentException { if(parameters.size() > 0) { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ResidualCloseness.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ResidualCloseness.java index 49b8f7d3..0a8f18ac 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ResidualCloseness.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/ResidualCloseness.java @@ -1,10 +1,8 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; +import org.graphstream.algorithm.Dijkstra; import org.la4j.matrix.Matrix; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; @@ -14,11 +12,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.algo.ShortestPaths; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; + +import org.graphstream.graph.Node; + /** * Implementation of Residual Centrality. @@ -32,79 +29,114 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.RESIDUAL_ClOSENESS, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); + Iterator nc = graph.iterator(); // If there are less than 3 nodes - if(graph.nodeCount() < 3) { - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + if(graph.getNodeCount() < 3) { + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } return res; } + + // Set edge length attribute for the Dijkstra algorithm + Iterator edges = graph.edges().iterator(); + Edge edge; + while (edges.hasNext()) { + edge = edges.next(); + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); + } // Calculate the network closeness (for normalization) - double[] edgeWeights = graph.getEdgeWeights(); - double networkCloseness = 0.0; - while(nc.ok()) { + double networkCloseness = 0.0; + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - ShortestPaths.dijkstra(graph, node, true, edgeWeights, dist); - for(double d : dist) { + Node node = nc.next(); + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()){ + double d = dijkstra.getPathLength(nc2.next()); if(d != 0) { networkCloseness += 1.0/Math.pow(2, d); } } - nc.next(); } Matrix A = graph.getNeighbourhoodMatrix(); - int n = graph.nodeCount(); - Node[] nodes = graph.getNodeArray(); + int n = graph.getNodeCount(); + Node[] nodes = graph.nodes().toArray(Node[]::new); + // Remove and re-add each node (by removing its edges) for(int k = 0; k < n; k++) { Node currentNode = nodes[k]; - // Remove edges - EdgeCursor currentNodeEdges = currentNode.edges(); - while(currentNodeEdges.ok()) { - graph.removeEdge(currentNodeEdges.edge()); - currentNodeEdges.next(); + ArrayList edgesToRemove = new ArrayList<>(); + + // Select edges to remove + Iterator currentNodeEdges = currentNode.edges().iterator(); + while(currentNodeEdges.hasNext()) { + Edge currEdge = currentNodeEdges.next(); + edgesToRemove.add(currEdge); + } + + // Remove the edges selected for removal + for (Edge edgeToRemove : edgesToRemove){ + graph.removeEdge(edgeToRemove); + } + + // set edge length attribute for the Dijkstra algorithm + edges = graph.edges().iterator(); + while (edges.hasNext()) { + edge = edges.next(); + edge.setAttribute("edgeLength", graph.getEdgeWeight(edge)); } - nc.toFirst(); + nc = graph.iterator(); double[] newEdgeWeights = graph.getEdgeWeights(); double distSum = 0.0; // Calculate the sum of distances in the graph without the current node - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - double[] dist = new double[graph.nodeCount()]; - ShortestPaths.dijkstra(graph, node, true, newEdgeWeights, dist); - for(double d : dist) { + Node node = nc.next(); + double[] dist = new double[graph.getNodeCount()]; + + // Length is determined by edge weight + Dijkstra dijkstra = new Dijkstra(Dijkstra.Element.EDGE, null, "edgeLength"); + dijkstra.init(graph); + dijkstra.setSource(node); + dijkstra.compute(); + + Iterator nc2 = graph.iterator(); + while(nc2.hasNext()){ + double d = dijkstra.getPathLength(nc2.next()); if(d != 0) { distSum += 1.0/Math.pow(2, d); } } - nc.next(); + } res.setNodeValue(currentNode, networkCloseness/distSum); // Recreate edges for(int i = 0; i < n; i++) { - double weight = A.get(currentNode.index(), i); + double weight = A.get(currentNode.getIndex(), i); if(weight != 0) { - Edge newEdge = graph.createEdge(currentNode, nodes[i]); + Edge newEdge = graph.addEdge(UUID.randomUUID().toString(), currentNode, nodes[i]); graph.setEdgeWeight(newEdge, weight); } } for(int i = 0; i < n; i++) { - double weight = A.get(i, currentNode.index()); + double weight = A.get(i, currentNode.getIndex()); if(weight != 0) { - Edge newEdge = graph.createEdge(nodes[i], currentNode); + Edge newEdge = graph.addEdge(UUID.randomUUID().toString(), nodes[i], currentNode); graph.setEdgeWeight(newEdge, weight); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaAuthorityScore.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaAuthorityScore.java index 4a5a2f66..5c63dc43 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaAuthorityScore.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaAuthorityScore.java @@ -1,10 +1,8 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; +import org.graphstream.graph.implementations.MultiNode; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; import org.la4j.vector.Vector; @@ -17,9 +15,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of the SALSA authority score. @@ -33,22 +31,21 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.SALSA_AUTHORITY_SCORE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - int n = graph.nodeCount(); + int n = graph.getNodeCount(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } // Create bipartite graph CustomGraph bipartiteGraph = new CustomGraph(); - Node[] nodes = graph.getNodeArray(); - Edge[] edges = graph.getEdgeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); + Edge[] edges = graph.edges().toArray(Edge[]::new); Map hubNodeMap = new HashMap(); Map authorityNodeMap = new HashMap(); Map reverseAuthorityNodeMap = new HashMap(); @@ -58,12 +55,12 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { if(Thread.interrupted()) { throw new InterruptedException(); } - if(node.outDegree() > 0) { - Node hubNode = bipartiteGraph.createNode(); + if(node.getOutDegree() > 0) { + Node hubNode = bipartiteGraph.addNode("hubNode" + node.getId()); hubNodeMap.put(node, hubNode); } - if(node.inDegree() > 0) { - Node authorityNode = bipartiteGraph.createNode(); + if(node.getInDegree() > 0) { + Node authorityNode = bipartiteGraph.addNode("authorityNode" + node.getId()); authorityNodeMap.put(node, authorityNode); reverseAuthorityNodeMap.put(authorityNode, node); } @@ -74,11 +71,11 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { if(Thread.interrupted()) { throw new InterruptedException(); } - Node oldSource = edge.source(); - Node oldTarget = edge.target(); + Node oldSource = edge.getSourceNode(); + Node oldTarget = edge.getTargetNode(); Node newSource = hubNodeMap.get(oldSource); Node newTarget = authorityNodeMap.get(oldTarget); - Edge newEdge = bipartiteGraph.createEdge(newSource, newTarget); + Edge newEdge = bipartiteGraph.addEdge(UUID.randomUUID().toString(), newSource, newTarget); bipartiteGraph.setEdgeWeight(newEdge, graph.getEdgeWeight(edge)); } @@ -89,36 +86,33 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { throw new InterruptedException(); } Node i = reverseAuthorityNodeMap.get(ia); - NodeCursor stepOne = ia.predecessors(); - while(stepOne.ok()) { - Node kh = stepOne.node(); - NodeCursor stepTwo = kh.successors(); - while(stepTwo.ok()) { - Node ja = stepTwo.node(); + Iterator stepOne = graph.getPredecessorNeighbours(ia).iterator(); + while(stepOne.hasNext()) { + Node kh = stepOne.next(); + Iterator stepTwo = graph.getSuccessorNeighbours(kh).iterator(); + while(stepTwo.hasNext()) { + Node ja = stepTwo.next(); Node j = reverseAuthorityNodeMap.get(ja); - double edgeWeightKI = bipartiteGraph.getEdgeWeight(kh.getEdgeTo(ia)); - double edgeWeightKJ = bipartiteGraph.getEdgeWeight(kh.getEdgeTo(ja)); + double edgeWeightKI = bipartiteGraph.getEdgeWeight(kh.getEdgeToward(ia)); + double edgeWeightKJ = bipartiteGraph.getEdgeWeight(kh.getEdgeToward(ja)); double weightedInDegreeI = bipartiteGraph.getWeightedInDegree(ia); - double weightedOutDegreeK = bipartiteGraph.getWeightedOutDegree(kh); - double oldAij = authorityMatrix.get(i.index(), j.index()); + double weightedOutDegreeK = bipartiteGraph.getWeightedOutDegree((MultiNode) kh); + double oldAij = authorityMatrix.get(i.getIndex(), j.getIndex()); double newAij = oldAij + (double)edgeWeightKI/weightedInDegreeI * (double)edgeWeightKJ/weightedOutDegreeK; - authorityMatrix.set(i.index(), j.index(), newAij); - stepTwo.next(); - } - stepOne.next(); + authorityMatrix.set(i.getIndex(), j.getIndex(), newAij); + } } } // Calculate stationary distribution of authority Markov chain Vector authorityVector = MatrixOperations.calculateStationaryDistribution(authorityMatrix); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, authorityVector.get(node.index())); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, authorityVector.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaHubScore.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaHubScore.java index 40c58ca2..fad6dea3 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaHubScore.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SalsaHubScore.java @@ -1,10 +1,8 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; +import org.graphstream.graph.implementations.MultiNode; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; import org.la4j.vector.Vector; @@ -17,9 +15,9 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of the SALSA hub score. @@ -33,22 +31,21 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.SALSA_HUB_SCORE, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - int n = graph.nodeCount(); + int n = graph.getNodeCount(); // If the graph contains no edges - if(graph.edgeCount() == 0) { - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); + if(graph.getEdgeCount() == 0) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); res.setNodeValue(node, 0); - nc.next(); } return res; } // Create bipartite graph CustomGraph bipartiteGraph = new CustomGraph(); - Node[] nodes = graph.getNodeArray(); - Edge[] edges = graph.getEdgeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); + Edge[] edges = graph.edges().toArray(Edge[]::new); Map hubNodeMap = new HashMap(); Map authorityNodeMap = new HashMap(); Map reverseHubNodeMap = new HashMap(); @@ -58,13 +55,13 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { if(Thread.interrupted()) { throw new InterruptedException(); } - if(node.outDegree() > 0) { - Node hubNode = bipartiteGraph.createNode(); + if(node.getOutDegree() > 0) { + Node hubNode = bipartiteGraph.addNode("hubNode" + node.getId()); hubNodeMap.put(node, hubNode); reverseHubNodeMap.put(hubNode, node); } - if(node.inDegree() > 0) { - Node authorityNode = bipartiteGraph.createNode(); + if(node.getInDegree() > 0) { + Node authorityNode = bipartiteGraph.addNode("authorityNode" + node.getId()); authorityNodeMap.put(node, authorityNode); } } @@ -74,11 +71,11 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { if(Thread.interrupted()) { throw new InterruptedException(); } - Node oldSource = edge.source(); - Node oldTarget = edge.target(); + Node oldSource = edge.getSourceNode(); + Node oldTarget = edge.getTargetNode(); Node newSource = hubNodeMap.get(oldSource); Node newTarget = authorityNodeMap.get(oldTarget); - Edge newEdge = bipartiteGraph.createEdge(newSource, newTarget); + Edge newEdge = bipartiteGraph.addEdge(UUID.randomUUID().toString(), newSource, newTarget); bipartiteGraph.setEdgeWeight(newEdge, graph.getEdgeWeight(edge)); } @@ -89,36 +86,33 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { throw new InterruptedException(); } Node i = reverseHubNodeMap.get(ih); - NodeCursor stepOne = ih.successors(); - while(stepOne.ok()) { - Node ka = stepOne.node(); - NodeCursor stepTwo = ka.predecessors(); - while(stepTwo.ok()) { - Node jh = stepTwo.node(); + Iterator stepOne = graph.getSuccessorNeighbours(ih).iterator(); + while(stepOne.hasNext()) { + Node ka = stepOne.next(); + Iterator stepTwo = graph.getPredecessorNeighbours(ka).iterator(); + while(stepTwo.hasNext()) { + Node jh = stepTwo.next(); Node j = reverseHubNodeMap.get(jh); - double edgeWeightIK = bipartiteGraph.getEdgeWeight(ih.getEdgeTo(ka)); - double edgeWeightJK = bipartiteGraph.getEdgeWeight(jh.getEdgeTo(ka)); - double weightedOutDegreeI = bipartiteGraph.getWeightedOutDegree(ih); + double edgeWeightIK = bipartiteGraph.getEdgeWeight(ih.getEdgeToward(ka)); + double edgeWeightJK = bipartiteGraph.getEdgeWeight(jh.getEdgeToward(ka)); + double weightedOutDegreeI = bipartiteGraph.getWeightedOutDegree((MultiNode) ih); double weightedInDegreeK = bipartiteGraph.getWeightedInDegree(ka); - double oldHij = hubMatrix.get(i.index(), j.index()); + double oldHij = hubMatrix.get(i.getIndex(), j.getIndex()); double newHij = oldHij + (double)edgeWeightIK/weightedOutDegreeI * (double)edgeWeightJK/weightedInDegreeK; - hubMatrix.set(i.index(), j.index(), newHij); - stepTwo.next(); - } - stepOne.next(); + hubMatrix.set(i.getIndex(), j.getIndex(), newHij); + } } } // Calculate stationary distribution of hub Markov chain Vector hubVector = MatrixOperations.calculateStationaryDistribution(hubMatrix); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node node = nc.node(); - res.setNodeValue(node, hubVector.get(node.index())); - nc.next(); + Node node = nc.next(); + res.setNodeValue(node, hubVector.get(node.getIndex())); } return res; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/StressCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/StressCentrality.java index ec187ca6..30a7e988 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/StressCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/StressCentrality.java @@ -1,12 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.Stack; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -15,9 +9,10 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + /** * Implementation of Stress Centrality. @@ -34,18 +29,17 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.STRESS_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } - nc.toFirst(); + nc = graph.iterator(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node s = nc.node(); + Node s = nc.next(); // Variable declaration Queue Q = new LinkedList(); @@ -56,15 +50,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Map delta = new HashMap(); // Initialization - NodeCursor iterator = graph.nodes(); - while(iterator.ok()) { - Node w = iterator.node(); + Iterator iterator = graph.iterator(); + while(iterator.hasNext()) { + Node w = iterator.next(); Pred.put(w, new LinkedList()); dist.put(w, Double.POSITIVE_INFINITY); sigma.put(w, 0); - iterator.next(); } dist.put(s, 0.0); sigma.put(s, 1); @@ -75,9 +68,9 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Node v = Q.poll(); S.push(v); - NodeCursor outNeighbors = v.successors(); - while(outNeighbors.ok()) { - Node w = outNeighbors.node(); + Iterator outNeighbors = graph.getSuccessorNeighbours(v).iterator(); + while(outNeighbors.hasNext()) { + Node w = outNeighbors.next(); // Path discovery if(dist.get(w) == Double.POSITIVE_INFINITY) { @@ -91,16 +84,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { Pred.get(w).add(v); } - outNeighbors.next(); } } // Accumulation - iterator.toFirst(); - while(iterator.ok()) { - Node v = iterator.node(); + iterator = graph.iterator(); + while(iterator.hasNext()) { + Node v = iterator.next(); delta.put(v, 0.0); - iterator.next(); } while(!S.isEmpty()) { @@ -112,15 +103,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { res.setNodeValue(w, res.getNodeValue(w) + delta.get(w)); } } - nc.next(); } // If graph is undirected, divide centrality values by 2 if(!graph.getTypes().contains(GraphType.DIRECTED)) { - nc.toFirst(); - while(nc.ok()) { - res.setNodeValue(nc.node(), res.getNodeValue(nc.node())/2); - nc.next(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, res.getNodeValue(node)/2); } } return res; @@ -130,18 +120,17 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.STRESS_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } - nc.toFirst(); + nc = graph.iterator(); - while(nc.ok()) { + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node s = nc.node(); + Node s = nc.next(); // Variable declaration Queue Q = new LinkedList(); @@ -152,13 +141,12 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc Map delta = new HashMap(); // Initialization - NodeCursor iterator = graph.nodes(); - while(iterator.ok()) { - Node w = iterator.node(); + Iterator iterator = graph.iterator(); + while(iterator.hasNext()) { + Node w = iterator.next(); Pred.put(w, new LinkedList()); dist.put(w, Double.POSITIVE_INFINITY); sigma.put(w, 0); - iterator.next(); } dist.put(s, 0.0); sigma.put(s, 1); @@ -175,14 +163,15 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc S.push(v); Q.remove(v); - // NodeCursor outNeighbors = v.successors(); - EdgeCursor outEdges = v.outEdges(); - while(outEdges.ok()) { - Node w = outEdges.edge().target(); + // Iterator outNeighbors = v.successors(); + Iterator outEdges = v.leavingEdges().iterator(); + while(outEdges.hasNext()) { + Edge outEdge = outEdges.next(); + Node w = outEdge.getTargetNode(); // Path discovery - if(dist.get(w) > dist.get(v) + graph.getEdgeWeight(outEdges.edge())) { - dist.put(w, dist.get(v) + graph.getEdgeWeight(outEdges.edge())); + if(dist.get(w) > dist.get(v) + graph.getEdgeWeight(outEdge)) { + dist.put(w, dist.get(v) + graph.getEdgeWeight(outEdge)); if(!Q.contains(w)) Q.add(w); sigma.put(w, 0); @@ -190,21 +179,19 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc } // Path counting - if(dist.get(w) == dist.get(v) + graph.getEdgeWeight(outEdges.edge())) { + if(dist.get(w) == dist.get(v) + graph.getEdgeWeight(outEdge)) { sigma.put(w, sigma.get(w) + sigma.get(v)); Pred.get(w).add(v); } - outEdges.next(); } } // Accumulation - iterator.toFirst(); - while(iterator.ok()) { - Node v = iterator.node(); + iterator = graph.iterator(); + while(iterator.hasNext()) { + Node v = iterator.next(); delta.put(v, 0.0); - iterator.next(); } while(!S.isEmpty()) { Node w = S.pop(); @@ -215,15 +202,14 @@ private CentralityMap getValuesWeighted(CustomGraph graph) throws InterruptedExc res.setNodeValue(w, res.getNodeValue(w) + delta.get(w)); } } - nc.next(); } // If graph is undirected, divide centrality values by 2 if(!graph.getTypes().contains(GraphType.DIRECTED)) { - nc.toFirst(); - while(nc.ok()) { - res.setNodeValue(nc.node(), res.getNodeValue(nc.node())/2); - nc.next(); + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); + res.setNodeValue(node, res.getNodeValue(node)/2); } } return res; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SubgraphCentrality.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SubgraphCentrality.java index f620f816..deb5a9e8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SubgraphCentrality.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/measures/SubgraphCentrality.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; @@ -14,8 +11,8 @@ import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + /** * Implementation of Subgraph Centrality. @@ -31,10 +28,9 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap res = new CentralityMap(graph); res.setCreationMethod(new CentralityCreationLog(CentralityMeasureType.SUBGRAPH_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - res.setNodeValue(nc.node(), 0); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + res.setNodeValue(nc.next(), 0); } Matrix A = graph.getNeighbourhoodMatrix(); @@ -44,12 +40,11 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } Matrix powerOfA = A.power(p); long weight = factorial(p); - nc.toFirst(); - while(nc.ok()) { - Node node = nc.node(); - double weightedCycles = powerOfA.get(node.index(), node.index())/weight; + nc = graph.iterator(); + while(nc.hasNext()) { + Node node = nc.next(); + double weightedCycles = powerOfA.get(node.getIndex(), node.getIndex())/weight; res.setNodeValue(node, res.getNodeValue(node) + weightedCycles); - nc.next(); } } return res; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionUnweighted.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionUnweighted.java index 67c34aab..ed8550ee 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionUnweighted.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionUnweighted.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.simulations; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,8 @@ import i5.las2peer.services.ocd.centrality.utils.CentralitySimulation; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * In this simulation each node sends a package to each node in the graph (including itself). @@ -30,8 +26,8 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap map = new CentralityMap(graph); map.setCreationMethod(new CentralityCreationLog(CentralitySimulationType.RANDOM_PACKAGE_TRANSMISSION_UNWEIGHTED, CentralityCreationType.SIMULATION, this.getParameters(), this.compatibleGraphTypes())); - Node[] nodes = graph.getNodeArray(); - double[] passageCounter = new double[graph.nodeCount()]; + Node[] nodes = graph.nodes().toArray(Node[]::new); + double[] passageCounter = new double[graph.getNodeCount()]; int sPos = 0; int tPos = 0; @@ -46,15 +42,14 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } Node currentNode = nodes[packagePosition]; // Determine incident edges - Edge[] incidentEdges = new Edge[currentNode.outDegree()]; - double currentDegree = currentNode.outDegree(); - EdgeCursor ec = currentNode.outEdges(); + Edge[] incidentEdges = new Edge[currentNode.getOutDegree()]; + double currentDegree = currentNode.getOutDegree(); + Iterator ec = currentNode.leavingEdges().iterator(); int i = 0; - while(ec.ok()) { - Edge edge = ec.edge(); + while(ec.hasNext()) { + Edge edge = ec.next(); incidentEdges[i] = edge; i++; - ec.next(); } // Choose one of the edges at random int randomEdgeIndex = -1; @@ -67,8 +62,8 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } } Edge nextEdge = incidentEdges[randomEdgeIndex]; - packagePosition = nextEdge.target().index(); - passageCounter[nextEdge.target().index()]++; + packagePosition = nextEdge.getTargetNode().getIndex(); + passageCounter[nextEdge.getTargetNode().getIndex()]++; } // Change the position of t tPos++; @@ -77,7 +72,7 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { sPos++; } // Set centrality value equal to the number of times a package passed the node - for(int i = 0; i < graph.nodeCount(); i++) { + for(int i = 0; i < graph.getNodeCount(); i++) { map.setNodeValue(nodes[i], passageCounter[i]); } return map; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionWeighted.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionWeighted.java index 90a58e8f..4281301d 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionWeighted.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/RandomPackageTransmissionWeighted.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.centrality.simulations; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; @@ -12,9 +9,8 @@ import i5.las2peer.services.ocd.centrality.utils.CentralitySimulation; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * In this simulation each node sends a package to each node in the graph (including itself). @@ -31,8 +27,8 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap map = new CentralityMap(graph); map.setCreationMethod(new CentralityCreationLog(CentralitySimulationType.RANDOM_PACKAGE_TRANSMISSION_UNWEIGHTED, CentralityCreationType.SIMULATION, this.getParameters(), this.compatibleGraphTypes())); - Node[] nodes = graph.getNodeArray(); - double[] passageCounter = new double[graph.nodeCount()]; + Node[] nodes = graph.nodes().toArray(Node[]::new); + double[] passageCounter = new double[graph.getNodeCount()]; int sPos = 0; int tPos = 0; @@ -47,18 +43,17 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } Node currentNode = nodes[packagePosition]; // Determine incident edges and edge weights - Edge[] incidentEdges = new Edge[currentNode.outDegree()]; - double[] incidentEdgesWeights = new double[currentNode.outDegree()]; + Edge[] incidentEdges = new Edge[currentNode.getOutDegree()]; + double[] incidentEdgesWeights = new double[currentNode.getOutDegree()]; double currentDegree = 0; - EdgeCursor ec = currentNode.outEdges(); + Iterator ec = currentNode.leavingEdges().iterator(); int i = 0; - while(ec.ok()) { - Edge edge = ec.edge(); + while(ec.hasNext()) { + Edge edge = ec.next(); incidentEdges[i] = edge; incidentEdgesWeights[i] = graph.getEdgeWeight(edge); currentDegree += incidentEdgesWeights[i]; i++; - ec.next(); } // Choose one of the edges using probabilities proportional to the edge weight int randomEdgeIndex = -1; @@ -71,8 +66,8 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { } } Edge nextEdge = incidentEdges[randomEdgeIndex]; - packagePosition = nextEdge.target().index(); - passageCounter[nextEdge.target().index()]++; + packagePosition = nextEdge.getTargetNode().getIndex(); + passageCounter[nextEdge.getTargetNode().getIndex()]++; } // Change the position of t tPos++; @@ -81,7 +76,7 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { sPos++; } // Set centrality value equal to the number of times a package passed the node - for(int i = 0; i < graph.nodeCount(); i++) { + for(int i = 0; i < graph.getNodeCount(); i++) { map.setNodeValue(nodes[i], passageCounter[i]); } return map; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/SirSimulation.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/SirSimulation.java index 80b3524a..e16aa8bd 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/SirSimulation.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/simulations/SirSimulation.java @@ -14,8 +14,8 @@ import i5.las2peer.services.ocd.centrality.utils.CentralitySimulation; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Implementation of a susceptible-infected-recovered process with a single source node @@ -43,19 +43,18 @@ public CentralityMap getValues(CustomGraph graph) throws InterruptedException { CentralityMap map = new CentralityMap(graph); map.setCreationMethod(new CentralityCreationLog(CentralitySimulationType.SIR, CentralityCreationType.SIMULATION, this.getParameters(), this.compatibleGraphTypes())); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { + Iterator nc = graph.iterator(); + while(nc.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node currentNode = nc.node(); + Node currentNode = nc.next(); double spreadingSum = 0; for(int i = 0; i < repetitions; i++) { spreadingSum += runSimulation(graph, currentNode); } spreadingSum /= repetitions; map.setNodeValue(currentNode, spreadingSum); - nc.next(); } return map; } @@ -74,13 +73,12 @@ private int runSimulation(CustomGraph graph, Node sourceNode) throws Interrupted this.sourceNode = sourceNode; infectedNodes.add(sourceNode); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - infectionMap.put(nc.node(), InfectionState.SUSCEPTIBLE); - nc.next(); + Iterator nc = graph.iterator(); + while(nc.hasNext()) { + infectionMap.put(nc.next(), InfectionState.SUSCEPTIBLE); } for(Node infected : infectedNodes) { - if(graph.contains(infected)) { + if(graph.getNode(infected.getId()) != null) { infectionMap.put(infected, InfectionState.INFECTED); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/utils/CentralityAlgorithmExecutor.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/utils/CentralityAlgorithmExecutor.java index e657c683..de4ff369 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/utils/CentralityAlgorithmExecutor.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/centrality/utils/CentralityAlgorithmExecutor.java @@ -23,6 +23,7 @@ public class CentralityAlgorithmExecutor { * @throws InterruptedException In case of an algorithm interrupt. */ public CentralityMap execute(CustomGraph graph, CentralityAlgorithm algorithm) throws CentralityAlgorithmException, InterruptedException { + CustomGraph graphCopy = new CustomGraph(graph); GraphProcessor processor = new GraphProcessor(); processor.makeCompatible(graphCopy, algorithm.compatibleGraphTypes()); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandler.java deleted file mode 100644 index 716fbba1..00000000 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandler.java +++ /dev/null @@ -1,297 +0,0 @@ -package i5.las2peer.services.ocd.cooperation.data; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.TypedQuery; - -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeries; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeriesGroup; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeriesParameters; -import i5.las2peer.services.ocd.cooperation.simulation.dynamic.DynamicType; -import i5.las2peer.services.ocd.cooperation.simulation.game.GameType; -import i5.las2peer.services.ocd.utils.EntityHandler; - -public class SimulationEntityHandler extends EntityHandler { - - private static SimulationEntityHandler handler; - - public static synchronized SimulationEntityHandler getInstance() { - if (handler == null) { - handler = new SimulationEntityHandler(); - } - return handler; - } - - //////////////////////// Simulation Series ////////////////////////// - - /** - * Return a persisted SimulationSeries - * - * @param seriesId Id of the simulation series - * @return the requested simulation series - */ - public SimulationSeries getSimulationSeries(long seriesId) { - - SimulationSeries series; - EntityManager em = getEntityManager(); - try { - em.getTransaction().begin(); - series = em.find(SimulationSeries.class, seriesId); - em.getTransaction().commit(); - } catch (RuntimeException e) { - em.getTransaction().rollback(); - throw e; - } - - return series; - } - - /** - * Persists a SimulationSeries - * - * @param series the simulation series - * @param userId the users id - * @return the persistence id - */ - public synchronized long store(SimulationSeries series, String userId) { - - series.setUserId(userId); - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.getTransaction().commit(); - - long seriesId = series.getId(); - em.close(); - - return seriesId; - } - - /** - * Removes a SimulatioSeries from the database - * - * @param Id SimulationSeries id - */ - public void deleteSeries(long Id) { - - SimulationSeries simulation = getSimulationSeries(Id); - delete(simulation); - } - - /** - * Removes a SimulatioSeries from the database - * - * @param series SimulationSeries - */ - public synchronized void delete(SimulationSeries series) { - - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - series = em.getReference(SimulationSeries.class, series.getId()); - em.remove(series); - em.close(); - } - - /** - * @param userId the users id - * @return all SimulationSeries of a specific user - */ - public List getSimulationSeriesByUser(String userId) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery("SELECT s FROM SimulationSeries s WHERE s.userId = :id", SimulationSeries.class); - query.setParameter("id", userId); - List seriesList = query.getResultList(); - return seriesList; - } - - /** - * @param userId Id of the user - * @param firstIndex Id of the first simulation - * @param length Number of simulations - * @return List of SimulationSeries of a specific user - */ - public List getSimulationSeriesByUser(String userId, int firstIndex, int length) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery("SELECT s FROM SimulationSeries s WHERE s.userId = :id", SimulationSeries.class); - query.setFirstResult(firstIndex); - query.setMaxResults(length); - query.setParameter("id", userId); - List seriesList = query.getResultList(); - return seriesList; - } - - /** - * Returns a list of SimulationSeries filtered by their parameters - * @param userId the users id - * @param dynamic the type of dynamic - * @param game the game used - * @param graphId the graphs id - * @return List of SimulationsSeries - */ - public List getSimulationSeries(String userId, long graphId, DynamicType dynamic, GameType game) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery( - "SELECT s FROM SimulationSeries s WHERE s.userId =:userId AND s.graphId =:graphId AND s.dynamic =:dynamic AND s.game =:game", - SimulationSeries.class); - - query.setParameter("userId", userId); - query.setParameter("graphId", graphId); - query.setParameter("dynamic", dynamic); - query.setParameter("game", game); - List seriesList = query.getResultList(); - return seriesList; - } - - /** - * Returns a list of SimulationSeries filtered by the graphId - * - * @param userId the users id - * @param firstIndex the first index - * @param length the length of the result set - * @param graphId the graphs id - * @return simulation series list - */ - public List getSimulationSeriesByUser(String userId, long graphId, int firstIndex, int length) { - - List seriesList = getSimulationSeriesByUser(userId, firstIndex, length); - List resultList = new ArrayList<>(); - for (SimulationSeries series : seriesList) { - if (series.getParameters().getGraphId() == graphId) - resultList.add(series); - } - return resultList; - } - - - /** - * Returns the parameters of a simulation series - * - * @param seriesId the id of the series - * @return the series parameters - */ - public SimulationSeriesParameters getSimulationParameters(long seriesId) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery("SELECT p FROM SimulationSeriesParameters AS p WHERE s.series_seriesId =:id", - SimulationSeriesParameters.class); - query.setParameter("id", seriesId); - SimulationSeriesParameters parameters = query.getSingleResult(); - return parameters; - } - - -//////////////////////// Simulation Series Groups ////////////////////////// - - /** - * Persists a SimulationSeriesGroup - * - * @param userId the users id - * @param group the SimulationSeriesGroup - * @return its id - */ - public synchronized long store(SimulationSeriesGroup group, String userId) { - - group.setUserId(userId); - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - em.persist(group); - em.flush(); - em.getTransaction().commit(); - - long id = group.getId(); - em.close(); - - return id; - } - - /** - * Returns a persisted SimulationSeriesGroup - * - * @param id SimulationSeriesGroup Id - * @return its id - */ - public SimulationSeriesGroup getSimulationSeriesGroup(long id) { - - SimulationSeriesGroup simulation; - EntityManager em = getEntityManager(); - try { - em.getTransaction().begin(); - simulation = em.find(SimulationSeriesGroup.class, id); - em.getTransaction().commit(); - } catch (RuntimeException e) { - em.getTransaction().rollback(); - throw e; - } - return simulation; - } - - /** - * Removes a SimulatioSeriesGroup from the database - * - * @param id the id of the SimulationSeriesGroup - */ - public void deleteGroup(long id) { - - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - SimulationSeriesGroup simulation = em.getReference(SimulationSeriesGroup.class, id); - em.remove(simulation); - em.getTransaction().commit(); - em.close(); - } - - /** - * Removes a SimulatioSeriesGroup from the database - * - * @param simulation SimulationSeriesGroup - */ - public synchronized void delete(SimulationSeriesGroup simulation) { - - EntityManager em = getEntityManager(); - em.getTransaction().begin(); - simulation = em.getReference(SimulationSeriesGroup.class, simulation.getId()); - em.remove(simulation); - em.getTransaction().commit(); - em.close(); - } - - - /** - * @param userId the users id - * @return all SimulationSeriesGroups of a specific user - */ - public List getSimulationSeriesGroups(String userId) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery("SELECT s FROM SimulationSeriesGroup s WHERE s.userId = :id", SimulationSeriesGroup.class); - query.setParameter("id", userId); - List list = query.getResultList(); - return list; - } - - /** - * Return a list of SimulationSeriesGroups. - * - * @param userId Id of owner - * @param firstIndex the first index - * @param length Number of entries - * @return simulationSeriesGroups - */ - public List getSimulationSeriesGroups(String userId, int firstIndex, int length) { - - EntityManager em = getEntityManager(); - TypedQuery query = em.createQuery("SELECT s FROM SimulationSeriesGroup s WHERE s.userId = :id", SimulationSeriesGroup.class); - query.setFirstResult(firstIndex); - query.setMaxResults(length); - query.setParameter("id", userId); - List list = query.getResultList(); - return list; - } - - -} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/mapping/MappingList.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/mapping/MappingList.java index 3c5c96c0..74e44022 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/mapping/MappingList.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/mapping/MappingList.java @@ -38,7 +38,7 @@ public double[] getPropertyValues(GraphProperty property) { double[] properties = mapping.getPropertyValues(property); for (int i = 0; i < properties.length; i++) { if (mapping.getCover().getCommunitySize(i) > 1) { - if (mapping.getCover().getCommunitySize(i) < mapping.getCover().getGraph().nodeCount()) { + if (mapping.getCover().getCommunitySize(i) < mapping.getCover().getGraph().getNodeCount()) { values.add(properties[i]); } } @@ -61,7 +61,7 @@ public double[] getCooperationValues() { double[] cooperation = mapping.getCooperationValues(); for (int i = 0; i < cooperation.length; i++) { if (mapping.getCover().getCommunitySize(i) > 1) { - if (mapping.getCover().getCommunitySize(i) < mapping.getCover().getGraph().nodeCount()) { + if (mapping.getCover().getCommunitySize(i) < mapping.getCover().getGraph().getNodeCount()) { values.add(cooperation[i]); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/AgentData.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/AgentData.java index 292be13e..f32d1acf 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/AgentData.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/AgentData.java @@ -2,61 +2,46 @@ import java.util.List; -import javax.persistence.Basic; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Transient; +import javax.persistence.*; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @Entity +@JsonIgnoreProperties(ignoreUnknown = true) +/** + * Class to hold agent related data + */ public class AgentData { - /** - * identity. Used as persistence primary key - */ - @Id - @GeneratedValue - private long id; - /** * The simulation dataset this agent data belongs to */ - @ManyToOne(fetch = FetchType.EAGER) - private SimulationDataset dataset; + private SimulationDataset simulationDataset; /** * Used strategies of every generation */ - @Transient private List strategies; /** * Received payoff of every generation */ - @Transient private List payoff; /** * The cooperativity value of the agent. Averaged over the last strategies */ - @Basic private double cooperativity; /** * The wealth value of the agent. Averaged over the last payoff values. */ - @Basic private double wealth; - @Basic private boolean finalStrategy; - @Basic private double finalPayoff; ///// Constructor ///// @@ -152,4 +137,30 @@ public void setWealth(double wealth) { this.wealth = wealth; } + public SimulationDataset getSimulationDataset() { + return simulationDataset; + } + + public void setSimulationDataset(SimulationDataset simulationDataset) { + this.simulationDataset = simulationDataset; + } + + public boolean isFinalStrategy() { + return finalStrategy; + } + + + + @Override + public String toString() { + return "AgentData{" + + ", simulationDataset=" + simulationDataset + + ", strategies=" + strategies + + ", payoff=" + payoff + + ", cooperativity=" + cooperativity + + ", wealth=" + wealth + + ", finalStrategy=" + finalStrategy + + ", finalPayoff=" + finalPayoff + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/Evaluation.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/Evaluation.java index 353ef7a7..8971f328 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/Evaluation.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/Evaluation.java @@ -3,12 +3,16 @@ import java.io.Serializable; import java.util.List; -import javax.persistence.Basic; import javax.persistence.Embeddable; + +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; import org.apache.commons.math3.stat.StatUtils; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; import i5.las2peer.services.ocd.cooperation.data.table.TableRow; @@ -20,23 +24,22 @@ @Embeddable public class Evaluation implements Serializable { - private static final long serialVersionUID = 1L; - ///////// Entity Fields /////////// + private static final long serialVersionUID = 1L; - @Basic + @JsonProperty private double average; - @Basic + @JsonProperty private double variance; - @Basic + @JsonProperty private double deviation; - @Basic + @JsonProperty private double maximum; - @Basic + @JsonProperty private double minimum; /////////// Constructor /////////// @@ -124,59 +127,44 @@ private double calculateMin(double[] values) { //////////// Getter ///////////// - @JsonProperty - public double getAverage() { - return average; - } + public double getAverage() {return average; } - @JsonProperty public double getVariance() { return this.variance; } - @JsonProperty public double getDeviation() { return this.deviation; } - @JsonProperty - public double getMax() { + public double getMaximum() { return maximum; } - @JsonProperty - public double getMin() { + public double getMinimum() { return minimum; } - ////// Setter ////// - - @JsonSetter public void setAverage(double average) { this.average = average; } - @JsonSetter public void setVariance(double variance) { this.variance = variance; } - @JsonSetter public void setDeviation(double deviation) { this.deviation = deviation; } - @JsonSetter - public void setMax(double max) { + public void setMaximum(double max) { this.maximum = max; } - @JsonSetter - public void setMin(double min) { + public void setMinimum(double min) { this.minimum = min; } - /////////// Table /////////// public TableRow toTableLine() { @@ -192,4 +180,14 @@ public static TableRow toHeadLine() { return line; } + @Override + public String toString() { + return "Evaluation{" + + "average=" + average + + ", variance=" + variance + + ", deviation=" + deviation + + ", maximum=" + maximum + + ", minimum=" + minimum + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/GroupParameters.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/GroupParameters.java index 851e57e4..c9482e39 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/GroupParameters.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/GroupParameters.java @@ -8,6 +8,11 @@ import javax.persistence.Id; import javax.persistence.OneToOne; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; @@ -19,22 +24,16 @@ @Entity public class GroupParameters implements TableLineInterface { - ////////// Entity Fields ////////// - - @Id - @OneToOne(fetch = FetchType.EAGER) - SimulationSeriesGroup simulations; - - @Basic - private long graphId; + @JsonProperty + private String graphKey; - @Enumerated(EnumType.STRING) - private GroupType game; + @JsonProperty + private GroupType game; //TODO: why is this GroupType and not GameType? - @Basic + @JsonProperty private int scaling; - @Enumerated(EnumType.STRING) + @JsonProperty private DynamicType dynamic; ////////// Constructor ////////// @@ -42,66 +41,44 @@ public class GroupParameters implements TableLineInterface { public GroupParameters() { } - ////////// Getter ////////// - - @JsonIgnore - public SimulationSeriesGroup getSimulations() { - return simulations; - } - - @JsonProperty - public long getGraphId() { - return graphId; - } - - @JsonProperty + public GroupType getGame() { return game; } - - @JsonProperty + public int getScaling() { return scaling; } - - @JsonProperty + public DynamicType getDynamic() { return dynamic; } - ////////// Setter ////////// - - @JsonIgnore - public void setSimulations(SimulationSeriesGroup simulations) { - this.simulations = simulations; + public String getGraphKey() { + return graphKey; } - - @JsonSetter - public void setGraphId(long graphId) { - this.graphId = graphId; + + public void setGraphKey(String graphKey) { + this.graphKey = graphKey; } - - @JsonIgnore + public void setGame(GroupType game) { this.game = game; } - - @JsonSetter + public void setGame(String game) { this.game = GroupType.fromString(game); } - - @JsonSetter + public void setScaling(int scaling) { this.scaling = scaling; } - - @JsonIgnore + public void setDynamic(DynamicType dynamic) { this.dynamic = dynamic; } - @JsonSetter + public void setDynamic(String dynamic) { this.dynamic = DynamicType.fromString(dynamic); } @@ -110,7 +87,7 @@ public void setDynamic(String dynamic) { public boolean validate() { - if(getGraphId() == 0) + if(getGraphKey() == "0") return false; if(getGame() == null) return false; @@ -139,4 +116,13 @@ public TableRow toHeadLine() { return line; } + @Override + public String toString() { + return "GroupParameters{" + + ", graphKey='" + graphKey + '\'' + + ", game=" + game + + ", scaling=" + scaling + + ", dynamic=" + dynamic + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationAbstract.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationAbstract.java index dd31b9a8..8c7dc8e2 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationAbstract.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationAbstract.java @@ -32,62 +32,61 @@ @MappedSuperclass public abstract class SimulationAbstract implements TableInterface { + //ArangoDB + public static final String nameColumnName = "NAME"; + public static final String userIdColumnName = "USER"; + public static final String cooperativiatyColumnName = "COOPERATIVIATY"; + public static final String wealthColumnName = "WEALTH"; + public static final String cooperationEvaluationColumnName = "COOPERATION_EVALUATION"; + public static final String payoffEvaluationColumnName = "PAYOFF_EVALUATION"; + public static final String generationEvaluationColumnName = "GENERATION_EVALUATION"; + public static final String graphKeyName = "GRAPH_KEY"; + + ////////// Entity Fields ////////// + /** - * The id is used as persistence primary key + * System generated persistence key. */ - @Id - @GeneratedValue - private long Id; + private String key; /** * The name of the simulation */ - @Basic + @JsonProperty private String name; /** * The Id of the owning user */ - @Basic private String userId; /** * cooperativity the simulation */ - @Basic private double cooperativiaty; /** * Wealth the simulation */ - @Basic private double wealth; /** * Statistical evaluation of the cooperation values of the * SimulationDatasets */ - @Embedded private Evaluation cooperationEvaluation; + /** * Statistical evaluation of the payoff values of the SimulationDatasets */ - @AttributeOverrides({ - @AttributeOverride(name="average",column=@Column(name="payoffAverage")), - @AttributeOverride(name = "variance", column = @Column(name = "payoffvariance")), - @AttributeOverride(name = "deviation", column = @Column(name = "payoffdeviation")), - @AttributeOverride(name = "maximum", column = @Column(name = "payoffmaximum")), - @AttributeOverride(name = "minimum", column = @Column(name = "payoffminimum")), - }) - @Embedded private Evaluation payoffEvaluation; + /** * Statistical evaluation of the number of generations of the * SimulationDatasets */ - @Transient private Evaluation generationEvaluation; /* @@ -100,53 +99,45 @@ public abstract class SimulationAbstract implements TableInterface { /** * The network on which the simulation was performed. */ - @ManyToOne(cascade = CascadeType.ALL, targetEntity = CustomGraph.class, fetch=FetchType.LAZY) - @JoinColumns({ - @JoinColumn(name = "graphId", referencedColumnName = CustomGraph.idColumnName, insertable = false, updatable = false), - @JoinColumn(name = "username", referencedColumnName = CustomGraph.userColumnName, insertable = false, updatable = false) }) - private CustomGraph graph = new CustomGraph(); + private CustomGraph graph; ///// Getter ///// - /** - * Returns a unique id. - * - * @return the persistence id - */ - @JsonIgnore - public long getId() { - return this.Id; - } - /** * Returns the name or the id if no name is set. - * + * * @return the name */ - @Override - @JsonProperty public String getName() { if (name == null || name == "") - return String.valueOf(getId()); + return String.valueOf(getKey()); return name; } - @JsonIgnore + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + //@JsonIgnore public String getUserId() { return this.userId; } - @JsonProperty + //@JsonProperty public Evaluation getCooperationEvaluation() { return cooperationEvaluation; } - @JsonProperty + //@JsonProperty public Evaluation getPayoffEvaluation() { return payoffEvaluation; } - @JsonProperty + //@JsonProperty public Evaluation getGenerationEvaluation() { return generationEvaluation; } @@ -155,7 +146,6 @@ public Evaluation getGenerationEvaluation() { * @JsonProperty public Correlation getPayoffCorrelation() { return * payoffCorrelation; } */ - @JsonIgnore public CustomGraph getNetwork() { return this.graph; @@ -173,7 +163,29 @@ public double averagePayoffValue() { return getPayoffEvaluation().getAverage(); } - ///// Setter ///// + public double getCooperativiaty() { + return cooperativiaty; + } + + public void setCooperativiaty(double cooperativiaty) { + this.cooperativiaty = cooperativiaty; + } + + public double getWealth() { + return wealth; + } + + public void setWealth(double wealth) { + this.wealth = wealth; + } + + public String getGraphKey() { + if (this.graph != null) { + return this.graph.getKey(); + }else{ + return null; + } + } public void setName(String name) { this.name = name; @@ -183,36 +195,29 @@ public void setUserId(String userId) { this.userId = userId; } - @JsonSetter public void setNetwork(CustomGraph graph) { this.graph = graph; } - @JsonSetter public void setCooperationEvaluation(Evaluation cooperationEvaluation) { - //@MaxKissgen SimulationSeriesTest calls this function with null, I added a Handler for this case as the test will otherwise fail through a NullPointerException - if(cooperationEvaluation == null) - this.cooperationEvaluation = new Evaluation(); - else + if(cooperationEvaluation != null) { this.cooperationEvaluation = cooperationEvaluation; - - this.cooperativiaty = this.cooperationEvaluation.getAverage(); + this.cooperativiaty = this.cooperationEvaluation.getAverage(); + } } - @JsonSetter public void setPayoffEvaluation(Evaluation payoffEvaluation) { - //@MaxKissgen SimulationSeriesTest calls this function with null, I added a Handler for this case as the test will otherwise fail through a NullPointerException - if(payoffEvaluation == null) - this.payoffEvaluation = new Evaluation(); - else + + if(payoffEvaluation != null) { //TODO: this was == instead of !=, probably bug? but how come code worked? this.payoffEvaluation = payoffEvaluation; - - this.wealth = this.payoffEvaluation.getAverage(); + this.wealth = this.payoffEvaluation.getAverage(); + } } - @JsonSetter public void setGenerationEvaluation(Evaluation generationEvaluation) { - this.generationEvaluation = generationEvaluation; + if (generationEvaluation != null) { + this.generationEvaluation = generationEvaluation; + } } /* @@ -240,10 +245,8 @@ public TableRow toTableLine() { return null; } - @Override public Table toTable() { // TODO Auto-generated method stub return null; } - } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationDataset.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationDataset.java index 1932b659..bcf12258 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationDataset.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationDataset.java @@ -1,65 +1,53 @@ package i5.las2peer.services.ocd.cooperation.data.simulation; +import java.util.ArrayList; import java.util.List; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Transient; -import com.fasterxml.jackson.annotation.JsonIgnore; +import javax.persistence.Entity; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; import i5.las2peer.services.ocd.cooperation.data.table.Table; import i5.las2peer.services.ocd.cooperation.data.table.TableRow; import i5.las2peer.services.ocd.graphs.Community; /** * Simulation Data - * + * * Objects of this class represent the data collected by simulation series The * objects can be stored - * + * */ @Entity @JsonIgnoreProperties(ignoreUnknown = true) public class SimulationDataset extends SimulationAbstract { - /////////////// Entity Fields /////////////// - - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn + @JsonProperty private List agentData; - - /** - * A simulation is part of one simulation series - */ - @ManyToOne(cascade = CascadeType.ALL) - @JoinColumn(name="simulationSeries") - private SimulationSeries simulationSeries; - - @Basic + + @JsonProperty private double finalCooperationValue; - @Basic + @JsonProperty private double finalPayoffValue; - @Basic + @JsonProperty private double iterations; - @ElementCollection + @JsonProperty private List cooperationValues; - @ElementCollection + @JsonProperty private List payoffValues; - @Transient + @JsonProperty private boolean stable; /////////////// Constructor /////////////// @@ -93,72 +81,65 @@ public SimulationDataset(List cooperationValues, List payoffValu this.finalPayoffValue = payoffValues.get(payoffValues.size() - 1); } - /////////////// Getter /////////////// + /////////// Getters/Setters //////////// - @JsonProperty - public List getCooperationValues() { - return this.cooperationValues; - } - @JsonProperty - public List getPayoffValues() { - return this.payoffValues; + public List getAgentData() { + return agentData; } - @JsonIgnore - public List getAgentData() { - return this.agentData; + public void setAgentData(List agentData) { + this.agentData = agentData; } - @JsonProperty public double getFinalCooperationValue() { - return this.finalCooperationValue; + return finalCooperationValue; } - @JsonProperty - public double getIterations() { - return this.iterations; + public void setFinalCooperationValue(double finalCooperationValue) { + this.finalCooperationValue = finalCooperationValue; } - @JsonProperty public double getFinalPayoffValue() { - return this.finalPayoffValue; + return finalPayoffValue; } - @JsonIgnore - public boolean isStable() { - return stable; + public void setFinalPayoffValue(double finalPayoffValue) { + this.finalPayoffValue = finalPayoffValue; } - ////// Setter ///// + public double getIterations() { + return iterations; + } - public void setAgentData(List agentList) { - this.agentData = agentList; + public void setIterations(double iterations) { + this.iterations = iterations; + } + + public List getCooperationValues() { + return cooperationValues; } public void setCooperationValues(List cooperationValues) { this.cooperationValues = cooperationValues; } - public void setPayoffValues(List payoffValues) { - this.payoffValues = payoffValues; + public List getPayoffValues() { + return payoffValues; } - public void setStable(boolean stable) { - this.stable = stable; + public void setPayoffValues(List payoffValues) { + this.payoffValues = payoffValues; } - public void setFinalCooperationValue(double finalCooperationValue) { - this.finalCooperationValue = finalCooperationValue; + public boolean isStable() { + return stable; } - public void setFinalPayoffValue(double finalPayoffValue) { - this.finalPayoffValue = finalPayoffValue; + public void setStable(boolean stable) { + this.stable = stable; } - public void setIterations(int iterations) { - this.iterations = iterations; - } //////////// Methods //////////// @@ -223,14 +204,15 @@ public double getCommunityCooperationValue(List memberList) { } return cooperativitySum / memberCount; + } - @JsonIgnore + public boolean getAgentStrategy(int agentId) { return getAgentData().get(agentId).getFinalStrategy(); } - @JsonIgnore + public double getAgentCooperativity(int agentId) { return getAgentData().get(agentId).getCooperativity(); } @@ -287,4 +269,29 @@ public Table toTable() { return table; } + /** + * Helper method to convert object representation of a list + * returned in a query into an array list + * @param listToParse Object to parse as a list + * @return ArrayList representation of the input object + */ + public static ArrayList documentToArrayList(Object listToParse){ + ObjectMapper objectMapper = new ObjectMapper(); + ArrayList res; + res = objectMapper.convertValue(listToParse, ArrayList.class); + return res; + } + + @Override + public String toString() { + return "SimulationDataset{" + + ", finalCooperationValue=" + finalCooperationValue + + ", finalPayoffValue=" + finalPayoffValue + + ", iterations=" + iterations + + ", cooperationValues=" + cooperationValues + + ", payoffValues=" + payoffValues + + ", stable=" + stable + + '}'; + } + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationList.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationList.java index 3ead5c03..a8dfe61f 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationList.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationList.java @@ -66,8 +66,8 @@ public Table toTable() { for (SimulationSeriesGroup s : this) { int netId = getRow(s.getNetwork().getName()); int gId = -1; - if (s.getSimulationSeries().get(0).getParameters().getGame().equals(GameType.PRISONERS_DILEMMA)) { - switch (s.getSimulationSeries().get(0).getParameters().getDynamic()) { + if (s.getSeriesList().get(0).getSimulationSeriesParameters().getGame().equals(GameType.PRISONERS_DILEMMA)) { + switch (s.getSeriesList().get(0).getSimulationSeriesParameters().getDynamic()) { case REPLICATOR: gId = 0; break; @@ -85,8 +85,8 @@ public Table toTable() { break; } } - if (s.getSimulationSeries().get(0).getParameters().getGame().equals(GameType.PRISONERS_DILEMMA_COST)) { - switch (s.getSimulationSeries().get(0).getParameters().getDynamic()) { + if (s.getSeriesList().get(0).getSimulationSeriesParameters().getGame().equals(GameType.PRISONERS_DILEMMA_COST)) { + switch (s.getSeriesList().get(0).getSimulationSeriesParameters().getDynamic()) { case REPLICATOR: gId = 3; break; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeries.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeries.java index 5eef774e..5dc5ed54 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeries.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeries.java @@ -1,22 +1,23 @@ package i5.las2peer.services.ocd.cooperation.data.simulation; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.OneToMany; -import javax.persistence.Transient; +import javax.persistence.*; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.ObjectMapper; import i5.las2peer.services.ocd.cooperation.data.mapping.correlation.Correlation; import i5.las2peer.services.ocd.cooperation.data.table.Table; import i5.las2peer.services.ocd.cooperation.data.table.TableRow; @@ -25,7 +26,7 @@ /** * A SimulationSeries serves as a container for multiple SimulationDatasets. - * + * * If you repeat the same Simulation multiple times, you will get multiple * SimulationDatasets with the same parameters. This class is meant to group * them together and allow statistical evaluation of the data sets. @@ -35,51 +36,43 @@ @Entity public class SimulationSeries extends SimulationAbstract { + //ArangoDB + public static final String collectionName = "simulationseries"; + public static final String simulationSeriesParametersColumnName = "SIMULATION_SERIES_PARAMETERS"; + public static final String simulationDatasetsColumnName = "SIMULATION_DATASETS"; + public static final String simulationSeriesGroupKeysColumnName = "SIMULATION_SERIES_GROUP_KEYS"; + public static final String generationsColumnName = "GENERATIONS"; + /////////////// Entity Fields /////////////// - /** - * The id of the owner - */ - @Basic - private String userId; /** * The simulation parameters used for this simulation series */ - @Embedded - private SimulationSeriesParameters parameters; + private SimulationSeriesParameters simulationSeriesParameters; + /** * Statistical evaluation of the number of generations of the * SimulationDatasets */ - @Transient private Evaluation generationEvaluation; /** * Correlation between the cooperation value and the average payoff of the * SimulationDatasets */ - @Transient private Correlation payoffCorrelation; /** * A simulations series consists of multiple simulation datasets */ - @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) - @JoinColumn private List simulationDatasets; - /** - * A simulation series can be part of multiple groups - */ - @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - private List simulationGroups; /** * Highest number of iterations of a dataset */ - @Basic private int generations; ///////////////// Constructor ////////////////// @@ -94,46 +87,38 @@ public SimulationSeries() { /** * Creates a instance with datasets, parameters and graph. - * - * @param parameters the parameters + * + * @param simulationSeriesParameters the parameters * @param datasets the datasets * @param graph the graph */ - public SimulationSeries(SimulationSeriesParameters parameters, List datasets, CustomGraph graph) { - this.setParameters(parameters); + public SimulationSeries(SimulationSeriesParameters simulationSeriesParameters, List datasets, CustomGraph graph) { + this.setSimulationSeriesParameters(simulationSeriesParameters); this.setSimulationDatasets(datasets); this.setNetwork(graph); } - + /** * Creates a instance with datasets and parameters * - * @param parameters the parameters + * @param simulationSeriesParameters the parameters * @param datasets the datasets */ - public SimulationSeries(SimulationSeriesParameters parameters, List datasets) { - this.setParameters(parameters); + public SimulationSeries(SimulationSeriesParameters simulationSeriesParameters, List datasets) { + this.setSimulationSeriesParameters(simulationSeriesParameters); this.setSimulationDatasets(datasets); } - ////////////////// Getter ///////////////////// - - @Override - @JsonIgnore - public String getUserId() { - return userId; - } - @JsonIgnore public long getGenerations() { return generations; } @JsonProperty - public SimulationSeriesParameters getParameters() { - return parameters; + public SimulationSeriesParameters getSimulationSeriesParameters() { + return simulationSeriesParameters; } @Override @@ -149,50 +134,47 @@ public List getSimulationDatasets() { @JsonIgnore public SimulationSeriesMetaData getMetaData() { - SimulationSeriesMetaData meta = new SimulationSeriesMetaData(this); + SimulationSeriesMetaData meta = new SimulationSeriesMetaData(this); return meta; } - @JsonIgnore - public List getSimulationSeriesGroups() { - return this.simulationGroups; - } - - ////////////////// Setter ///////////////////// - @Override - @JsonSetter - public void setUserId(String userId) { - this.userId = userId; - } - @JsonSetter public void setGenerations(int generations) { this.generations = generations; } - @JsonSetter - public void setParameters(SimulationSeriesParameters parameters) { - this.parameters = parameters; + + public void setSimulationSeriesParameters(SimulationSeriesParameters simulationSeriesParameters) { + this.simulationSeriesParameters = simulationSeriesParameters; } @Override - @JsonSetter public void setGenerationEvaluation(Evaluation generationEvaluation) { this.generationEvaluation = generationEvaluation; } - @JsonSetter public void setSimulationDatasets(List simulationDatasets) { this.simulationDatasets = simulationDatasets; } + + public Correlation getPayoffCorrelation() { + return payoffCorrelation; + } + + public void setPayoffCorrelation(Correlation payoffCorrelation) { + this.payoffCorrelation = payoffCorrelation; + } + + + /////////////////// Methods /////////////////////// /** * Create {@link Evaluation} objects with the values given by * {@link #getFinalCooperationValues()} and {@link #getFinalPayoffValues()}. - * + * */ @Override public void evaluate() { @@ -263,7 +245,7 @@ public double averagePayoffValue() { /** * Return the average community cooperation values of all SimulationDatasets * * - * + * * @param communityList * the list of communities * @return the values @@ -286,7 +268,7 @@ public double[] getAverageCommunityCooperationValues(List communityLi /** * Returns the average community cooperation value of the SimulationDatasets * * - * + * * @param community * the Community * @return average cooperation value @@ -396,7 +378,7 @@ public Table toTable() { @Override public TableRow toTableLine() { - SimulationSeriesParameters parameters = getParameters(); + SimulationSeriesParameters parameters = getSimulationSeriesParameters(); Evaluation coopEvaluation = getCooperationEvaluation(); Evaluation payoffEvaluation = getPayoffEvaluation(); // valuation generationEvaluation = getGenerationEvaluation(); @@ -411,7 +393,7 @@ public TableRow toTableLine() { public TableRow toHeadLine() { - SimulationSeriesParameters parameters = getParameters(); + SimulationSeriesParameters parameters = getSimulationSeriesParameters(); Evaluation coopEvaluation = getCooperationEvaluation(); Evaluation payoffEvaluation = getPayoffEvaluation(); // Evaluation generationEvaluation = getGenerationEvaluation(); @@ -426,4 +408,120 @@ public TableRow toHeadLine() { } + /** + * Update column values to be stored in the database. + * @param bd Document holding updated values. + * @return Document with updated values. + */ + public BaseDocument updateDocument(BaseDocument bd){ + bd.addAttribute(userIdColumnName, this.getUserId()); + bd.addAttribute(simulationSeriesParametersColumnName, this.getSimulationSeriesParameters()); + bd.addAttribute(generationsColumnName, this.getGenerations()); + bd.addAttribute(simulationDatasetsColumnName, this.getSimulationDatasets()); + // fields from superclass + bd.addAttribute(nameColumnName, this.getName()); + bd.addAttribute(cooperativiatyColumnName, this.getCooperativiaty()); + bd.addAttribute(wealthColumnName, this.getWealth()); + bd.addAttribute(cooperationEvaluationColumnName, this.getCooperationEvaluation()); + bd.addAttribute(payoffEvaluationColumnName, this.getPayoffEvaluation()); + bd.addAttribute(generationEvaluationColumnName, this.getGenerationEvaluation()); + if(this.getNetwork() != null) { + bd.addAttribute(graphKeyName, this.getNetwork().getKey()); + } + + + return bd; + } + + // Persistence Methods + public void persist(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + collection.insertDocument(bd, createOptions); + this.setKey(bd.getKey()); // if key is assigned before inserting (line above) the value is null + } + + public void persist(ArangoDatabase db, String transId, String userId) { + ArangoCollection collection = db.collection(collectionName); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + bd.addAttribute(userIdColumnName, userId); + collection.insertDocument(bd, createOptions); + this.setKey(bd.getKey()); // if key is assigned before inserting (line above) the value is null + } + + + public void updateDB(ArangoDatabase db, String transId) { + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + collection.updateDocument(this.getKey(), bd, updateOptions); + } + + /** + * Helper method to convert object representation of a list + * returned in a query into a list of datasets + * @param simulationDatasetListObject Object representing SimulationDataset list + * @return ArrayList representation of the input object + */ + public static List objectToSimulationDatasetList(Object simulationDatasetListObject){ + if (simulationDatasetListObject == null){ + return new ArrayList(); // TODO: should this return null or empty list? + } + ObjectMapper objectMapper = new ObjectMapper(); + SimulationDataset[] simulationDatasetsArray = objectMapper.convertValue(simulationDatasetListObject, SimulationDataset[].class); + List simulationDatasetsList = Arrays.asList(simulationDatasetsArray); + + return simulationDatasetsList; + } + + public static SimulationSeries load(String key, ArangoDatabase db, String transId) { + ObjectMapper objectMapper = new ObjectMapper(); + SimulationSeries simulationSeries = new SimulationSeries(); + ArangoCollection collection = db.collection(collectionName); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + BaseDocument bd = collection.getDocument(key, BaseDocument.class, readOpt); + if (bd != null) { + simulationSeries.setKey(bd.getKey()); + simulationSeries.setUserId((String) bd.getAttribute(userIdColumnName)); + simulationSeries.setSimulationSeriesParameters(objectMapper.convertValue(bd.getAttribute(simulationSeriesParametersColumnName), SimulationSeriesParameters.class)); + simulationSeries.setGenerations((int) bd.getAttribute(generationsColumnName)); + simulationSeries.setSimulationDatasets(objectToSimulationDatasetList(bd.getAttribute(simulationDatasetsColumnName))); + // fields from superclass + simulationSeries.setName((String) bd.getAttribute(nameColumnName)); + simulationSeries.setCooperativiaty((double) bd.getAttribute(cooperativiatyColumnName)); + simulationSeries.setWealth((double) bd.getAttribute(wealthColumnName)); + simulationSeries.setCooperationEvaluation(objectMapper.convertValue(bd.getAttribute(cooperationEvaluationColumnName), Evaluation.class)); + simulationSeries.setPayoffEvaluation(objectMapper.convertValue(bd.getAttribute(payoffEvaluationColumnName), Evaluation.class)); + simulationSeries.setGenerationEvaluation(objectMapper.convertValue(bd.getAttribute(generationEvaluationColumnName), Evaluation.class)); + + if(bd.getAttribute(graphKeyName) != null) { + simulationSeries.setNetwork(CustomGraph.load((String) bd.getAttribute(graphKeyName), db, transId)); + } + + } + else { + System.out.println("SimulationSeries with key " + key + " not found."); + } + return simulationSeries; + } + + @Override + public String toString() { + return "SimulationSeries{" + + "key='" + this.getKey() + '\'' + + ", cooperationEvaluation='" + getCooperationEvaluation() + '\'' + + ", simulationSeriesParameters=" + simulationSeriesParameters + + ", generationEvaluation=" + generationEvaluation + + ", payoffCorrelation=" + payoffCorrelation + + ", simulationDatasets=" + simulationDatasets + + ", generations=" + generations + + '}'; + } + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroup.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroup.java index f66dbcf7..466a7117 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroup.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroup.java @@ -3,15 +3,18 @@ import java.util.ArrayList; import java.util.List; -import javax.persistence.CascadeType; import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ManyToMany; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; import i5.las2peer.services.ocd.cooperation.data.table.Table; import i5.las2peer.services.ocd.cooperation.data.table.TableRow; import i5.las2peer.services.ocd.graphs.Community; @@ -28,13 +31,28 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class SimulationSeriesGroup extends SimulationAbstract { + //ArangoDB + public static final String collectionName = "simulationseriesgroup"; + public static final String simulationSeriesKeysColumnName = "SIMULATION_SERIES_KEYS"; + private static final String groupParametersColumnName = "GROUP_PARAMETERS"; + private static final String groupMetaDataColumnName = "GROUP_METADATA"; + ////////// Entity Fields ////////// - @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE) + @JsonIgnore private List seriesList; + @JsonProperty + private List simulationSeriesKeys; + + @JsonProperty + private GroupParameters groupParameters; + + @JsonProperty + private SimulationSeriesGroupMetaData groupMetaData; + ////////// Constructor ////////// - + /** * Creates a empty instance, that is used for persistence and testing purposes. */ @@ -44,12 +62,25 @@ public SimulationSeriesGroup() { public SimulationSeriesGroup(List list) { this.seriesList = list; + if (this.simulationSeriesKeys == null){ + this.simulationSeriesKeys = new ArrayList(); + } + for (SimulationSeries simulationSeries : list){ + this.simulationSeriesKeys.add(simulationSeries.getKey()); + } + // calculate and set the groupMetaData which is used for WebClient requests + SimulationSeriesGroupMetaData groupMetaData = this.calculateMetaData(); + this.setGroupMetaData(groupMetaData); } - ////////// Getter ////////// - @JsonProperty - public List getSimulationSeries() { + + public void setSeriesList(List seriesList) { + this.seriesList = seriesList; + } + + @JsonIgnore + public List getSeriesList() { return this.seriesList; } @@ -57,52 +88,80 @@ public List getSimulationSeries() { * @return the network ids used in the simulation series */ @JsonIgnore - public List getNetworkIds() { + public List getNetworkKeys() { - List networkIds = new ArrayList(); + List networkIds = new ArrayList(); for (SimulationSeries series : seriesList) { - networkIds.add(series.getParameters().getGraphId()); + networkIds.add(series.getSimulationSeriesParameters().getGraphKey()); } return networkIds; } @Override public CustomGraph getNetwork() { - return this.getSimulationSeries().get(0).getNetwork(); + if(this.getSeriesList() != null && this.getSeriesList().size() > 0) { + return this.getSeriesList().get(0).getNetwork(); + } + return null; } /** * Creates the metaData object of this SimulationSeriesGroup. The metaData * object is used to be sent to the web client. - * + * * @return MetaData */ @JsonIgnore - public SimulationSeriesGroupMetaData getMetaData() { - if(this.getCooperationEvaluation() == null) + public SimulationSeriesGroupMetaData calculateMetaData() { + if(this.getCooperationEvaluation() == null) { this.evaluate(); + } SimulationSeriesGroupMetaData metaData = new SimulationSeriesGroupMetaData(this); + this.setGroupMetaData(metaData); return metaData; } + public void setGroupMetaData(SimulationSeriesGroupMetaData groupMetaData) { + this.groupMetaData = groupMetaData; + } + + public SimulationSeriesGroupMetaData getGroupMetaData() { + return groupMetaData; + } + /** - * + * * @return SimulationSeries MetaData */ @JsonProperty public List getSeriesMetaData() { List list = new ArrayList<>(this.size()); - for (SimulationSeries sim : this.getSimulationSeries()) { + for (SimulationSeries sim : this.getSeriesList()) { list.add(sim.getMetaData()); } return list; } - /////////// Setter //////////// + public GroupParameters getGroupParameters() { + return groupParameters; + } + + public void setGroupParameters(GroupParameters groupParameters) { + this.groupParameters = groupParameters; + } + + public List getSimulationSeriesKeys() { + return simulationSeriesKeys; + } + + public void setSimulationSeriesKeys(List simulationSeriesKeys) { + this.simulationSeriesKeys = simulationSeriesKeys; + } + /** * Adds a SimulationSeries to this group - * + * * @param series * SimulationSeries */ @@ -118,11 +177,11 @@ public void setSimulationSeries(List seriesList) { @Override public void evaluate() { - + setCooperationEvaluation(new Evaluation(getAverageFinalCooperationValues())); setPayoffEvaluation(new Evaluation(getAverageFinalPayoffValues())); //setGenerationEvaluation(new Evaluation(getAverageIterations())); - + } /** @@ -140,12 +199,12 @@ public int generations() { } return maxSize; } - + //////////// Communities ///////////// /** * Return the average community cooperation values of all SimulationSeries - * + * * @param communityList * the list of communities * @return the values @@ -167,7 +226,7 @@ public double[] getAverageCommunityCooperationValues(List communityLi /** * Returns the average community cooperation value of all SimulationSeries - * + * * @param community * the Community * @return average cooperation value @@ -183,7 +242,7 @@ public double getAverageCommunityCooperationValue(Community community) { double total = 0.0; for (int datasetId = 0; datasetId < datasetCount; datasetId++) { - total += getSimulationSeries().get(datasetId).getAverageCommunityCooperationValue(community); + total += getSeriesList().get(datasetId).getAverageCommunityCooperationValue(community); } return total / datasetCount; @@ -193,7 +252,6 @@ public double getAverageCommunityCooperationValue(Community community) { @JsonIgnore public double[] getAverageFinalCooperationValues() { - int size = seriesList.size(); double[] values = new double[size]; for (int i = 0; i < size; i++) { @@ -212,9 +270,9 @@ public double[] getAverageFinalPayoffValues() { } return values; } - + ///// average - + @JsonIgnore public double[] getAverageIterations() { @@ -225,21 +283,21 @@ public double[] getAverageIterations() { } return values; } - - + + public boolean equals(double d, double e) { if((d - e) < 0.0001) { return true; } return false; } - + ////////// Print ////////// @Override public Table toTable() { - List simulations = getSimulationSeries(); + List simulations = getSeriesList(); Table table = new Table(); // headline @@ -274,6 +332,110 @@ public TableRow toTableLine() { //line.add(generationEvaluation.toTableLine()); return line; } - + + + + /** + * Update column values to be stored in the database. + * @param bd Document holding updated values. + * @return Document with updated values. + */ + public BaseDocument updateDocument(BaseDocument bd){ + bd.addAttribute(userIdColumnName, this.getUserId()); + ArrayList simulationSeriesKeys = new ArrayList(); + for (SimulationSeries simulationSeries : this.getSeriesList()){ + simulationSeriesKeys.add(simulationSeries.getKey()); + } + bd.addAttribute(simulationSeriesKeysColumnName, simulationSeriesKeys); + bd.addAttribute(groupParametersColumnName, this.getGroupParameters()); + bd.addAttribute(groupMetaDataColumnName, this.getGroupMetaData()); //TODO:DELETE + // fields from superclass + bd.addAttribute(super.nameColumnName, super.getName()); + bd.addAttribute(super.cooperativiatyColumnName, super.getCooperativiaty()); +// bd.addAttribute(super.wealthColumnName, super.getWealth()); + bd.addAttribute(super.cooperationEvaluationColumnName, new Evaluation(getAverageFinalCooperationValues())); + bd.addAttribute(super.payoffEvaluationColumnName, new Evaluation(getAverageFinalPayoffValues())); + + // extra attribute for the WebClient + if(this.getSimulationSeriesKeys() != null) { + bd.addAttribute("size", this.getSimulationSeriesKeys().size()); + } + + return bd; + } + + + // Persistence Methods + public void persist(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + collection.insertDocument(bd, createOptions); + this.setKey(bd.getKey()); // if key is assigned before inserting (line above) the value is null + } + + public void persist(ArangoDatabase db, String transId, String userId) { + ArangoCollection collection = db.collection(collectionName); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + bd.addAttribute(userIdColumnName, userId); + collection.insertDocument(bd, createOptions); + this.setKey(bd.getKey()); // if key is assigned before inserting (line above) the value is null + } + + public void updateDB(ArangoDatabase db, String transId) { + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + updateDocument(bd); + collection.updateDocument(this.getKey(), bd, updateOptions); + } + + /** + * Helper method to convert object representation of a list + * returned in a query into an array list + * @param listToParse Object to parse as a list + * @return ArrayList representation of the input object + */ + public static ArrayList documentToArrayList(Object listToParse){ + ObjectMapper objectMapper = new ObjectMapper(); + ArrayList res; + res = objectMapper.convertValue(listToParse, ArrayList.class); + return res; + } + + public static SimulationSeriesGroup load(String key, ArangoDatabase db, String transId) { + ObjectMapper objectMapper = new ObjectMapper(); + SimulationSeriesGroup simulationSeriesGroup = new SimulationSeriesGroup(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class); + if (bd != null) { + simulationSeriesGroup.setKey(bd.getKey()); + simulationSeriesGroup.setSimulationSeriesKeys(objectMapper.convertValue(bd.getAttribute(simulationSeriesKeysColumnName), ArrayList.class)); + simulationSeriesGroup.setGroupParameters(objectMapper.convertValue(bd.getAttribute(groupParametersColumnName), GroupParameters.class)); + + // fields from superclass + simulationSeriesGroup.setName((String) bd.getAttribute(nameColumnName)); + simulationSeriesGroup.setCooperativiaty((double) bd.getAttribute(cooperativiatyColumnName)); +// simulationSeriesGroup.setWealth((double) bd.getAttribute(wealthColumnName)); + simulationSeriesGroup.setCooperationEvaluation(objectMapper.convertValue(bd.getAttribute(cooperationEvaluationColumnName), Evaluation.class)); + simulationSeriesGroup.setPayoffEvaluation(objectMapper.convertValue(bd.getAttribute(payoffEvaluationColumnName), Evaluation.class)); +// simulationSeriesGroup.setGenerationEvaluation(objectMapper.convertValue(bd.getAttribute(generationEvaluationColumnName), Evaluation.class)); + + + // set metadata related to the simulation series group + simulationSeriesGroup.setGroupMetaData(objectMapper.convertValue(bd.getAttribute(groupMetaDataColumnName), SimulationSeriesGroupMetaData.class)); + } + else { + System.out.println("SimulationSeriesGroup with key " + key + " not found."); + } + return simulationSeriesGroup; + } + + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroupMetaData.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroupMetaData.java index baa91fdc..b2c2dedd 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroupMetaData.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesGroupMetaData.java @@ -1,11 +1,9 @@ package i5.las2peer.services.ocd.cooperation.data.simulation; -import java.io.Serializable; - +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; -import i5.las2peer.services.ocd.graphs.CustomGraph; +import java.io.Serializable; /** * Objects of this class contain the meta data of simulation series group. They are @@ -16,9 +14,17 @@ public class SimulationSeriesGroupMetaData implements Serializable { private static final long serialVersionUID = 1L; - private long id; + + @JsonProperty + private String key; + + @JsonProperty private String name; + + @JsonProperty private int size; + + @JsonProperty private Evaluation evaluation; public SimulationSeriesGroupMetaData() { @@ -27,32 +33,37 @@ public SimulationSeriesGroupMetaData() { public SimulationSeriesGroupMetaData(SimulationSeriesGroup simulation) { - this.id = simulation.getId(); + this.key = simulation.getKey(); this.name = simulation.getName(); this.size = simulation.size(); this.evaluation = simulation.getCooperationEvaluation(); } - public long getId() { - return id; + @JsonProperty + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; } + @JsonProperty public String getName() { return name; } + @JsonProperty public int getSize() { return size; } + @JsonProperty public Evaluation getEvaluation() { return evaluation; } - public void setId(long id) { - this.id = id; - } public void setName(String name) { this.name = name; @@ -66,4 +77,13 @@ public void setEvaluation(Evaluation evaluation) { this.evaluation = evaluation; } + @Override + public String toString() { + return "SimulationSeriesGroupMetaData{" + + "key='" + key + '\'' + + ", name='" + name + '\'' + + ", size=" + size + + ", evaluation=" + evaluation + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesMetaData.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesMetaData.java index 5ec1677c..51b9a96e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesMetaData.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesMetaData.java @@ -14,10 +14,10 @@ public class SimulationSeriesMetaData implements Serializable { private static final long serialVersionUID = 1L; - private long id; + private String id; private String name; private String graphName; - private long graphId; + private String graphId; private SimulationSeriesParameters parameters; private Evaluation evaluation; @@ -27,19 +27,19 @@ public SimulationSeriesMetaData() { public SimulationSeriesMetaData(SimulationSeries series) { - this.id = series.getId(); + this.id = series.getKey(); this.name = series.getName(); - this.parameters = series.getParameters(); + this.parameters = series.getSimulationSeriesParameters(); this.evaluation = series.getCooperationEvaluation(); - this.graphId = series.getParameters().getGraphId(); - this.graphName = series.getParameters().getGraphName(); + this.graphId = series.getSimulationSeriesParameters().getGraphKey(); + this.graphName = series.getSimulationSeriesParameters().getGraphName(); } ////// Getter ////// @JsonProperty - public long getId() { + public String getId() { return id; } @@ -59,7 +59,7 @@ public Evaluation getEvaluation() { } @JsonProperty - public long getGraphId() { + public String getGraphId() { return graphId; } @@ -71,7 +71,7 @@ public String getGraphName() { ////// Setter ////// @JsonSetter - public void setId(long id) { + public void setId(String id) { this.id = id; } @@ -91,7 +91,7 @@ public void setEvaluation(Evaluation evaluation) { } @JsonSetter - public void setGraphId(long graphId) { + public void setGraphId(String graphId) { this.graphId = graphId; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesParameters.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesParameters.java index 0d37d1bb..c1cfeb82 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesParameters.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesParameters.java @@ -1,18 +1,18 @@ package i5.las2peer.services.ocd.cooperation.data.simulation; +import java.beans.ConstructorProperties; import java.io.Serializable; -import javax.persistence.Basic; -import javax.persistence.Column; import javax.persistence.Embeddable; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Transient; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonSetter; import i5.las2peer.services.ocd.cooperation.data.table.TableRow; import i5.las2peer.services.ocd.cooperation.simulation.Simulation; @@ -31,85 +31,84 @@ public class SimulationSeriesParameters implements Serializable { private static final long serialVersionUID = 1L; - ////////// Entity Fields ////////// + @JsonProperty + private String graphKey; - @Column(name = "graphId") - private long graphId; - - @Enumerated(EnumType.STRING) + @JsonProperty private GameType game; - @Basic + + @JsonProperty private double payoffCC; - @Basic + @JsonProperty private double payoffCD; - @Basic + @JsonProperty private double payoffDD; - @Basic + + @JsonProperty private double payoffDC; /** * the payoff cost value. Used only with a cost variant game. */ - @Transient private double cost; /** * the payoff benefit value. Used only with a cost variant game. */ - @Transient private double benefit; - @Enumerated(EnumType.STRING) + @JsonProperty private DynamicType dynamic; - @Basic + @JsonProperty private double dynamicValue; /** * the break condition for the simulaiton */ - @Enumerated(EnumType.STRING) + @JsonProperty private ConditionType condition; + /** * the maximum rounds of a Simulation */ - @Basic + @JsonProperty private int maxIterations; /** * the minimum rounds of a Simulation */ - @Basic + @JsonProperty private int minIterations; /** * time window for the break condition */ - @Basic + @JsonProperty private int timeWindow; /** * time window for the break condition */ - @Basic + @JsonProperty private int threshold; /** * how often a {@link Simulation} is executed resulting in multiple * {@link SimulationDataset}s as part of one {@link SimulationSeries} */ - @Basic + @JsonProperty private int iterations; - @Basic + @JsonProperty private String simulationName; - @Basic + @JsonProperty private String graphName; ////////// Constructor ////////// @@ -118,44 +117,47 @@ public SimulationSeriesParameters() { } - public SimulationSeriesParameters(SimulationSeries series, long graphId, GameType game, double payoffCC, double payoffCD, - double payoffDD, double payoffDC, DynamicType dynamic, double dynamicValue, int iterations) { - this.setGraphId(graphId); + @ConstructorProperties({"name", "iterations","payoffDC","payoffCC","payoffDD","payoffCD", + "dynamic","dynamicValue","condition","maxIterations","graphId"}) + public SimulationSeriesParameters( String simulationName, int iterations, double payoffDC, double payoffCC, double payoffDD, + double payoffCD, String dynamic, double dynamicValue, String condition, + int maxIterations, String graphKey) { + this.graphKey = graphKey; this.payoffCC = payoffCC; this.payoffCD = payoffCD; - this.payoffDC = payoffDC; this.payoffDD = payoffDD; + this.payoffDC = payoffDC; this.setDynamic(dynamic); - this.setDynamicValue(dynamicValue); - this.setIterations(iterations); + this.dynamicValue = dynamicValue; + this.setCondition(condition); + this.maxIterations = maxIterations; + this.iterations = iterations; + this.simulationName = simulationName; } + ////////// Getter ////////// - @JsonProperty - public String getName() { - return this.simulationName; - } - @JsonProperty - public long getGraphId() { - return graphId; + + public String getGraphKey() { + return graphKey; } - @JsonProperty + public DynamicType getDynamic() { if(dynamic == null) return DynamicType.UNKNOWN; return dynamic; } - @JsonProperty + public int getIterations() { return iterations; } - @JsonProperty + public GameType getGame() { if (game == null) { this.game = GameType.getGameType(payoffCC, payoffCD, payoffDC, payoffDD); @@ -163,37 +165,31 @@ public GameType getGame() { return this.game; } - @JsonProperty + public double getPayoffCC() { return payoffCC; } - @JsonProperty public double getPayoffCD() { return payoffCD; } - @JsonProperty public double getPayoffDD() { return payoffDD; } - @JsonProperty public double getPayoffDC() { return payoffDC; } - @JsonProperty public double getCost() { return cost; } - @JsonProperty public double getBenefit() { return benefit; } - @JsonProperty public ConditionType getCondition() { if (condition == null) return ConditionType.UNKNOWN; @@ -231,81 +227,75 @@ public int[] getConditionValues() { ////////// Setter ////////// - @JsonSetter - public void setName(String name) { - this.simulationName = name; - } - @JsonSetter public void setIterations(int iterations) { this.iterations = iterations; } - @JsonSetter - public void setGraphId(long graphId) { - this.graphId = graphId; + public void setGraphKey(String graphKey) { + this.graphKey = graphKey; } - @JsonSetter public void setDynamic(String dynamic) { this.dynamic = DynamicType.fromString(dynamic); } - @JsonSetter public void setGame(String game) { this.game = GameType.fromString(game); } - @JsonIgnore public void setDynamic(DynamicType dynamic) { this.dynamic = dynamic; } - @JsonSetter public void setCondition(String condition) { this.condition = ConditionType.fromString(condition); } - @JsonIgnore public void setGame(GameType game) { this.game = game; } - @JsonSetter public void setDynamicValue(double dynamicValue) { this.dynamicValue = dynamicValue; } - @JsonSetter public void setPayoffCC(double payoffCC) { this.payoffCC = payoffCC; } - @JsonSetter public void setPayoffCD(double payoffCD) { this.payoffCD = payoffCD; } - @JsonSetter public void setPayoffDD(double payoffDD) { this.payoffDD = payoffDD; } - @JsonSetter public void setPayoffDC(double payoffDC) { this.payoffDC = payoffDC; } - @JsonSetter public void setBenefit(double benefit) { this.benefit = benefit; } - @JsonSetter public void setCost(double cost) { this.cost = cost; } + public void setCondition(ConditionType condition) { + this.condition = condition; + } + + public String getSimulationName() { + return simulationName; + } + + public void setSimulationName(String simulationName) { + this.simulationName = simulationName; + } + ///////////// Methods ///////////// /** @@ -395,4 +385,27 @@ public void setGraphName(String string) { this.graphName = string; } + @Override + public String toString() { + return "SimulationSeriesParameters{" + + "graphKey='" + graphKey + '\'' + + ", game=" + game + + ", payoffCC=" + payoffCC + + ", payoffCD=" + payoffCD + + ", payoffDD=" + payoffDD + + ", payoffDC=" + payoffDC + + ", cost=" + cost + + ", benefit=" + benefit + + ", dynamic=" + dynamic + + ", dynamicValue=" + dynamicValue + + ", condition=" + condition + + ", maxIterations=" + maxIterations + + ", minIterations=" + minIterations + + ", timeWindow=" + timeWindow + + ", threshold=" + threshold + + ", iterations=" + iterations + + ", simulationName='" + simulationName + '\'' + + ", graphName='" + graphName + '\'' + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilder.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilder.java index 18775ba1..2b8aaac8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilder.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilder.java @@ -2,8 +2,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; -import i5.las2peer.api.execution.ServiceInvocationException; import i5.las2peer.services.ocd.cooperation.data.simulation.AgentData; import i5.las2peer.services.ocd.cooperation.data.simulation.GroupType; import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationDataset; @@ -23,8 +23,8 @@ import i5.las2peer.services.ocd.graphs.GraphType; import sim.field.network.Network; import sim.util.Bag; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * Provides the interface to start simulations from the service. @@ -68,7 +68,7 @@ public void setParameters(SimulationSeriesParameters parameters) { setDynamicParameters(parameters); setConditionParameters(parameters); setIterations(parameters.getIterations()); - setName(parameters.getName()); + setName(parameters.getSimulationName()); } catch (Exception e) { e.printStackTrace(); @@ -201,9 +201,8 @@ protected void validate() throws IllegalStateException { * * @return SimulationSeries * @throws IllegalStateException if validation failed - * @throws ServiceInvocationException if service invocation failed */ - public SimulationSeries simulate() throws IllegalStateException, ServiceInvocationException { + public SimulationSeries simulate() throws IllegalStateException { try { validate(); @@ -233,9 +232,9 @@ public SimulationSeries simulate() throws IllegalStateException, ServiceInvocati List datasets = new ArrayList<>(); Simulation simulation = new Simulation(System.currentTimeMillis(), network, game, dynamic, condition); - System.out.println("simulate"); - System.out.println(simulation.getBreakCondition().getMaxIterations()); - System.out.println(simulation.getBreakCondition().toString()); +// System.out.println("simulate"); +// System.out.println(simulation.getBreakCondition().getMaxIterations()); +// System.out.println(simulation.getBreakCondition().toString()); for (int i = 0; i < iterations; i++) { simulation.start(); @@ -257,7 +256,7 @@ public SimulationSeries simulate() throws IllegalStateException, ServiceInvocati parameters.setPayoffCD(game.getPayoffAB()); parameters.setPayoffDC(game.getPayoffBA()); parameters.setPayoffDD(game.getPayoffBB()); - parameters.setGraphId(graph.getId()); + parameters.setGraphKey(graph.getKey()); parameters.setIterations(iterations); parameters.setGraphName(graph.getName()); parameters.setMaxIterations(condition.getMaxIterations()); @@ -265,6 +264,7 @@ public SimulationSeries simulate() throws IllegalStateException, ServiceInvocati SimulationSeries series = new SimulationSeries(parameters, datasets); series.setName(name); + series.setNetwork(graph); // graph on which the simulation is based series.evaluate(); return (series); } @@ -343,15 +343,15 @@ protected Network buildNetwork(CustomGraph graph) { Network network = new Network(false); List agents = new ArrayList<>(); - for (Node node : graph.getNodeArray()) { - Agent agent = new Agent(node.index()); - agents.add(node.index(), agent); + for (Node node : graph.nodes().toArray(Node[]::new)) { + Agent agent = new Agent(node.getIndex()); + agents.add(node.getIndex(), agent); network.addNode(agent); } - for (Edge edge : graph.getEdgeArray()) { - int source = edge.source().index(); - int target = edge.target().index(); + for (Edge edge : graph.edges().toArray(Edge[]::new)) { + int source = edge.getSourceNode().getIndex(); + int target = edge.getTargetNode().getIndex(); if (network.getEdge(agents.get(source), agents.get(target)) == null) network.addEdge(agents.get(source), agents.get(target), true); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/dynamic/DynamicType.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/dynamic/DynamicType.java index a163cf4c..a1a2b316 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/dynamic/DynamicType.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/dynamic/DynamicType.java @@ -1,5 +1,7 @@ package i5.las2peer.services.ocd.cooperation.simulation.dynamic; +import i5.las2peer.services.ocd.cooperation.simulation.termination.ConditionType; + import java.security.InvalidParameterException; @@ -135,6 +137,20 @@ public static DynamicType getType(Class dynamicClass) { throw new InvalidParameterException(); } + /** + * Returns the type corresponding to an id. + * @param id The id. + * @return The corresponding type. + */ + public static DynamicType lookupType(int id) { + for (DynamicType type : DynamicType.values()) { + if (id == type.getId()) { + return type; + } + } + throw new InvalidParameterException(); + } + public static DynamicType[] getValues() { return DynamicType.values(); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/termination/ConditionType.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/termination/ConditionType.java index 9825035f..f983fe4d 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/termination/ConditionType.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/cooperation/simulation/termination/ConditionType.java @@ -1,5 +1,7 @@ package i5.las2peer.services.ocd.cooperation.simulation.termination; +import i5.las2peer.services.ocd.metrics.OcdMetricType; + import java.security.InvalidParameterException; @@ -106,6 +108,20 @@ public static ConditionType getType(Class enumClass) { throw new InvalidParameterException(); } + /** + * Returns the type corresponding to an id. + * @param id The id. + * @return The corresponding type. + */ + public static ConditionType lookupType(int id) { + for (ConditionType type : ConditionType.values()) { + if (id == type.getId()) { + return type; + } + } + throw new InvalidParameterException(); + } + public static ConditionType[] getValues() { return ConditionType.values(); } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Community.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Community.java index 73cc37b1..a15ce15e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Community.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Community.java @@ -21,8 +21,18 @@ import javax.persistence.MapKeyJoinColumns; import javax.persistence.PreRemove; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + + import i5.las2peer.services.ocd.graphs.properties.GraphProperty; -import y.base.Node; +import org.graphstream.graph.Node; /** * Represents a community of a cover. @@ -47,7 +57,10 @@ public class Community { private static final String membershipMapGraphIdKeyColumnName = "GRAPH_ID"; private static final String membershipMapGraphUserKeyColumnName = "USER_NAME"; private static final String membershipMapNodeIdKeyColumnName = "CUSTOM_NODE_ID"; - + + public static final String collectionName = "community"; + private static final String coverKeyColumnName = "COVER_KEY"; + private static final String membershipKeyMapColumnName = "MEMBERSHIP_KEYS"; /** * System generated persistence id. */ @@ -55,7 +68,10 @@ public class Community { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = idColumnName) private long id; - + /** + * System generated persistence key. + */ + private String key; /** * The cover that the community is part of. */ @@ -120,7 +136,13 @@ protected Community() { public long getId() { return id; } - + /** + * Getter for key. + * @return The key. + */ + public String getKey() { + return key; + } /** * Getter for name. * @@ -271,5 +293,75 @@ public List getMemberIndices() { public void preRemove() { this.memberships.clear(); } + + //persistence functions + public void persist( ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(colorColumnName, this.color); + if(this.properties == null) { + this.properties = new ArrayList(); //TODO kann das null bleiben? + } + bd.addAttribute(propertiesColumnName, this.properties); + bd.addAttribute(coverKeyColumnName, this.cover.getKey()); + Map membershipKeyMap = new HashMap(); + + for (Map.Entry entry : this.memberships.entrySet()) { + membershipKeyMap.put(entry.getKey().getKey(), entry.getValue()); //CustomNode Keys muessen bekannt sein + } + bd.addAttribute(membershipKeyMapColumnName, membershipKeyMap); + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public static Community load(String key, Cover cover, ArangoDatabase db, DocumentReadOptions opt) { + Community c = new Community(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + ObjectMapper om = new ObjectMapper(); + String colorString = bd.getAttribute(colorColumnName).toString(); + Object objProperties = bd.getAttribute(propertiesColumnName); + Object objMembershipKeyMap = bd.getAttribute(membershipKeyMapColumnName); + HashMap membershipKeyMap = om.convertValue(objMembershipKeyMap,new TypeReference>() { }); + + c.key = key; + c.cover = cover; + c.name = bd.getAttribute(nameColumnName).toString(); + c.color = Integer.parseInt(colorString); + c.properties = om.convertValue(objProperties, List.class); + + // each customNode is assigned the stored belongingValue + for (Map.Entry entry : membershipKeyMap.entrySet()) { + String nodeKey = entry.getKey(); + CustomNode cn = cover.getGraph().getCustomNodeByKey(nodeKey);// null fall abfangen + c.memberships.put(cn, entry.getValue()); + } + } + else { + System.out.println("empty Community document"); + } + return c; + } + + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "Community : " + n; + if(this.cover != null) {ret += "cover : existiert" +n;} + ret += "Key : " + this.key + n; + ret += "name : " + this.name + n; + ret += "color value: " + this.color + n; + ret += "properties : " + this.properties + n; + if(this.memberships != null) { + for (Map.Entry entry : this.memberships.entrySet()) { + CustomNode cn = entry.getKey(); + ret += cn.String() + entry.getValue() +n; + } + } + return ret; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Cover.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Cover.java index 128c8fa7..2acb5ccb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Cover.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/Cover.java @@ -7,6 +7,7 @@ import java.awt.Color; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -31,8 +32,18 @@ import org.la4j.vector.Vector; import org.la4j.vector.Vectors; -import y.base.Node; -import y.base.NodeCursor; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoCursor; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.AqlQueryOptions; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentDeleteOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.graphstream.graph.Node; /** * Represents a cover, i.e. the result of an overlapping community detection @@ -52,33 +63,45 @@ public class Cover { */ public static final String graphIdColumnName = "GRAPH_ID"; public static final String graphUserColumnName = "USER_NAME"; - private static final String nameColumnName = "NAME"; + public static final String nameColumnName = "NAME"; public static final String idColumnName = "ID"; private static final String creationMethodColumnName = "CREATION_METHOD"; public static final String simCostsColumnName = "SIMILARITYCOSTS"; + public static final String numberOfCommunitiesColumnName = "NUMBER_OF_COMMUNITIES"; // private static final String descriptionColumnName = "DESCRIPTION"; // private static final String lastUpdateColumnName = "LAST_UPDATE"; - + + //ArangoDB name definitions + public static final String collectionName = "cover"; + public static final String graphKeyColumnName = "GRAPH_KEY"; + public static final String creationMethodKeyColumnName = "CREATION_METHOD_KEY"; + public static final String communityKeysColumnName = "COMMUNITY_KEYS"; /* * Field name definitions for JPQL queries. */ public static final String GRAPH_FIELD_NAME = "graph"; public static final String CREATION_METHOD_FIELD_NAME = "creationMethod"; public static final String METRICS_FIELD_NAME = "metrics"; - public static final String ID_FIELD_NAME = "id"; + public static final String ID_FIELD_NAME = "key"; + public static final String NAME_FIELD_NAME = "name"; + public static final String COMMUNITY_COUNT_FIELD_NAME = "numberOfCommunities"; ////////////////////////////// ATTRIBUTES ////////////////////////////// /** * System generated persistence id. */ + private long id; + /** + * System generated persistence key. + */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = idColumnName) - private long id; - + private String key = ""; /** * The graph that the cover is based on. */ + //TODO: GRaph should not be ID in javax persistence, we should change this as long as we dont use any other database library @Id // @ManyToOne(fetch=FetchType.LAZY) @JoinColumns({ @JoinColumn(name = graphIdColumnName, referencedColumnName = CustomGraph.idColumnName), @@ -91,6 +114,13 @@ public class Cover { @Column(name = nameColumnName) private String name = ""; + /** + * The number of communities in the cover + */ + @Column(name = numberOfCommunitiesColumnName) + private Integer numberOfCommunities; + + // /** // * A description of the cover. // */ @@ -166,6 +196,7 @@ public Cover(CustomGraph graph) { public Cover(CustomGraph graph, Matrix memberships) { this.graph = graph; setMemberships(memberships, true); + this.numberOfCommunities = communityCount(); } //////////////////////////// GETTER & SETTER //////////////////////////// @@ -178,7 +209,16 @@ public Cover(CustomGraph graph, Matrix memberships) { public long getId() { return id; } - + + /** + * Getter for the key. + * + * @return The key. + */ + public String getKey() { + return key; + } + /** * Getter for the graph that the cover is based on. * @@ -295,18 +335,18 @@ public void setCreationMethod(CoverCreationLog creationMethod) { * according to the 1-norm. */ public Matrix getMemberships() { - Matrix memberships = new CCSMatrix(graph.nodeCount(), communities.size()); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), communities.size()); Map reverseNodeMap = new HashMap(); - NodeCursor nodes = graph.nodes(); - while (nodes.ok()) { - Node node = nodes.node(); + Iterator nodes = graph.iterator(); + while (nodes.hasNext()) { + Node node = nodes.next(); reverseNodeMap.put(graph.getCustomNode(node), node); - nodes.next(); + } for (int i = 0; i < communities.size(); i++) { Community community = communities.get(i); for (Map.Entry membership : community.getMemberships().entrySet()) { - memberships.set(membership.getKey().index(), i, membership.getValue()); + memberships.set(membership.getKey().getIndex(), i, membership.getValue()); } } return memberships; @@ -328,7 +368,7 @@ public Matrix getMemberships() { * Decides whether the (first) execution time metric log is kept. */ protected void setMemberships(Matrix memberships, boolean keepExecutionTime) { - if (memberships.rows() != graph.nodeCount()) { + if (memberships.rows() != graph.getNodeCount()) { throw new IllegalArgumentException( "The row number of the membership matrix must correspond to the graph node count."); } @@ -339,7 +379,7 @@ protected void setMemberships(Matrix memberships, boolean keepExecutionTime) { metrics.add(executionTime); } memberships = this.normalizeMembershipMatrix(memberships); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); for (int j = 0; j < memberships.columns(); j++) { Community community = new Community(this); communities.add(community); @@ -354,6 +394,7 @@ protected void setMemberships(Matrix memberships, boolean keepExecutionTime) { } } + this.updateNumberOfCommunities(this.communityCount()); } /** @@ -371,6 +412,7 @@ protected void setMemberships(Matrix memberships, boolean keepExecutionTime) { */ public void setMemberships(Matrix memberships) { setMemberships(memberships, false); + this.updateNumberOfCommunities(this.communityCount()); } //////////////////////////// METRICS //////////////////////////// @@ -490,6 +532,16 @@ public void setCommunityName(int communityIndex, String name) { communities.get(communityIndex).setName(name); } + /** + * Setter for the number of communities in the cover. + * + * @param numberOfCommunities + * The community count. + */ + public void updateNumberOfCommunities(Integer numberOfCommunities) { + this.numberOfCommunities = numberOfCommunities; + } + /** * Getter for the color of a certain community. * @@ -617,7 +669,7 @@ protected void removeEmptyCommunities() { /** * Initializes the properties of all communities of this cover. */ - public void initCommunityProperties() { + public void initCommunityProperties() throws InterruptedException { for(Community community: getCommunities()) { CustomGraph subGraph = getGraph().getSubGraph(community.getMemberIndices()); community.setProperties(GraphProperty.getPropertyList(subGraph)); @@ -650,7 +702,7 @@ protected Matrix normalizeMembershipMatrix(Matrix matrix) { /* * Resizing also rows is required in case there are zero columns. */ - matrix = matrix.resize(graph.nodeCount(), matrix.columns() + zeroRowIndices.size()); + matrix = matrix.resize(graph.getNodeCount(), matrix.columns() + zeroRowIndices.size()); for (int i = 0; i < zeroRowIndices.size(); i++) { matrix.set(zeroRowIndices.get(i), matrix.columns() - zeroRowIndices.size() + i, 1d); } @@ -698,6 +750,139 @@ protected void setRowEntriesBelowThresholdToZero(Matrix matrix, int rowIndex, do } matrix.setRow(rowIndex, row); } + + //persistence functions + public void persist(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + if(this.graph == null) { + throw new IllegalArgumentException("graph attribute of the cover to be persisted does not exist"); + } + else if(this.graph.getKey().equals("")) { + throw new IllegalArgumentException("the graph of the cover is not persisted yet"); + } + bd.addAttribute(graphKeyColumnName, this.graph.getKey()); + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(simCostsColumnName, this.simCosts); + bd.addAttribute(numberOfCommunitiesColumnName, this.numberOfCommunities); + + this.creationMethod.persist(db, transId); + bd.addAttribute(creationMethodKeyColumnName, this.creationMethod.getKey()); + collection.insertDocument(bd, createOptions); + this.key = bd.getKey(); + + bd = new BaseDocument(); + List communityKeyList = new ArrayList(); + for(Community c : this.communities) { + c.persist(db, createOptions); + communityKeyList.add(c.getKey()); + } + + bd.addAttribute(communityKeysColumnName, communityKeyList); + for(OcdMetricLog oml : this.metrics) { + oml.persist(db, createOptions); + } + collection.updateDocument(this.key, bd, updateOptions); + } + + public void updateDB(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + ArangoCollection communityCollection = db.collection(Community.collectionName); + ObjectMapper om = new ObjectMapper(); + + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + DocumentReadOptions readOptions = new DocumentReadOptions().streamTransactionId(transId); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + + BaseDocument bd = collection.getDocument(this.key, BaseDocument.class, readOptions); + + if(this.graph == null) { + throw new IllegalArgumentException("graph attribute of the cover to be updated does not exist"); + } + else if(this.graph.getKey().equals("")) { + throw new IllegalArgumentException("the graph of the cover is not persisted yet"); + } + bd.updateAttribute(nameColumnName, this.name); + bd.updateAttribute(simCostsColumnName, this.simCosts); + this.creationMethod.updateDB(db, transId); + + Object objCommunityKeys = bd.getAttribute(communityKeysColumnName); + List communityKeys = om.convertValue(objCommunityKeys, List.class); + for(String communityKey : communityKeys) { //delete all communitys + communityCollection.deleteDocument(communityKey, null, deleteOpt); + } + + List communityKeyList = new ArrayList(); + for(Community c : this.communities) { //add new communities + c.persist(db, createOptions); + communityKeyList.add(c.getKey()); + } + bd.updateAttribute(communityKeysColumnName, communityKeyList); + bd.addAttribute(numberOfCommunitiesColumnName, this.numberOfCommunities); + + for(OcdMetricLog oml : this.metrics) { //updates or persists a metric depending on its current existence + if(oml.getKey().equals("")) { + oml.persist(db, createOptions); + } + else { + oml.updateDB(db, transId); + } + } + collection.updateDocument(this.key, bd, updateOptions); + } + + public static Cover load(String key, CustomGraph g, ArangoDatabase db, String transId) { + + Cover cover = null; + ArangoCollection collection = db.collection(collectionName); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + BaseDocument bd = collection.getDocument(key, BaseDocument.class, readOpt); + + if (bd != null) { + cover = new Cover(g); + ObjectMapper om = new ObjectMapper(); //prepair attributes + String graphKey = bd.getAttribute(graphKeyColumnName).toString(); + if(!graphKey.equals(g.getKey())) { + System.out.println("graph with key: " + g.getKey() + " does not fit to cover with GraphKey: " + graphKey); + return null; + } + String creationMethodKey = bd.getAttribute(creationMethodKeyColumnName).toString(); + Object objCommunityKeys = bd.getAttribute(communityKeysColumnName); + List communityKeys = om.convertValue(objCommunityKeys, List.class); + Object objSimCost = bd.getAttribute(simCostsColumnName); + + //restore all attributes + cover.key = key; + cover.name = bd.getAttribute(nameColumnName).toString(); + cover.creationMethod = CoverCreationLog.load(creationMethodKey, db, readOpt); + for(String communityKey : communityKeys) { + Community community = Community.load(communityKey, cover, db, readOpt); + cover.communities.add(community); + } + cover.numberOfCommunities = (Integer) bd.getAttribute(numberOfCommunitiesColumnName); + + String queryStr = "FOR m IN " + OcdMetricLog.collectionName + " FILTER m." + OcdMetricLog.coverKeyColumnName + + " == @cKey RETURN m._key"; + Map bindVars = Collections.singletonMap("cKey", key); + ArangoCursor metricKeys = db.query(queryStr, bindVars, queryOpt, String.class); + + for(String metricKey : metricKeys) { + OcdMetricLog oml = OcdMetricLog.load(metricKey, cover, db, readOpt); + cover.metrics.add(oml); + } + if(objSimCost != null) { + cover.simCosts = Double.parseDouble(objSimCost.toString()); + } + } + else { + System.out.println("empty Cover document"); + } + return cover; + } @Override public String toString() { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationLog.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationLog.java index cc2e76f0..a28331eb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationLog.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationLog.java @@ -14,6 +14,14 @@ import javax.persistence.GenerationType; import javax.persistence.Id; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; + +import com.fasterxml.jackson.databind.ObjectMapper; /** * A log representation for a cover creation method, i.e. typically an OcdAlgorithm or OcdBenchmark execution. * @author Sebastian @@ -26,9 +34,12 @@ public class CoverCreationLog { * Database column name definitions. */ private static final String idColumnName = "ID"; - private static final String typeColumnName = "TYPE"; - private static final String statusIdColumnName = "STATUS"; + public static final String typeColumnName = "TYPE"; + public static final String statusIdColumnName = "STATUS"; + private static final String parameterColumnName = "PARAMETER"; + private static final String compatibleGraphTypesColumnName = "COMPATIBLEGRAPHTYPES"; + public static final String collectionName = "covercreationlog"; /* * Field names. */ @@ -41,6 +52,10 @@ public class CoverCreationLog { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) private long id; + /** + * System generated persistence key. + */ + private String key; /** * Parameters used by the creation method. */ @@ -118,7 +133,13 @@ public Map getParameters() { public long getId() { return id; } - + /** + * Returns the log key. + * @return The key. + */ + public String getKey() { + return key; + } /** * Returns the graph types the corresponding creation method is compatible with. * @return The graph types. @@ -147,4 +168,70 @@ public void setStatus(ExecutionStatus status) { this.statusId = status.getId(); } + //persistence functions + public void persist(ArangoDatabase db, String transId) { + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(parameterColumnName, this.parameters); //TODO + bd.addAttribute(compatibleGraphTypesColumnName, this.compatibleGraphTypes); + + collection.insertDocument(bd, createOptions); + this.key = bd.getKey(); + } + + public void updateDB(ArangoDatabase db, String transId) { + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(parameterColumnName, this.parameters); + bd.addAttribute(compatibleGraphTypesColumnName, this.compatibleGraphTypes); + collection.updateDocument(this.key, bd, updateOptions); + } + + public static CoverCreationLog load(String key, ArangoDatabase db, DocumentReadOptions opt) { + CoverCreationLog ccl = new CoverCreationLog(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + ObjectMapper om = new ObjectMapper(); + String typeIdString = bd.getAttribute(typeColumnName).toString(); + String statusIdString = bd.getAttribute(statusIdColumnName).toString(); + Object objCompatibleGraphTypes = bd.getAttribute(compatibleGraphTypesColumnName); + Object objParam = bd.getAttribute(parameterColumnName); + + ccl.key = key; + if(objParam != null) { + ccl.parameters = om.convertValue(objParam, Map.class); + } + ccl.typeId = Integer.parseInt(typeIdString); + ccl.statusId = Integer.parseInt(statusIdString); + if(objCompatibleGraphTypes != null) { + ccl.compatibleGraphTypes = om.convertValue(objCompatibleGraphTypes, Set.class); + } + } + else { + System.out.println("empty CoverCreationLog document"); + } + return ccl; + } + + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "CoverCreationLog: " + n; + ret += "Key : " + this.key +n ; + ret += "typeId : " + this.typeId + n ; + ret += "statusId : " + this.statusId + n; + ret += "parameters : " + this.parameters.toString() + n; + ret += "GraphTypes : " + this.compatibleGraphTypes.toString() + n; + return ret; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationType.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationType.java index ee092e7c..0416eaa2 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationType.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverCreationType.java @@ -20,13 +20,16 @@ import i5.las2peer.services.ocd.algorithms.AntColonyOptimizationAlgorithm; import i5.las2peer.services.ocd.algorithms.LouvainAlgorithm; import i5.las2peer.services.ocd.algorithms.DetectingOverlappingCommunitiesAlgorithm; +import i5.las2peer.services.ocd.algorithms.MemeticLinkClusteringAlgorithm; +import i5.las2peer.services.ocd.algorithms.FuzzyCMeansSpectralClusteringAlgorithm; +import i5.las2peer.services.ocd.algorithms.WeakCliquePercolationMethodAlgorithm; +import i5.las2peer.services.ocd.algorithms.LOCAlgorithm; import i5.las2peer.services.ocd.benchmarks.GroundTruthBenchmark; import i5.las2peer.services.ocd.benchmarks.LfrBenchmark; import i5.las2peer.services.ocd.benchmarks.SignedLfrBenchmark; import i5.las2peer.services.ocd.utils.EnumDisplayNames; import i5.las2peer.services.ocd.benchmarks.NewmanBenchmark; -import i5.las2peer.services.ocd.algorithms.FuzzyCMeansSpectralClusteringAlgorithm; -import i5.las2peer.services.ocd.algorithms.WeakCliquePercolationMethodAlgorithm; + import java.security.InvalidParameterException; import java.util.Locale; @@ -161,8 +164,15 @@ public enum CoverCreationType implements EnumDisplayNames { /** * Type corresponding to the WeakCliquePercolationMethodAlgorithm Algorithm. */ - WEAK_CLIQUE_PERCOLATION_METHOD_ALGORITHM("Weak Clique Percolation Method Algorithm", WeakCliquePercolationMethodAlgorithm.class, 25); + WEAK_CLIQUE_PERCOLATION_METHOD_ALGORITHM("Weak Clique Percolation Method Algorithm", WeakCliquePercolationMethodAlgorithm.class, 25), + /** Type corresponding to the MemeticLinkClusteringAlgorithm Algorithm. + */ + M_LINK("M Link", MemeticLinkClusteringAlgorithm.class, 26), + /** + * Type corresponding to the LOCAlgoirthm Algorithm. + */ + LOC_ALGORITHM("LOC Algorithm", LOCAlgorithm.class, 27); /** * The class corresponding to the type, typically a concrete OcdAlgorithm or GroundTruthBenchmark subclass. * Abstract types correspond to the CoverCreationMethod interface itself. @@ -265,4 +275,4 @@ public String toString() { name = name.toLowerCase(Locale.ROOT); return name; } -} \ No newline at end of file +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverId.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverId.java index b9773069..f267fab1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverId.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverId.java @@ -8,9 +8,9 @@ public class CoverId { /** - * The cover-specific id. + * The cover-specific key. */ - private long id; + private String key; /** * The id of the graph the cover is based on. @@ -19,11 +19,11 @@ public class CoverId { /** * Creates a new instance. - * @param id The cover-specific id. + * @param key The cover-specific id. * @param graphId The id of the graph the cover is based on. */ - public CoverId(long id, CustomGraphId graphId) { - this.id = id; + public CoverId(String key, CustomGraphId graphId) { + this.key = key; this.graph = graphId; } @@ -31,7 +31,7 @@ public CoverId(long id, CustomGraphId graphId) { public boolean equals(Object object) { if (object instanceof CoverId) { CoverId pk = (CoverId)object; - return graph.equals(graph) && id == pk.id; + return graph.equals(graph) && key.equals(pk.key); } else { return false; } @@ -39,7 +39,7 @@ public boolean equals(Object object) { @Override public int hashCode() { - return (int)(id + graph.hashCode()); + return (int)(key.hashCode() + graph.hashCode()); } /** @@ -49,4 +49,7 @@ public int hashCode() { public CustomGraphId getGraphId() { return graph; } + public String getKey() { + return key; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverMeta.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverMeta.java new file mode 100644 index 00000000..d1ff5cdc --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CoverMeta.java @@ -0,0 +1,170 @@ +package i5.las2peer.services.ocd.graphs; + +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import i5.las2peer.services.ocd.utils.ExecutionStatus; + +import java.beans.ConstructorProperties; +import java.util.ArrayList; + +/** + * Instance of this class holds meta information about covers and is used + * for efficient requests that don't require accessing full cover + */ +public class CoverMeta { + + /** + * database key of the Cover to which metadata belongs + */ + private String key; + + /** + * The name of the cover + */ + private String name = ""; + + /** + * The number of communities of the cover + */ + private long numberOfCommunities; + + /** + * The key of the graph the cover is based on. + */ + private String graphKey; + + /** + * The name of the graph + */ + private String graphName; + + /** + * The type corresponding to the graph creation log. + */ + int creationTypeId; + + /** + * The type corresponding to the graph creation log status. + */ + int creationStatusId; + + + /** + * + * @param key Key of the cover + * @param name Name of the cover + * @param numberOfCommunities Number of communities in the cover + * @param graphKey Key of the graph the cover is based on + * @param graphName Name of the graph + * @param creationTypeId Id of the cover creation log + * @param creationStatusId Status of the Cover creation log + */ + @ConstructorProperties({"key","name","numberOfCommunities","graphKey", "graphName", "creationTypeId", "creationStatusId"}) + public CoverMeta(String key, String name, long numberOfCommunities, String graphKey, + String graphName, int creationTypeId, int creationStatusId) { + this.key = key; + this.name = name; + this.numberOfCommunities = numberOfCommunities; + this.graphKey = graphKey; + this.graphName = graphName; + this.creationTypeId = creationTypeId; + this.creationStatusId = creationStatusId; + } + + + /** + * Finds and returns name of the cover creation type of the + * cover to which this meta data belongs. + * @return Cover creation type name. + */ + public String getCreationTypeName(){ + return CoverCreationType.lookupType(this.creationTypeId).name(); + } + + /** + * Finds and returns display name of the creation log of the + * cover to which this meta data belongs. + * @return Cover creation log display name. + */ + public String getCreationTypeDisplayName(){ + return CoverCreationType.lookupType(this.creationTypeId).getDisplayName(); + } + + /** + * Finds and returns name of the execution status of the + * cover to which this meta data belongs. + * @return Cover execution status name. + */ + public String getCreationStatusName(){ + + return ExecutionStatus.lookupStatus(this.creationStatusId).name(); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getNumberOfCommunities() { + return numberOfCommunities; + } + + public void setNumberOfCommunities(long numberOfCommunities) { + this.numberOfCommunities = numberOfCommunities; + } + + public String getGraphKey() { + return graphKey; + } + + public void setGraphKey(String graphKey) { + this.graphKey = graphKey; + } + + public String getGraphName() { + return graphName; + } + + public void setGraphName(String graphName) { + this.graphName = graphName; + } + + public int getCreationTypeId() { + return creationTypeId; + } + + public void setCreationTypeId(int creationTypeId) { + this.creationTypeId = creationTypeId; + } + + public int getCreationStatusId() { + return creationStatusId; + } + + public void setCreationStatusId(int creationStatusId) { + this.creationStatusId = creationStatusId; + } + + @Override + public String toString() { + return "CoverMeta{" + + "key='" + key + '\'' + + ", name='" + name + '\'' + + ", numberOfCommunities=" + numberOfCommunities + + ", graphKey='" + graphKey + '\'' + + ", graphName='" + graphName + '\'' + + ", creationTypeId=" + creationTypeId + + ", creationStatusId=" + creationStatusId + + '}'; + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomEdge.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomEdge.java index 0e27d91c..6882530c 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomEdge.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomEdge.java @@ -10,8 +10,21 @@ import javax.persistence.JoinColumns; import javax.persistence.ManyToOne; -import y.base.Edge; -import y.base.Node; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoEdgeCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseEdgeDocument; +import com.arangodb.entity.CollectionType; +import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.arangodb.model.EdgeCreateOptions; + +import java.util.UUID; +import org.graphstream.graph.implementations.AbstractEdge; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + /** * Custom edge extension. @@ -32,7 +45,9 @@ public class CustomEdge { protected static final String graphIdColumnName = "GRAPH_ID"; protected static final String graphUserColumnName = "USER_NAME"; private static final String weightColumnName = "WEIGHT"; - + //ArangoDB + public static final String graphKeyColumnName = "GRAPH_KEY"; + public static final String collectionName = "customedge"; /** * System generated persistence id. */ @@ -41,6 +56,11 @@ public class CustomEdge { @Column(name = idColumnName) private int id; + /** + * System generated persistence key. + */ + public String key; + /** * The graph that the edge belongs to. */ @@ -119,7 +139,15 @@ protected CustomEdge(CustomEdge customEdge) { public int getId() { return id; } - + + /** + * Getter for the key. + * @return The key. + */ + public String getKey() { + return this.key; + } + /** * Getter for the edge weight. * @return The edge weight. @@ -201,8 +229,8 @@ protected void setTarget(CustomNode target) { * @param edge The corresponding yFiles edge. */ protected void update(CustomGraph graph, Edge edge) { - this.source = graph.getCustomNode(edge.source()); - this.target = graph.getCustomNode(edge.target()); + this.source = graph.getCustomNode(edge.getSourceNode()); + this.target = graph.getCustomNode(edge.getTargetNode()); // EdgeRealizer eRealizer = graph.getRealizer(edge); // this.points = new ArrayList(); // this.points.add(new PointEntity(eRealizer.getSourcePoint())); @@ -214,7 +242,7 @@ protected void update(CustomGraph graph, Edge edge) { } /** - * Creates the corresponding yFiles edge after the custom edge is loaded from persistence. + * Creates the corresponding graphstream edge after the custom edge is loaded from persistence. * Only for persistence purposes. * @param graph The graph that the edge is part of. * @param source The source node of the edge. @@ -222,7 +250,8 @@ protected void update(CustomGraph graph, Edge edge) { * @return The edge. */ protected Edge createEdge(CustomGraph graph, Node source, Node target) { - Edge edge = graph.createEdge(source, target); + //TODO: Again figure out how to name edges + Edge edge = graph.addEdge(UUID.randomUUID().toString(), source, target); // EdgeRealizer eRealizer = graph.getRealizer(edge); // eRealizer.setSourcePoint(points.get(0).createPoint()); // eRealizer.setTargetPoint(points.get(1).createPoint()); @@ -232,4 +261,60 @@ protected Edge createEdge(CustomGraph graph, Node source, Node target) { // } return edge; } + + + //persistence functions + public void persist(ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseEdgeDocument bed = new BaseEdgeDocument(); + bed.addAttribute(weightColumnName, this.weight); + bed.addAttribute(graphKeyColumnName, this.graph.getKey()); + bed.setFrom(CustomNode.collectionName + "/" + this.source.getKey()); + bed.setTo(CustomNode.collectionName + "/" + this.target.getKey()); + + collection.insertDocument(bed, opt); + this.key = bed.getKey(); + } + + public void updateDB(ArangoDatabase db, DocumentUpdateOptions opt) { + + ArangoCollection collection = db.collection(collectionName); + BaseEdgeDocument bed = new BaseEdgeDocument(); + bed.addAttribute(weightColumnName, this.weight); + bed.addAttribute(graphKeyColumnName, this.graph.getKey()); + bed.setFrom(CustomNode.collectionName + "/" + this.source.getKey()); + bed.setTo(CustomNode.collectionName + "/" + this.target.getKey()); + collection.updateDocument(this.key, bed, opt); + } + + public static CustomEdge load(BaseEdgeDocument bed, CustomNode source, CustomNode target, CustomGraph graph, ArangoDatabase db) { + CustomEdge ce = new CustomEdge(); + if (bed != null) { + ce.key = bed.getKey(); + ce.graph = graph; + if(bed.getAttribute(weightColumnName)!=null) { + ce.weight = Double.parseDouble(bed.getAttribute(weightColumnName).toString()); + } + ce.source = source; + ce.target = target; + } + else { + System.out.println("Empty Document"); + } + return ce; + } + + + + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "CustomNode: " + n; + ret += "Key : " + this.key + n; + ret += "weight : " + this.weight; + ret += "source Key : " + this.source.getKey(); + ret += "target Key : " + this.target.getKey(); + + return ret; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraph.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraph.java index cfe7f8bb..1e7abb67 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraph.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraph.java @@ -1,12 +1,7 @@ package i5.las2peer.services.ocd.graphs; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; +import java.util.stream.Stream; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -26,19 +21,37 @@ import javax.persistence.PreUpdate; import javax.persistence.Transient; +import org.graphstream.graph.implementations.AbstractGraph; +import org.graphstream.graph.implementations.AbstractNode; +import org.graphstream.graph.implementations.MultiNode; +import org.graphstream.ui.layout.Layout; +import org.graphstream.ui.layout.springbox.implementations.SpringBox; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.entity.BaseEdgeDocument; +import com.arangodb.ArangoCursor; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.arangodb.model.DocumentDeleteOptions; +import com.arangodb.model.AqlQueryOptions; + +import com.fasterxml.jackson.databind.ObjectMapper; import i5.las2peer.services.ocd.algorithms.utils.Termmatrix; import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeries; import i5.las2peer.services.ocd.graphs.properties.AbstractProperty; import i5.las2peer.services.ocd.graphs.properties.GraphProperty; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.GraphListener; -import y.base.Node; -import y.base.NodeCursor; -import y.view.Graph2D; +import org.graphstream.graph.implementations.MultiGraph; + + + +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + /** * Represents a graph (or network), i.e. the node / edge structure and @@ -49,7 +62,13 @@ */ @Entity @IdClass(CustomGraphId.class) -public class CustomGraph extends Graph2D { +//TODO: Add boolean/function to check if graph is connected or not. +//TODO: Decide about undirected edges, graphstream would have own functionalities for that. +//TODO: Check whether UUIDs work out as unique graph IDs, collision chances should however be extremely low +//TODO: Check whether UUIDs work out as unique edge IDs, collision chances should however be extremely low +//TODO: Check whether UUIDs work out as unique node IDs, collision chances should however be extremely low. Check whether this could actually replace the current node names. Would however break style with the naming of the other classes. +//TODO: Integrate graphstream attributes into persistence or not? +public class CustomGraph extends MultiGraph { /////////////////// DATABASE COLUMN NAMES @@ -58,31 +77,47 @@ public class CustomGraph extends Graph2D { */ public static final String idColumnName = "ID"; public static final String userColumnName = "USER_NAME"; - private static final String nameColumnName = "NAME"; + public static final String nameColumnName = "NAME"; + public static final String nodeCountColumnName = "NODE_COUNT"; + public static final String edgeCountColumnName = "EDGE_COUNT"; // private static final String descriptionColumnName = "DESCRIPTION"; // private static final String lastUpdateColumnName = "LAST_UPDATE"; private static final String idEdgeMapKeyColumnName = "RUNTIME_ID"; private static final String idNodeMapKeyColumnName = "RUNTIME_ID"; - private static final String creationMethodColumnName = "CREATION_METHOD"; + public static final String creationMethodColumnName = "CREATION_METHOD"; private static final String pathColumnName = "INDEX_PATH"; - + //ArangoDB + private static final String propertiesColumnName = "PROPERTIES"; + private static final String coverKeysColumnName = "COVER_KEYS"; + public static final String creationMethodKeyColumnName = "CREATION_METHOD_KEY"; + public static final String typesColumnName = "TYPES"; + public static final String collectionName = "customgraph"; //do not choose the name "graph" here because it is reserved for querys + /* * Field name definitions for JPQL queries. */ public static final String USER_NAME_FIELD_NAME = "userName"; - public static final String ID_FIELD_NAME = "id"; + public static final String ID_FIELD_NAME = "key"; + public static final String NAME_FIELD_NAME = "name"; public static final String CREATION_METHOD_FIELD_NAME = "creationMethod"; + public static final String NODE_COUNT_FIELD_NAME = "graphNodeCount"; + public static final String EDGE_COUNT_FIELD_NAME = "graphEdgeCount"; + public static final String TYPES_FIELD_NAME = "types"; ////////////////////////////////////////////////////////////////// ///////// Attributes ////////////////////////////////////////////////////////////////// /** - * System generated persistence id. + * System generated persistence key. */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = idColumnName) + private String key = ""; + /** + * System generated persistence id. + */ private long id; /** @@ -105,6 +140,21 @@ public class CustomGraph extends Graph2D { @Column(name = pathColumnName) private String path = ""; + /** + * The number of nodes in the graph. + */ + @Column(name = nodeCountColumnName) + private long graphNodeCount; + + /** + * The number of edges in the graph. + */ + @Column(name = edgeCountColumnName) + private long graphEdgeCount; + + + + // /** // * The description of the graph. // */ @@ -176,12 +226,12 @@ public class CustomGraph extends Graph2D { * Mapping from nodes to fix node ids. */ @Transient - private Map nodeIds = new HashMap(); + private Map nodeIds = new HashMap(); /* * Mapping from custom nodes to nodes. */ @Transient - private Map reverseNodeMap = new HashMap(); + private Map reverseNodeMap = new HashMap(); /* * Used for assigning runtime edge indices. */ @@ -196,54 +246,79 @@ public class CustomGraph extends Graph2D { @Transient private Termmatrix termMatrix = new Termmatrix(); + @Transient + public Layout layout; ////////////////////////////////////////////////////////////////// ///////// Constructor ////////////////////////////////////////////////////////////////// /** - * Creates a new instance. + * Creates a new instance. The name attribute will be a random UUID */ - public CustomGraph() { - this.addGraphListener(new CustomGraphListener()); - } + public CustomGraph() { + super(UUID.randomUUID().toString()); + this.addSink(new CustomGraphListener(this)); + layout = new SpringBox(false); + this.addSink(layout); //Layout listener + layout.addAttributeSink(this); + } /** * Copy constructor. - * + * * @param graph * The graph to copy. */ - public CustomGraph(Graph2D graph) { - super(graph); - NodeCursor nodes = this.nodes(); - while (nodes.ok()) { - Node node = nodes.node(); - this.addCustomNode(node); - nodes.next(); + //TODO: Refactor this to actually copy nodes/edges + public CustomGraph(AbstractGraph graph) { + super(UUID.randomUUID().toString()); //TODO: CHANGE to correct super execution + this.addSink(new CustomGraphListener(this)); + layout = new SpringBox(false); + this.addSink(layout); //Layout listener + layout.addAttributeSink(this); + //super(graph); + Node[] nodes = this.nodes().toArray(Node[]::new); + for(Node node : nodes) { + //TODO: Maybe checks needed whether MultiNode or not + this.addNode(node.getId()); } - EdgeCursor edges = this.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); - this.addCustomEdge(edge); - edges.next(); + Edge[] edges = this.edges().toArray(Edge[]::new); + for(Edge edge : edges) { + this.addEdge(edge.getId(), edge.getSourceNode().getId(),edge.getTargetNode().getId()); } - Iterator listenerIt = this.getGraphListeners(); - while (listenerIt.hasNext()) { - this.removeGraphListener((GraphListener) listenerIt.next()); - listenerIt.remove(); - } - this.addGraphListener(new CustomGraphListener()); +// Iterator listenerIt = this.getGraphListeners(); +// while (listenerIt.hasNext()) { +// this.removeGraphListener((GraphListener) listenerIt.next()); +// listenerIt.remove(); +// } +// this.addGraphListener(new CustomGraphListener()); } /** * Copy constructor. - * + * * @param graph * The graph to copy. */ public CustomGraph(CustomGraph graph) { - super(graph); + super(UUID.randomUUID().toString()); + this.addSink(new CustomGraphListener(this)); + layout = new SpringBox(false); + this.addSink(layout); //Layout listener + layout.addAttributeSink(this); + + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + this.addNode(nodesIt.next().getId()); + } + + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + this.addEdge(edge.getId(),edge.getSourceNode().getId(),edge.getTargetNode().getId()); + } + this.creationMethod = new GraphCreationLog(graph.creationMethod.getType(), graph.creationMethod.getParameters()); this.creationMethod.setStatus(graph.creationMethod.getStatus()); @@ -251,7 +326,7 @@ public CustomGraph(CustomGraph graph) { copyMappings(graph.customNodes, graph.customEdges, graph.nodeIds, graph.edgeIds); this.userName = new String(graph.userName); this.name = new String(graph.name); - this.id = graph.id; + this.key = graph.key; this.path = graph.path; // this.description = new String(graph.description); // if(graph.lastUpdate != null) { @@ -270,20 +345,18 @@ public CustomGraph(CustomGraph graph) { * Sets all the structural information to that of another graph. This * includes the structure of the nodes and edges, their custom information * and the graph types. - * + * * @param graph * The graph to obtain data from. */ + //TODO: Possibly add graphstream attributes as well here (provided we start saving them as well) public void setStructureFrom(CustomGraph graph) { - NodeCursor nodes = this.nodes(); - Node node; + Node[] nodes = this.nodes().toArray(Node[]::new); /* * Removes all nodes and edges including their custom information. */ - while (nodes.ok()) { - node = nodes.node(); - this.removeNode(node); - nodes.next(); + for(Node NodeToRemove : nodes) { + this.removeNode(NodeToRemove); } /* * Adds new nodes and edges. @@ -296,42 +369,44 @@ public void setStructureFrom(CustomGraph graph) { this.nodeIndexer = 0; this.reverseNodeMap.clear(); this.types.clear(); - nodes = graph.nodes(); - while (nodes.ok()) { - node = this.createNode(); - this.setNodeName(node, graph.getNodeName(nodes.node())); - nodes.next(); - } - Node[] nodeArr = this.getNodeArray(); - EdgeCursor edges = graph.edges(); - Edge edge; - Edge refEdge; - while (edges.ok()) { - refEdge = edges.edge(); - edge = this.createEdge(nodeArr[refEdge.source().index()], nodeArr[refEdge.target().index()]); - this.setEdgeWeight(edge, graph.getEdgeWeight(refEdge)); - edges.next(); - } - /* - * Updates graph types. - */ - for (GraphType type : graph.getTypes()) { - this.addType(type); - } + + Node node; + + nodes = graph.nodes().toArray(Node[]::new); + for(Node nodeToCopy : nodes) { + node = this.addNode(nodeToCopy.getId()); + this.setNodeName(node, graph.getNodeName(nodeToCopy)); + } + Node[] nodeArr = this.nodes().toArray(Node[]::new); + + Iterator edges = graph.edges().iterator(); + Edge edge; + Edge refEdge; + while (edges.hasNext()) { + refEdge = edges.next(); + edge = this.addEdge(UUID.randomUUID().toString(), nodeArr[refEdge.getSourceNode().getIndex()], nodeArr[refEdge.getTargetNode().getIndex()]); + this.setEdgeWeight(edge, graph.getEdgeWeight(refEdge)); + } + /* + * Updates graph types. + */ + for (GraphType type : graph.getTypes()) { + this.addType(type); + } } /** - * Getter for the id. - * - * @return The id. + * Getter for the persistence id. + * + * @return The persistence id. */ - public long getId() { - return id; + public String getKey() { + return key; } /** * Getter for the user name. - * + * * @return The name. */ public String getUserName() { @@ -340,7 +415,7 @@ public String getUserName() { /** * Setter for the user name. - * + * * @param user * The name. */ @@ -350,7 +425,7 @@ public void setUserName(String user) { /** * Getter for the graph name. - * + * * @return The name. */ public String getName() { @@ -359,7 +434,7 @@ public String getName() { /** * Setter for the graph name. - * + * * @param name * The name. */ @@ -369,7 +444,7 @@ public void setName(String name) { /** * Getter for the graphs path to the index for the node content. - * + * * @return The index path. */ public String getPath() { @@ -378,7 +453,7 @@ public String getPath() { /** * Setter for the graphs path to the index for the node content. - * + * * @param path * The index path. */ @@ -408,7 +483,7 @@ public void setTermMatrix(Termmatrix t) { /** * Setter for the creation method. - * + * * @param creationMethod * The creation method. */ @@ -418,7 +493,7 @@ public void setCreationMethod(GraphCreationLog creationMethod) { /** * Getter for the creation method. - * + * * @return The creation method. */ public GraphCreationLog getCreationMethod() { @@ -429,7 +504,7 @@ public GraphCreationLog getCreationMethod() { /** * States whether the graph is of a certain type. - * + * * @param type * The graph type. * @return TRUE if the graph is of the type, otherwise FALSE. @@ -440,7 +515,7 @@ public boolean isOfType(GraphType type) { /** * Adds a graph type to the graph. - * + * * @param type * The graph type. */ @@ -450,7 +525,7 @@ public void addType(GraphType type) { /** * Removes a graph type from the graph. - * + * * @param type * The graph type. */ @@ -467,7 +542,7 @@ public void clearTypes() { /** * Getter for the graph types. - * + * * @return The types. */ public Set getTypes() { @@ -492,9 +567,31 @@ public boolean isWeighted() { return isOfType(GraphType.WEIGHTED); } + /** + * TODO + * @param edgeId + * Id of the edge to be added. + * @param src + * Source node + * @param srcId + * Source node id + * @param dst + * Destination node + * @param dstId + * Destination node id + * @param directed + * True if edge is directed + * @return The directed edge + */ + protected Edge addEdge(String edgeId, AbstractNode src, String srcId, AbstractNode dst, String dstId, + boolean directed) { + Edge edge = super.addEdge(edgeId, src, srcId, dst, dstId, true); + return edge; + } + /** * Getter for the edge weight of a certain edge. - * + * * @param edge * The edge. * @return The edge weight. @@ -505,7 +602,7 @@ public double getEdgeWeight(Edge edge) { /** * Setter for the edge weight of a certain edge. - * + * * @param edge * The edge. * @param weight @@ -515,13 +612,42 @@ public void setEdgeWeight(Edge edge, double weight) { getCustomEdge(edge).setWeight(weight); } + /** + * Finds two nodes based on their identifiers and combines edge weights + * between the found nodes. This is equivalent to having + * a single undirected, weighted edge between two nodes. + * @param fromId First node + * @param toId Second node + */ + public void combineEdgeWeights(String fromId, String toId){ + /* + find nodes and edges based on the identifiers provided + */ + Node from = this.getNode(fromId); + Node to = this.getNode(toId); + Edge forward = from.getEdgeToward(to); + Edge backward = to.getEdgeToward(from); + + /* + calculate combined weight of edges between the above two nodes + */ + double edgeWeight = this.getEdgeWeight(forward) + this.getEdgeWeight(backward); + + /* + set the combined weight to be the weight of the edges between the above two nodes. + */ + this.setEdgeWeight(forward, edgeWeight); + this.setEdgeWeight(backward, edgeWeight); + + } + // public long getEdgeId(Edge edge) { // return getCustomEdge(edge).getId(); // } /** * Getter for the node name of a certain node. - * + * * @param node * The node. * @return The node name. @@ -532,7 +658,7 @@ public String getNodeName(Node node) { /** * Setter for the node name of a certain node. - * + * * @param node * The node. * @param name @@ -542,6 +668,14 @@ public void setNodeName(Node node, String name) { getCustomNode(node).setName(name); } + /** + * Update node and edge count numbers + */ + public void setNodeEdgeCountColumnFields(){ + this.graphNodeCount = this.nodes().count(); + this.graphEdgeCount = this.edges().count(); + } + public int getNodeId(Node node) { return getCustomNode(node).getId(); } @@ -551,18 +685,19 @@ public int getNodeId(Node node) { /** * Returns weighted in-degree, i.e. the sum of the weights of all incoming * edges of a node. - * + * * @param node * The node. * @return The weighted in-degree. + * @throws InterruptedException If the executing thread was interrupted. */ - public double getWeightedInDegree(Node node) { + //TODO: Check whether we need to account extra for parallel edges here (and in all other edge methods) + public double getWeightedInDegree(Node node) throws InterruptedException { + Edge[] inEdges = Stream.concat(this.getPositiveInEdges(node).stream(), this.getNegativeInEdges(node).stream()).toArray(Edge[]::new); double inDegree = 0; - EdgeCursor inEdges = node.inEdges(); - while (inEdges.ok()) { - Edge edge = inEdges.edge(); + for (Edge edge : inEdges) { inDegree += getCustomEdge(edge).getWeight(); - inEdges.next(); + } return inDegree; } @@ -570,21 +705,19 @@ public double getWeightedInDegree(Node node) { /** * Returns positive in-degree, i.e. the weight sum of all positive incoming * edges of a node. - * + * * @param node * The node. * @return The positive in-degree. - * + * @throws InterruptedException If the executing thread was interrupted. + * * @author YLi */ - public double getPositiveInDegree(Node node) { + public double getPositiveInDegree(Node node) throws InterruptedException { + Edge[] inEdges = this.getPositiveInEdges(node).toArray(Edge[]::new); double inDegree = 0; - EdgeCursor inEdges = node.inEdges(); - while (inEdges.ok()) { - Edge edge = inEdges.edge(); - if (getCustomEdge(edge).getWeight() > 0) - inDegree += getCustomEdge(edge).getWeight(); - inEdges.next(); + for (Edge edge : inEdges) { + inDegree += getCustomEdge(edge).getWeight(); } return inDegree; } @@ -592,21 +725,19 @@ public double getPositiveInDegree(Node node) { /** * Returns positive out-degree, i.e. the weight sum of all positive outgoing * edges of a node. - * + * * @param node * The concerned node. * @return The positive out-degree. - * + * @throws InterruptedException If the executing thread was interrupted. + * * @author YLi */ - public double getPositiveOutDegree(Node node) { + public double getPositiveOutDegree(Node node) throws InterruptedException { + Edge[] outEdges = this.getPositiveOutEdges(node).toArray(Edge[]::new); double outDegree = 0; - EdgeCursor outEdges = node.outEdges(); - while (outEdges.ok()) { - Edge edge = outEdges.edge(); - if (getCustomEdge(edge).getWeight() > 0) - outDegree += getCustomEdge(edge).getWeight(); - outEdges.next(); + for (Edge edge : outEdges) { + outDegree += getCustomEdge(edge).getWeight(); } return outDegree; } @@ -614,21 +745,19 @@ public double getPositiveOutDegree(Node node) { /** * Returns negative in-degree, i.e. the sum of all negative incoming edges * of a node. - * + * * @param node * The node under observation. * @return The negative in-degree. - * + * @throws InterruptedException If the executing thread was interrupted. + * * @author YLi */ - public double getNegativeInDegree(Node node) { + public double getNegativeInDegree(Node node) throws InterruptedException { + Edge[] inEdges = this.getNegativeInEdges(node).toArray(Edge[]::new); double inDegree = 0; - EdgeCursor inEdges = node.inEdges(); - while (inEdges.ok()) { - Edge edge = inEdges.edge(); - if (getCustomEdge(edge).getWeight() < 0) - inDegree += getCustomEdge(edge).getWeight(); - inEdges.next(); + for (Edge edge : inEdges) { + inDegree += getCustomEdge(edge).getWeight(); } return inDegree; } @@ -636,21 +765,19 @@ public double getNegativeInDegree(Node node) { /** * Returns negative out-degree, i.e. the sum of all negative outgoing edges * of a node. - * + * * @param node * The node under observation. * @return The negative out-degree. - * + * @throws InterruptedException If the executing thread was interrupted. + * * @author YLi */ - public double getNegativeOutDegree(Node node) { + public double getNegativeOutDegree(Node node) throws InterruptedException { + Edge[] outEdges = this.getNegativeOutEdges(node).toArray(Edge[]::new); double outDegree = 0; - EdgeCursor outEdges = node.outEdges(); - while (outEdges.ok()) { - Edge edge = outEdges.edge(); - if (getCustomEdge(edge).getWeight() < 0) - outDegree += getCustomEdge(edge).getWeight(); - outEdges.next(); + for (Edge edge : outEdges) { + outDegree += getCustomEdge(edge).getWeight(); } return outDegree; } @@ -658,18 +785,18 @@ public double getNegativeOutDegree(Node node) { /** * Returns the weighted out-degree, i.e. the sum of the weights of all * outgoing edges of a node. - * + * * @param node * The node. * @return The weighted out-degree. + * @throws InterruptedException If the executing thread was interrupted. */ - public double getWeightedOutDegree(Node node) { + public double getWeightedOutDegree(MultiNode node) throws InterruptedException { + Edge[] outEdges = Stream.concat(this.getPositiveOutEdges(node).stream(), this.getNegativeOutEdges(node).stream()).toArray(Edge[]::new); double outDegree = 0; - EdgeCursor outEdges = node.outEdges(); - while (outEdges.ok()) { - Edge edge = outEdges.edge(); + for (Edge edge : outEdges) { outDegree += getCustomEdge(edge).getWeight(); - outEdges.next(); + } return outDegree; } @@ -677,18 +804,18 @@ public double getWeightedOutDegree(Node node) { /** * Returns the weighted node degree, i.e. the sum of the weights of all * incident edges of a node. - * + * * @param node * The node. * @return The weighted degree. + * @throws InterruptedException If the executing thread was interrupted. */ - public double getWeightedNodeDegree(Node node) { + public double getWeightedNodeDegree(MultiNode node) throws InterruptedException { + Edge[] edges = node.edges().toArray(Edge[]::new); double degree = 0; - EdgeCursor edges = node.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + for (Edge edge : edges) { degree += getCustomEdge(edge).getWeight(); - edges.next(); + } return degree; } @@ -696,123 +823,123 @@ public double getWeightedNodeDegree(Node node) { /** * Returns the absolute node degree, i.e. the sum of absolute weights of all * incident edges of a node. - * + * * @param node * The node. * @return The absolute degree. - * + * @throws InterruptedException If the executing thread was interrupted. + * * @author YLi */ - public double getAbsoluteNodeDegree(Node node) { + public double getAbsoluteNodeDegree(MultiNode node) throws InterruptedException { + Edge[] edges = node.edges().toArray(Edge[]::new); double degree = 0; - EdgeCursor edges = node.edges(); - Edge edge; - while (edges.ok()) { - edge = edges.edge(); + for (Edge edge : edges) { degree += Math.abs(getCustomEdge(edge).getWeight()); - edges.next(); + } return degree; } - + /** * Returns all edge weights * @return Double array containing all edge weights - * + * * @author Tobias */ public double[] getEdgeWeights() { - double[] res = new double[this.edgeCount()]; - - EdgeCursor edges = this.edges(); + double[] res = new double[this.edgeCount]; + Edge[] edges = this.edges().toArray(Edge[]::new); + int i = 0; - while(edges.ok()) { - Edge edge = edges.edge(); + for (Edge edge : edges) { res[i] = this.getEdgeWeight(edge); - edges.next(); + i++; - } + } return res; } - + /** * Returns the maximum edge weight of the graph. - * + * * @return The maximum edge weight or negative infinity, if there are no * edges in the graph. */ public double getMaxEdgeWeight() { double maxWeight = Double.NEGATIVE_INFINITY; double edgeWeight; - EdgeCursor edges = this.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + Edge[] edges = this.edges().toArray(Edge[]::new); + + for (Edge edge : edges) { edgeWeight = getCustomEdge(edge).getWeight(); if (edgeWeight > maxWeight) { maxWeight = edgeWeight; } - edges.next(); + } return maxWeight; } /** * Returns the minimum edge weight of the graph. - * + * * @return The minimum edge weight or positive infinity, if there are no * edges in the graph. */ public double getMinEdgeWeight() { double minWeight = Double.POSITIVE_INFINITY; double edgeWeight; - EdgeCursor edges = this.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + Edge[] edges = this.edges().toArray(Edge[]::new); + + for (Edge edge : edges) { edgeWeight = getCustomEdge(edge).getWeight(); if (edgeWeight < minWeight) { minWeight = edgeWeight; } - edges.next(); + } return minWeight; } /** * Returns the minimum weighted in-degree of the graph. - * + * * @return The weighted in-degree or positive infinity if the graph does not * contain any nodes. + * @throws InterruptedException If the executing thread was interrupted. */ - public double getMinWeightedInDegree() { + public double getMinWeightedInDegree() throws InterruptedException { double minDegree = Double.POSITIVE_INFINITY; - NodeCursor nodes = this.nodes(); + Node[] nodes = this.nodes().toArray(Node[]::new); double curDegree; - while (nodes.ok()) { - curDegree = getWeightedInDegree(nodes.node()); + for (Node node : nodes) { + curDegree = getWeightedInDegree(node); if (curDegree < minDegree) { minDegree = curDegree; } - nodes.next(); + } return minDegree; } /** * Returns the maximum weighted in-degree of the graph. - * + * * @return The weighted in-degree or negative infinity if the graph does not * contain any nodes. + * @throws InterruptedException If the executing thread was interrupted. */ - public double getMaxWeightedInDegree() { + public double getMaxWeightedInDegree() throws InterruptedException { double maxDegree = Double.NEGATIVE_INFINITY; - NodeCursor nodes = this.nodes(); + Node[] nodes = this.nodes().toArray(Node[]::new); double curDegree; - while (nodes.ok()) { - curDegree = getWeightedInDegree(nodes.node()); + for (Node node : nodes) { + curDegree = getWeightedInDegree(node); if (curDegree > maxDegree) { maxDegree = curDegree; } - nodes.next(); + } return maxDegree; } @@ -820,333 +947,436 @@ public double getMaxWeightedInDegree() { /////////////// neighbours /////////// /** * Returns the neighbourhood matrix. - * + * * @return The neighbourhood matrix. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Matrix getNeighbourhoodMatrix() throws InterruptedException { - int nodeNumber = this.nodeCount(); + int nodeNumber = this.nodeCount; Matrix neighbourhoodMatrix = new CCSMatrix(nodeNumber, nodeNumber); - EdgeCursor edges = this.edges(); - Edge edge; - while (edges.ok()) { + Edge[] edges = this.edges().toArray(Edge[]::new); + for (Edge edge : edges) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); - neighbourhoodMatrix.set(edge.source().index(), edge.target().index(), this.getEdgeWeight(edge)); - edges.next(); + neighbourhoodMatrix.set(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex(), this.getEdgeWeight(edge)); } return neighbourhoodMatrix; } /** * Returns the set of all neighbours of a given node. - * + * * @param node * The node under observation. - * + * * @return The neighbour set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getNeighbours(Node node) throws InterruptedException { Set neighbourSet = new HashSet(); - NodeCursor neighbours = node.neighbors(); - Node neighbour; - while (neighbours.ok()) { + Node[] neighbours = node.neighborNodes().toArray(Node[]::new); // Gets every "opposite" node of all adjacent edges, can therefore have duplicates + + for (Node neighbour : neighbours) { if (Thread.interrupted()) { throw new InterruptedException(); } - neighbour = neighbours.node(); + if (!neighbourSet.contains(neighbour)) { neighbourSet.add(neighbour); } - neighbours.next(); + } + return neighbourSet; + } + + /** + * Returns the set of all neighbours of a given node. + * + * @param node + * The node under observation. + * + * @return The neighbour set of the given node. + * + * @author YLi + * @throws InterruptedException if the thread was interrupted + */ + public Set getSuccessorNeighbours(Node node) throws InterruptedException { + Set neighbourSet = new HashSet(); + Node[] neighbours = node.neighborNodes().toArray(Node[]::new); + + for (Node neighbour : neighbours) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (!neighbourSet.contains(neighbour) && neighbour.hasEdgeFrom(node)) { + neighbourSet.add(neighbour); + } + } + return neighbourSet; + } + + /** + * Returns the set of all neighbours of a given node that have an edge toward it. + * + * @param node + * The node under observation. + * + * @return The neighbour set of the given node. + * + * @author YLi + * @throws InterruptedException if the thread was interrupted + */ + public Set getPredecessorNeighbours(Node node) throws InterruptedException { + Set neighbourSet = new HashSet(); + Node[] neighbours = node.neighborNodes().toArray(Node[]::new); + + for (Node neighbour : neighbours) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (!neighbourSet.contains(neighbour) && neighbour.hasEdgeToward(node)) { + neighbourSet.add(neighbour); + } } return neighbourSet; } /** * Returns the set of all positive neighbours of a given node. - * + * * @param node * The node under observation. - * + * * @return The positive neighbour set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ - public Set getPositiveNeighbours(Node node) throws InterruptedException { - Set positiveNeighbour = new HashSet(); - Set neighbours = this.getNeighbours(node); + public Set getPositiveNeighbours(MultiNode node) throws InterruptedException { + Set positiveNeighbourSet = new HashSet(); + Node[] neighbours = node.neighborNodes().toArray(Node[]::new); + for (Node neighbour : neighbours) { /* * if node a->b positive or node b->a positive */ - Edge edge = node.getEdgeTo(neighbour); - Edge reverseEdge = node.getEdgeFrom(neighbour); - if (edge != null) { - if (this.getEdgeWeight(edge) > 0) { - positiveNeighbour.add(neighbour); - continue; - } - } - if (reverseEdge != null) { - if (this.getEdgeWeight(reverseEdge) > 0) { - positiveNeighbour.add(neighbour); + Edge[] edges = node.getEdgeSetBetween(neighbour).toArray(Edge[]::new); + for (Edge edge : edges) { + if (this.getEdgeWeight(edge) >= 0) { + positiveNeighbourSet.add(neighbour); + break; } } } - return positiveNeighbour; + return positiveNeighbourSet; } /** * Returns the set of all negative neighbours of a given node. - * + * * @param node * The node under observation. - * + * * @return The negative neighbour set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ - public Set getNegativeNeighbours(Node node) throws InterruptedException { - Set negativeNeighbour = new HashSet(); - Set neighbours = this.getNeighbours(node); + public Set getNegativeNeighbours(MultiNode node) throws InterruptedException { + Set negativeNeighbourSet = new HashSet(); + Node[] neighbours = (Node[]) node.neighborNodes().toArray(Node[]::new); + for (Node neighbour : neighbours) { /* - * if node a->b positive or node b->a positive + * if node a->b negative or node b->a negative */ - Edge edge = node.getEdgeTo(neighbour); - Edge reverseEdge = node.getEdgeFrom(neighbour); - if (edge != null) { + Edge[] edges = node.getEdgeSetBetween(neighbour).toArray(Edge[]::new); + for (Edge edge : edges) { if (this.getEdgeWeight(edge) < 0) { - negativeNeighbour.add(neighbour); - continue; - } - } - if (reverseEdge != null) { - if (this.getEdgeWeight(reverseEdge) < 0) { - negativeNeighbour.add(neighbour); + negativeNeighbourSet.add(neighbour); + break; } } } - return negativeNeighbour; + return negativeNeighbourSet; } ////////// incident edges //////// /** * Returns the set of all positive edges incident to a given node. - * + * * @param node * The node under observation. - * + * * @return The positive edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getPositiveEdges(Node node) throws InterruptedException { Set positiveEdges = new HashSet(); - EdgeCursor incidentEdges = node.edges(); - Edge incidentEdge; - while (incidentEdges.ok()) { - if (Thread.interrupted()) { - throw new InterruptedException(); + Edge[] edges = node.edges().toArray(Edge[]::new); + for (Edge edge : edges) { + if (this.getEdgeWeight(edge) >= 0) { + positiveEdges.add(edge); + break; } - incidentEdge = incidentEdges.edge(); - if (getCustomEdge(incidentEdge).getWeight() > 0) { - positiveEdges.add(incidentEdge); + } + return positiveEdges; + } + + /** + * Returns the set of all positive edges incident to a given node. + * + * @param node + * The node under observation. + * + * @return The positive edge set of the given node. + * + * @author YLi + * @throws InterruptedException if the thread was interrupted + */ + + public Set getPositiveEdgesAboveZero(Node node) throws InterruptedException { + Set positiveEdges = new HashSet(); + Edge[] edges = node.edges().toArray(Edge[]::new); + for (Edge edge : edges) { + if (this.getEdgeWeight(edge) > 0) { + positiveEdges.add(edge); + break; } - incidentEdges.next(); + } return positiveEdges; } /** * Returns the set of all positive incoming edges for a given node. - * + * * @param node * The node under observation. - * + * * @return The positive incoming edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getPositiveInEdges(Node node) throws InterruptedException { Set positiveInEdges = new HashSet(); - EdgeCursor incidentInEdges = node.inEdges(); - Edge incidentInEdge; - while (incidentInEdges.ok()) { + Edge[] incidentInEdges = node.enteringEdges().toArray(Edge[]::new); + for (Edge incidentInEdge : incidentInEdges) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (getCustomEdge(incidentInEdge).getWeight() >= 0) { + positiveInEdges.add(incidentInEdge); + } + } + return positiveInEdges; + } + + /** + * Returns the set of all positive incoming edges for a given node. + * + * @param node + * The node under observation. + * + * @return The positive incoming edge set of the given node. + * + * @author YLi + * @throws InterruptedException if the thread was interrupted + */ + + public Set getPositiveInEdgesAboveZero(Node node) throws InterruptedException { + Set positiveInEdges = new HashSet(); + Edge[] incidentInEdges = node.enteringEdges().toArray(Edge[]::new); + for (Edge incidentInEdge : incidentInEdges) { if (Thread.interrupted()) { throw new InterruptedException(); } - incidentInEdge = incidentInEdges.edge(); if (getCustomEdge(incidentInEdge).getWeight() > 0) { positiveInEdges.add(incidentInEdge); } - incidentInEdges.next(); + } return positiveInEdges; } /** * Returns the set of all positive outgoing edges for a given node. - * + * * @param node * The node under observation. - * + * * @return The positive outgoing edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getPositiveOutEdges(Node node) throws InterruptedException { Set positiveOutEdges = new HashSet(); - EdgeCursor incidentOutEdges = node.outEdges(); - Edge incidentOutEdge; - while (incidentOutEdges.ok()) { + Edge[] incidentOutEdges = node.leavingEdges().toArray(Edge[]::new); + for (Edge incidentOutEdge : incidentOutEdges) { + if (Thread.interrupted()) { + throw new InterruptedException(); + } + if (getCustomEdge(incidentOutEdge).getWeight() >= 0) { + positiveOutEdges.add(incidentOutEdge); + } + } + return positiveOutEdges; + } + + /** + * Returns the set of all positive outgoing edges for a given node. + * + * @param node + * The node under observation. + * + * @return The positive outgoing edge set of the given node. + * + * @author YLi + * @throws InterruptedException if the thread was interrupted + */ + + public Set getPositiveOutEdgesAboveZero(Node node) throws InterruptedException { + Set positiveOutEdges = new HashSet(); + Edge[] incidentOutEdges = node.leavingEdges().toArray(Edge[]::new); + for (Edge incidentOutEdge : incidentOutEdges) { if (Thread.interrupted()) { throw new InterruptedException(); } - incidentOutEdge = incidentOutEdges.edge(); if (getCustomEdge(incidentOutEdge).getWeight() > 0) { positiveOutEdges.add(incidentOutEdge); } - incidentOutEdges.next(); + } return positiveOutEdges; } /** * Returns the set of all negative edges incident to a given node. - * + * * @param node * The node under observation. - * + * * @return The negative edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getNegativeEdges(Node node) throws InterruptedException { Set negativeEdges = new HashSet(); - EdgeCursor incidentEdges = node.edges(); - Edge incidentEdge; - while (incidentEdges.ok()) { - if (Thread.interrupted()) { - throw new InterruptedException(); - } - incidentEdge = incidentEdges.edge(); - if (getCustomEdge(incidentEdge).getWeight() < 0) { - negativeEdges.add(incidentEdge); + Edge[] edges = node.edges().toArray(Edge[]::new); + for (Edge edge : edges) { + if (this.getEdgeWeight(edge) < 0) { + negativeEdges.add(edge); + break; } - incidentEdges.next(); + } return negativeEdges; } /** * Returns the set of all negative incoming edges for a given node. - * + * * @param node * The node under observation. - * + * * @return The negative incoming edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getNegativeInEdges(Node node) throws InterruptedException { Set negativeInEdges = new HashSet(); - EdgeCursor incidentInEdges = node.inEdges(); - Edge incidentInEdge; - while (incidentInEdges.ok()) { + Edge[] incidentInEdges = node.enteringEdges().toArray(Edge[]::new); + for (Edge incidentInEdge : incidentInEdges) { if (Thread.interrupted()) { throw new InterruptedException(); } - incidentInEdge = incidentInEdges.edge(); + if (getCustomEdge(incidentInEdge).getWeight() < 0) { negativeInEdges.add(incidentInEdge); } - incidentInEdges.next(); + } return negativeInEdges; } /** * Returns the set of all negative outgoing edges for a given node. - * + * * @param node * The node under observation. - * + * * @return The negative outgoing edge set of the given node. - * + * * @author YLi * @throws InterruptedException if the thread was interrupted */ public Set getNegativeOutEdges(Node node) throws InterruptedException { Set negativeOutEdges = new HashSet(); - EdgeCursor incidentOutEdges = node.outEdges(); - Edge incidentOutEdge; - while (incidentOutEdges.ok()) { + Edge[] incidentOutEdges = node.leavingEdges().toArray(Edge[]::new); + for (Edge incidentOutEdge : incidentOutEdges) { if (Thread.interrupted()) { throw new InterruptedException(); } - incidentOutEdge = incidentOutEdges.edge(); + if (getCustomEdge(incidentOutEdge).getWeight() < 0) { negativeOutEdges.add(incidentOutEdge); } - incidentOutEdges.next(); + } return negativeOutEdges; - } - + } + ////////// properties //////// - /** + /** + + * @return properties list */ public List getProperties() { return this.properties; } - - + + /** * Returns a specific graph property - * + * * @param property requested property - * + * * @return the graph property - * + * */ public double getProperty(GraphProperty property) { return getProperties().get(property.getId()); } - - /** + + /** * Initialize the properties - * + * @throws InterruptedException If the executing thread was interrupted. */ - public void initProperties() { - + //TODO: Figure out what this means + public void initProperties() throws InterruptedException { + this.properties = new ArrayList<>(GraphProperty.size()); for (int i = 0; i < GraphProperty.size(); i++) { AbstractProperty property = null; @@ -1157,18 +1387,18 @@ public void initProperties() { } this.properties.add(i, property.calculate(this)); } - } - + } + /** * Returns a new sub graph of a CustomGraph - * + * * @param nodeIds The node ids for the sub graph * @return sub graph */ public CustomGraph getSubGraph(List nodeIds) { CustomGraph subGraph = new CustomGraph(); - int graphSize = nodeCount(); + long graphSize = nodeCount; int subSize = nodeIds.size(); Map nodeMap = new HashMap<>(subSize); @@ -1181,15 +1411,15 @@ public CustomGraph getSubGraph(List nodeIds) { if (nodeId > graphSize) throw new IllegalArgumentException("Invalid node id; id to high"); - nodeMap.put(nodeId, subGraph.createNode()); + nodeMap.put(nodeId, subGraph.addNode(UUID.randomUUID().toString())); } - for (Edge edge : getEdgeArray()) { - int source = edge.source().index(); - int target = edge.target().index(); - + for (Edge edge : edges().toArray(Edge[]::new)) { + int source = edge.getSourceNode().getIndex(); + int target = edge.getTargetNode().getIndex(); + if (nodeIds.contains(source) && nodeIds.contains(target)) { - subGraph.createEdge(nodeMap.get(source), nodeMap.get(target)); + subGraph.addEdge(UUID.randomUUID().toString(), nodeMap.get(source), nodeMap.get(target)); } } return subGraph; @@ -1200,7 +1430,7 @@ public CustomGraph getSubGraph(List nodeIds) { /** * Initializes all node and edge mappings for the copy constructor. - * + * * @param customNodes * The custom node mapping of the copied custom graph. * @param customEdges @@ -1211,7 +1441,7 @@ public CustomGraph getSubGraph(List nodeIds) { * The edge id mapping of the copied custom graph. */ protected void copyMappings(Map customNodes, Map customEdges, - Map nodeIds, Map edgeIds) { + Map nodeIds, Map edgeIds) { for (Map.Entry entry : customNodes.entrySet()) { this.customNodes.put(entry.getKey(), new CustomNode(entry.getValue())); @@ -1219,24 +1449,23 @@ protected void copyMappings(Map customNodes, Map entry : customEdges.entrySet()) { this.customEdges.put(entry.getKey(), new CustomEdge(entry.getValue())); } - Node[] nodeArr = this.getNodeArray(); - for (Map.Entry entry : nodeIds.entrySet()) { - this.nodeIds.put(nodeArr[entry.getKey().index()], entry.getValue()); + Node[] nodeArr = this.nodes().toArray(Node[]::new); + for (Map.Entry entry : nodeIds.entrySet()) { + this.nodeIds.put((MultiNode) nodeArr[entry.getKey().getIndex()], entry.getValue()); } - NodeCursor nodes = this.nodes(); - while (nodes.ok()) { - this.reverseNodeMap.put(this.getCustomNode(nodes.node()), nodes.node()); - nodes.next(); + Node[] nodes = this.nodes().toArray(Node[]::new); + for (Node node : nodes) { + this.reverseNodeMap.put(this.getCustomNode(node), (MultiNode) node); } - Edge[] edgeArr = this.getEdgeArray(); + Edge[] edgeArr = this.edges().toArray(Edge[]::new); for (Map.Entry entry : edgeIds.entrySet()) { - this.edgeIds.put(edgeArr[entry.getKey().index()], entry.getValue()); + this.edgeIds.put(edgeArr[entry.getKey().getIndex()], entry.getValue()); } } /** * Returns the custom edge object corresponding to an edge. - * + * * @param edge * An edge which must belong to this graph. * @return The corresponding custom edge object. @@ -1248,21 +1477,36 @@ protected CustomEdge getCustomEdge(Edge edge) { /** * Returns the custom node object corresponding to a node. - * + * * @param node * A node which must belong to this graph. * @return The corresponding custom node object. */ + protected CustomNode getCustomNode(Node node) { - int index = nodeIds.get(node); - return customNodes.get(index); + + if ( nodeIds.get(node) != null) { + int index = nodeIds.get(node); + return customNodes.get(index); + } + + + //TODO: is this addition to avoid nullpointer exception correct? + for (CustomNode customNode : customNodes.values()){ + if (node.getId().equals(customNode.getName())){ + return customNode; + } + } + return null; + + } /** * Returns the node object corresponding to a custom node. - * + * * @param customNode - * A customNode which must belong to this graph. + * A customMultiNode which must belong to this graph. * @return The corresponding node object. */ protected Node getNode(CustomNode customNode) { @@ -1271,11 +1515,11 @@ protected Node getNode(CustomNode customNode) { /** * Creates a new custom node object and maps the node to it. - * + * * @param node * The node. */ - protected void addCustomNode(Node node) { + protected void addCustomNode(MultiNode node) { CustomNode customNode = new CustomNode(); this.nodeIds.put(node, this.nodeIndexer); this.customNodes.put(nodeIndexer, customNode); @@ -1285,11 +1529,11 @@ protected void addCustomNode(Node node) { /** * Removes the mappings between a node and its custom node object. - * + * * @param node * the node */ - protected void removeCustomNode(Node node) { + protected void removeCustomNode(MultiNode node) { CustomNode customNode = this.getCustomNode(node); int id = this.nodeIds.get(node); this.nodeIds.remove(node); @@ -1299,7 +1543,7 @@ protected void removeCustomNode(Node node) { /** * Creates a new custom edge object and maps the edge to it. - * + * * @param edge * The edge. */ @@ -1312,7 +1556,7 @@ protected void addCustomEdge(Edge edge) { /** * Removes the mapping from an edge to its custom edge. - * + * * @param edge * the edge */ @@ -1335,9 +1579,9 @@ private void postLoad() { this.nodeIds.clear(); this.customNodes.clear(); for (CustomNode customNode : nodes) { - Node node = customNode.createNode(this); - this.nodeIds.put(node, node.index()); - this.customNodes.put(node.index(), customNode); + MultiNode node = (MultiNode) customNode.createNode(this); + this.nodeIds.put(node, node.getIndex()); + this.customNodes.put(node.getIndex(), customNode); this.reverseNodeMap.put(customNode, node); } List edges = new ArrayList(this.customEdges.values()); @@ -1346,44 +1590,252 @@ private void postLoad() { for (CustomEdge customEdge : edges) { Edge edge = customEdge.createEdge(this, reverseNodeMap.get(customEdge.getSource()), this.reverseNodeMap.get(customEdge.getTarget())); - this.edgeIds.put(edge, edge.index()); - this.customEdges.put(edge.index(), customEdge); + this.edgeIds.put(edge, edge.getIndex()); + this.customEdges.put(edge.getIndex(), customEdge); } - nodeIndexer = this.nodeCount(); - edgeIndexer = this.edgeCount(); - Iterator listenerIt = this.getGraphListeners(); - while (listenerIt.hasNext()) { - this.removeGraphListener((GraphListener) listenerIt.next()); - listenerIt.remove(); - } - this.addGraphListener(new CustomGraphListener()); + nodeIndexer = this.nodeCount; + edgeIndexer = this.edgeCount; +// Iterator listenerIt = this.getGraphListeners(); +// while (listenerIt.hasNext()) { +// this.removeGraphListener((GraphListener) listenerIt.next()); +// listenerIt.remove(); +// } +// this.addGraphListener(new CustomGraphListener()); } /** * PrePersist Method. Writes the attributes of nodes and edges into their * corresponding custom nodes and edges. - * + * * Makes sure the Graph Properties are up-to-date. + * + * @throws InterruptedException If the executing thread was interrupted. */ @PrePersist @PreUpdate - protected void prePersist() { - NodeCursor nodes = this.nodes(); - while (nodes.ok()) { - Node node = nodes.node(); - this.getCustomNode(node).update(this, node); - nodes.next(); + protected void prePersist() throws InterruptedException { + Node[] nodes = this.nodes().toArray(Node[]::new); + for (Node node : nodes) { + this.getCustomNode(node).update(this, (Node)node); } - EdgeCursor edges = this.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + Edge[] edges = this.edges().toArray(Edge[]::new); + for (Edge edge : edges) { this.getCustomEdge(edge).update(this, edge); - edges.next(); } initProperties(); } + //persistence functions + protected CustomNode getCustomNodeByKey(String key) { + CustomNode ret = null; + List nodes = new ArrayList(this.customNodes.values()); + for(CustomNode cn : nodes) { + if(key.equals(cn.getKey())) { + ret = cn; + break; + } + } + if(ret == null) { + System.out.println("CustomNode with Key : " + key + "does not exist in this graph."); + } + return ret; + } + + public void persist( ArangoDatabase db, String transId) throws InterruptedException { + this.setNodeEdgeCountColumnFields(); // update node/edge counts before persisting + this.prePersist(); + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + //options for the transaction + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + //EdgeCreateOptions edgeCreateOptions = new EdgeCreateOptions().streamTransactionId(transId); + bd.addAttribute(userColumnName, this.userName); + bd.addAttribute(pathColumnName, this.path); //TODO muss gespeichert werden? + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(typesColumnName, this.types); + bd.addAttribute(nodeCountColumnName, this.graphNodeCount); + bd.addAttribute(edgeCountColumnName, this.graphEdgeCount); + this.creationMethod.persist(db, createOptions); + bd.addAttribute(creationMethodKeyColumnName, this.creationMethod.getKey()); + collection.insertDocument(bd, createOptions); + this.key = bd.getKey(); + + bd = new BaseDocument(); + + //TODO: is this a valid replacement to store customNode? +// NodeCursor nodes = this.nodes(); +// while (nodes.ok()) { //persist all nodes from the graph +// Node n = nodes.node(); +// CustomNode node = this.getCustomNode(n); +// node.persist(db, createOptions); +// nodes.next(); +// } + List nodes = new ArrayList(this.customNodes.values()); + for (CustomNode customNode : nodes) { + customNode.persist(db,createOptions); + } + + + List edges = new ArrayList(this.customEdges.values()); + for (CustomEdge customEdge : edges) { + customEdge.persist(db, createOptions); + } + +// Iterator edges = this.edges().iterator(); +// while (edges.hasNext()) { //persist all edges from the graph +// Edge edge = edges.next(); +// edge. +// } + + bd.addAttribute(propertiesColumnName, this.properties); + //TODO covers variable speichern? + + collection.updateDocument(this.key, bd, updateOptions); + } + + public static CustomGraph load(String key, ArangoDatabase db, String transId) { + CustomGraph graph = null; + ArangoCollection collection = db.collection(collectionName); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + BaseDocument bd = collection.getDocument(key, BaseDocument.class, readOpt); + + if (bd != null) { + graph = new CustomGraph(); + ObjectMapper om = new ObjectMapper(); + Object objId = bd.getAttribute(idColumnName); + if(objId!= null) { + graph.id = Long.parseLong(objId.toString()); + } + graph.key = key; + graph.userName = bd.getAttribute(userColumnName).toString(); + graph.path = bd.getAttribute(pathColumnName).toString(); + graph.name = bd.getAttribute(nameColumnName).toString(); + Object objTypes = bd.getAttribute(typesColumnName); + graph.types = om.convertValue(objTypes, Set.class); + Object objProperties = bd.getAttribute(propertiesColumnName); + graph.properties = om.convertValue(objProperties, List.class); + String creationMethodKey = bd.getAttribute(creationMethodKeyColumnName).toString(); + graph.graphNodeCount = om.convertValue(bd.getAttribute(nodeCountColumnName), Long.class); + graph.graphEdgeCount = om.convertValue(bd.getAttribute(edgeCountColumnName), Long.class); + graph.creationMethod = GraphCreationLog.load(creationMethodKey, db, readOpt); + + //nodes werden in customNodes Map eingefuegt + Map customNodeKeyMap = new HashMap(); + String query = "FOR node IN " + CustomNode.collectionName + " FILTER node." + + CustomNode.graphKeyColumnName +" == \"" + key +"\" RETURN node"; + ArangoCursor nodeDocuments = db.query(query, queryOpt, BaseDocument.class); + + int i=0; + while(nodeDocuments.hasNext()) { + BaseDocument nodeDocument = nodeDocuments.next(); + CustomNode node = CustomNode.load(nodeDocument, graph); + graph.customNodes.put(i, node); + customNodeKeyMap.put(CustomNode.collectionName +"/"+node.getKey(), node); + i++; + } + + //edges werden in customNodes Map eingefuegt + query = "FOR edge IN " + CustomEdge.collectionName + " FILTER edge."; + query += CustomEdge.graphKeyColumnName +" == \"" + key +"\" RETURN edge"; + ArangoCursor edgeDocuments = db.query(query, queryOpt, BaseEdgeDocument.class); + i=0; + + while(edgeDocuments.hasNext()) { + BaseEdgeDocument edgeDocument = edgeDocuments.next(); + CustomNode source = customNodeKeyMap.get(edgeDocument.getFrom()); + CustomNode target = customNodeKeyMap.get(edgeDocument.getTo()); + CustomEdge edge = CustomEdge.load(edgeDocument, source, target, graph, db); + graph.customEdges.put(i, edge); + i++; + } + graph.postLoad(); + } + else { + System.out.println("Empty Graph document"); + System.out.println(" DB name: " + db.dbName().get()); + } + return graph; + } + + public void updateDB(ArangoDatabase db, String transId) throws InterruptedException { //only updates the nodes/edges/GraphCreationLog and graph Attributes + this.prePersist(); + ArangoCollection collection = db.collection(collectionName); + + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + DocumentCreateOptions createOptions = new DocumentCreateOptions().streamTransactionId(transId); + + BaseDocument bd = collection.getDocument(this.key, BaseDocument.class, readOpt); + + String gclKey = bd.getAttribute(creationMethodKeyColumnName).toString(); + ArangoCollection gclCollection = db.collection(GraphCreationLog.collectionName); + gclCollection.deleteDocument(gclKey, null, deleteOpt); //delete GraphCreationLog + this.creationMethod.persist(db, createOptions); + bd.updateAttribute(creationMethodKeyColumnName, this.creationMethod.getKey()); //update creation method key + + + List nodes = new ArrayList(this.customNodes.values()); + for (CustomNode customNode : nodes) { // update all nodes from the graph + if(customNode.getKey() == null) { + customNode.persist(db, createOptions); + }else { + customNode.updateDB(db, updateOptions); + } + } + + + List edges = new ArrayList(this.customEdges.values()); + for (CustomEdge customEdge : edges) { + if(customEdge.getKey() == null) { + customEdge.persist(db, createOptions); + }else { + customEdge.updateDB(db, updateOptions); + } + } + + + + bd.updateAttribute(userColumnName, this.userName); //update all atributes + bd.updateAttribute(pathColumnName, this.path); + bd.updateAttribute(nameColumnName, this.name); + bd.updateAttribute(typesColumnName, this.types); + bd.updateAttribute(propertiesColumnName, this.properties); + bd.updateAttribute(nodeCountColumnName, this.graphNodeCount); + bd.updateAttribute(edgeCountColumnName, this.graphEdgeCount); + + collection.updateDocument(this.key, bd, updateOptions); + } + + //TODO funktion verwerfen + public void setNodeNames() { + Set nodes = this.nodeIds.keySet(); + int i = 0; + for(Node node : nodes) { + i++; + this.setNodeName(node,"Node : " + i); + } + } + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "CustomGraph: " + n; + ret += "Key : " + this.key +n ; + ret += "userName : " + this.userName + n ; + ret += "name : " + this.name+n; + ret += "path : " + this.path + n; + if(this.types != null) {ret += "types : " + this.types.toString()+n;} + else { ret += "no types" +n;} + if(this.properties != null) { ret += "properties : " + this.properties + n;} + else { ret += "no properties" +n;} + if(this.creationMethod != null) { ret += "creationMethod : " + this.creationMethod.String() + n;} + else { ret += "no creationMethod" +n;} + ret += "Es gibt : " + this.covers.size() + " cover"+n; + return ret; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphId.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphId.java index 2f2f8466..1c93dc2b 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphId.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphId.java @@ -10,7 +10,7 @@ public class CustomGraphId { /** * The graph-specific id. */ - private long id; + private String key; /** * The name of the user owning the graph. @@ -19,11 +19,11 @@ public class CustomGraphId { /** * Creates a new instance. - * @param id The graph-specific id. + * @param key The graph-specific key. * @param userName The name of the user owning the graph. */ - public CustomGraphId(long id, String userName) { - this.id = id; + public CustomGraphId(String key, String userName) { + this.key = key; this.userName = userName; } @@ -31,7 +31,7 @@ public CustomGraphId(long id, String userName) { public boolean equals(Object object) { if (object instanceof CustomGraphId) { CustomGraphId pk = (CustomGraphId)object; - return userName.equals(pk.userName) && id == pk.id; + return userName.equals(pk.userName) && key.equals(pk.key); } else { return false; } @@ -39,7 +39,13 @@ public boolean equals(Object object) { @Override public int hashCode() { - return (int)(id + userName.hashCode()); + return (int)(key.hashCode() + userName.hashCode()); + } + public String getUser() { + return userName; + } + public String getKey() { + return key; } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphListener.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphListener.java index c90bdb38..57f58ca5 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphListener.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphListener.java @@ -1,9 +1,7 @@ package i5.las2peer.services.ocd.graphs; -import y.base.Edge; -import y.base.GraphEvent; -import y.base.GraphListener; -import y.base.Node; +import org.graphstream.graph.implementations.MultiNode; +import org.graphstream.stream.Sink; /** * Listener for Custom Graph Events. @@ -11,37 +9,90 @@ * @author Sebastian * */ -public class CustomGraphListener implements GraphListener { - - @Override - public void onGraphEvent(GraphEvent event) { - if(event.getGraph() instanceof CustomGraph) { - CustomGraph graph = (CustomGraph)event.getGraph(); - byte type = event.getType(); - switch(type) { - case GraphEvent.EDGE_CREATION: - if(event.getData() instanceof Edge) { - graph.addCustomEdge((Edge)event.getData()); - } - break; - case GraphEvent.PRE_EDGE_REMOVAL: - if(event.getData() instanceof Edge) { - graph.removeCustomEdge((Edge)event.getData()); - } - break; - case GraphEvent.NODE_CREATION: - if(event.getData() instanceof Node) { - graph.addCustomNode((Node)event.getData()); - } - break; - case GraphEvent.PRE_NODE_REMOVAL: - if(event.getData() instanceof Node) { - graph.removeCustomNode((Node)event.getData()); - } - break; - default: - } - } +public class CustomGraphListener implements Sink { + CustomGraph graph; + + public CustomGraphListener(CustomGraph graph) { + this.graph = graph; + } + + + @Override + public void edgeAdded(String sourceId, long timeId, String edgeId, String fromNodeId, String toNodeId, boolean directed) { + //super.edgeAdded(sourceId, timeId, edgeId, fromNodeId, toNodeId, directed); + graph.addCustomEdge(graph.getEdge(edgeId)); + } + + @Override + public void edgeRemoved(String sourceId, long timeId, String edgeId) { + //super.edgeRemoved(sourceId, timeId, edgeId); + graph.removeCustomEdge(graph.getEdge(edgeId)); + } + + @Override + public void graphCleared(String sourceId, long timeId) { + + } + + @Override + public void stepBegins(String sourceId, long timeId, double step) { + + } + + @Override + public void nodeAdded(String sourceId, long timeId, String nodeId) { + graph.addCustomNode((MultiNode) graph.getNode(nodeId)); + } + + @Override + public void nodeRemoved(String sourceId, long timeId, String nodeId) { + graph.removeCustomNode((MultiNode) graph.getNode(nodeId)); + } + + @Override + public void graphAttributeAdded(String sourceId, long timeId, String attribute, Object value) { + + } + + @Override + public void graphAttributeChanged(String sourceId, long timeId, String attribute, Object oldValue, Object newValue) { + } + @Override + public void graphAttributeRemoved(String sourceId, long timeId, String attribute) { + + } + + @Override + public void nodeAttributeAdded(String sourceId, long timeId, String nodeId, String attribute, Object value) { + + } + + @Override + public void nodeAttributeChanged(String sourceId, long timeId, String nodeId, String attribute, Object oldValue, Object newValue) { + + } + + @Override + public void nodeAttributeRemoved(String sourceId, long timeId, String nodeId, String attribute) { + + } + + @Override + public void edgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) { + + } + + @Override + public void edgeAttributeChanged(String sourceId, long timeId, String edgeId, String attribute, Object oldValue, Object newValue) { + + } + + @Override + public void edgeAttributeRemoved(String sourceId, long timeId, String edgeId, String attribute) { + + } } + + diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphMeta.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphMeta.java new file mode 100644 index 00000000..bc5f5fba --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomGraphMeta.java @@ -0,0 +1,200 @@ +package i5.las2peer.services.ocd.graphs; + +import i5.las2peer.services.ocd.utils.ExecutionStatus; + +import java.beans.ConstructorProperties; +import java.util.ArrayList; + +/** + * Instance of this class holds meta information about graphs and is used + * for efficient requests that don't require accessing full graph + */ +public class CustomGraphMeta { + + /** + * database key of the CustomGraph to which metadata belongs + */ + private String key; + + /** + * id of the CustomGraph to which metadata belongs + */ + private long id; //TODO: is this needed? + + /** + * The name of the user owning the graph. + */ + private String userName = ""; + + /** + * The name of the graph. + */ + private String name = ""; + + /** + * The node count of the graph. + */ + private long nodeCount; + + /** + * The edge count of the graph. + */ + private long edgeCount; + + /** + * The list of type enum ids of the graph. + */ + ArrayList types; + + /** + * The type corresponding to the graph creation log. + */ + int creationTypeId; + + /** + * The type corresponding to the graph creation log status. + */ + int creationStatusId; + + + /** + * Constructor that is used to generate a CustomGraphMeta instance + * using the JSON input resulting from ArangoDB queries + * + * @param key Key of the graph + * @param userName Creator of the graph + * @param name Name of the graph + * @param nodeCount Node count of the graph + * @param edgeCount Edge count of the graph + * @param types Array of graph types + * @param creationTypeId Id of the graph creation log + * @param creationStatusId Status of the graph creation log + */ + @ConstructorProperties({"key","userName","name","nodeCount","edgeCount", "types", "creationTypeId", "creationStatusId"}) + public CustomGraphMeta(String key, String userName, String name, Long nodeCount, Long edgeCount, ArrayList types, int creationTypeId, int creationStatusId) { + this.key = key; + this.userName = userName; + this.name = name; + this.nodeCount = nodeCount; + this.edgeCount = edgeCount; + this.creationTypeId = creationTypeId; + this.creationStatusId = creationStatusId; + + if(types != null) { + this.types = types; + }else{ + this.types = new ArrayList<>(); + } + } + + public String getKey() {return key;} + + public void setKey(String key) {this.key = key;} + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getNodeCount() { + return nodeCount; + } + + public void setNodeCount(long nodeCount) { + this.nodeCount = nodeCount; + } + + public long getEdgeCount() { + return edgeCount; + } + + public void setEdgeCount(long edgeCount) { + this.edgeCount = edgeCount; + } + + public ArrayList getTypes() { + return types; + } + + public void setTypes(ArrayList types) { + this.types = types; + } + + public int getCreationTypeId() { + return creationTypeId; + } + + public void setCreationTypeId(int creationTypeId) { + this.creationTypeId = creationTypeId; + } + + public int getCreationStatusId() { + return creationStatusId; + } + + public void setCreationStatusId(int creationStatusId) { + this.creationStatusId = creationStatusId; + } + + /** + * Finds and returns name of the graph creation type of the + * graph to which this meta data belongs. + * @return Graph creation type name. + */ + public String getCreationTypeName(){ + return GraphCreationType.lookupType(this.creationTypeId).name(); + } + + /** + * Finds and returns display name of the creation log s of the + * graph to which this meta data belongs. + * @return Graph creation log display name. + */ + public String getCreationTypeDisplayName(){ + return GraphCreationType.lookupType(this.creationTypeId).getDisplayName(); + } + + /** + * Finds and returns name of the execution status of the + * graph to which this meta data belongs. + * @return Graph execution status name. + */ + public String getCreationStatusName(){ + return ExecutionStatus.lookupStatus(this.creationStatusId).name(); + } + + + + @Override + public String toString() { + return "CustomGraphMeta{" + + "key=" + key + + ", userName='" + userName + '\'' + + ", name='" + name + '\'' + + ", nodeCount=" + nodeCount + + ", edgeCount=" + edgeCount + + ", types=" + types + + ", creationType=" + creationTypeId + + ", creationStatus=" + creationStatusId + + '}'; + } +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomNode.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomNode.java index 4553165e..0701f28e 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomNode.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/CustomNode.java @@ -11,8 +11,23 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.graphs.CustomNodeId; +import org.graphstream.graph.Node; +import org.graphstream.graph.implementations.MultiNode; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import i5.las2peer.services.ocd.metrics.OcdMetricLog; + -import y.base.Node; /** * Custom node expansion. @@ -35,6 +50,9 @@ public class CustomNode { protected static final String graphIdColumnName = "GRAPH_ID"; protected static final String graphUserColumnName = "USER_NAME"; protected static final String nameColumnName = "NAME"; + + public static final String graphKeyColumnName = "GRAPH_KEY"; + public static final String collectionName = "customnode"; // private static final String xColumnName = "X"; // private static final String yColumnName = "Y"; // private static final String widthColumnName = "WIDTH"; @@ -48,7 +66,11 @@ public class CustomNode { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) private int id; - + /** + * System generated persistence key. + */ + private String key; + /** * The graph that the node is part of. */ @@ -130,6 +152,13 @@ protected CustomNode(CustomNode customNode) { */ public int getId() { return this.id; + } + /** + * Getter for the key. + * @return The key. + */ + public String getKey() { + return this.key; } /** @@ -218,13 +247,14 @@ protected void update(CustomGraph graph, Node node) { } /* - * Creates a corresponding node after the custom node was loaded from persistence. + * Creates a corresponding node after the custom node was loaded from persistence. * Only for persistence purposes. * @param graph The graph that the (custom) node is part of. * @return The created node. */ protected Node createNode(CustomGraph graph) { - Node node = graph.createNode(); + //TODO: Check whether it made sense to replace this here but the previous createNode definitely also didnt seem right as this doesnt even add a custom node + Node node = graph.addNode(this.name); // NodeRealizer nRealizer = graph.getRealizer(node); // nRealizer.setX(this.x); // nRealizer.setY(this.y); @@ -234,4 +264,79 @@ protected Node createNode(CustomGraph graph) { return node; } + //persistence functions + public void persist(ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(graphKeyColumnName, this.graph.getKey()); + + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public static CustomNode load(BaseDocument bd, CustomGraph graph) { + CustomNode cn = new CustomNode(); + if (bd != null) { + cn.key = bd.getKey(); + cn.graph = graph; + if(bd.getAttribute(nameColumnName)!= null) { + cn.name = bd.getAttribute(nameColumnName).toString(); + } + + } + else { + System.out.println("Empty Document"); + } + return cn; + } + + public void updateDB(ArangoDatabase db, DocumentUpdateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(nameColumnName, this.name); + bd.addAttribute(graphKeyColumnName, this.graph.getKey()); + collection.updateDocument(this.key, bd, opt); + } + + //TODO wird die funktion gebraucht? + public static CustomNode load(String key, CustomGraph graph, ArangoDatabase db, DocumentReadOptions opt) { + CustomNode cn = new CustomNode(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + String name = bd.getAttribute(nameColumnName).toString(); + + cn.key = key; + cn.graph = graph; + if(bd.getAttribute(nameColumnName)!= null) { + cn.name = bd.getAttribute(nameColumnName).toString(); + } + } + else { + System.out.println("Empty CustomNode Document"); + } + return cn; + } + + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "CustomNode: " + n; + ret += "Key : " + this.key + n; + ret += "name : " + this.name +n; + + return ret; + } + + @Override + public String toString() { + return "CustomNode{" + + "id=" + id + + ", key='" + key + '\'' + + ", graph=" + graph + + ", name='" + name + '\'' + + '}'; + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphCreationLog.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphCreationLog.java index 2a037126..2e5e88aa 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphCreationLog.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphCreationLog.java @@ -3,6 +3,7 @@ import i5.las2peer.services.ocd.utils.ExecutionStatus; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import javax.persistence.Column; @@ -12,6 +13,14 @@ import javax.persistence.GenerationType; import javax.persistence.Id; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.fasterxml.jackson.databind.ObjectMapper; /** * A log representation for a graph creation method, i.e. typically a OcdBenchmark execution. * @author Sebastian @@ -24,9 +33,11 @@ public class GraphCreationLog { * Database column name definitions. */ private static final String idColumnName = "ID"; - private static final String typeColumnName = "TYPE"; - private static final String statusIdColumnName = "STATUS"; + public static final String typeColumnName = "TYPE"; + public static final String statusIdColumnName = "STATUS"; + private static final String parameterColumnName = "PARAMETER"; + public static final String collectionName = "graphcreationlog"; /* * Field names */ @@ -39,6 +50,10 @@ public class GraphCreationLog { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) private long id; + /** + * System generated persistence key. + */ + private String key; /** * Parameters used by the creation method. */ @@ -84,7 +99,15 @@ public GraphCreationLog(GraphCreationType type, Map parameters) public long getId() { return id; } - + + /** + * Returns the log key. + * @return The key. + */ + public String getKey() { + return key; + } + /** * Returns the type of the corresponding creation method. * @return The type. @@ -117,4 +140,62 @@ public void setStatus(ExecutionStatus status) { this.statusId = status.getId(); } + //persistence functions + public void persist(ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(parameterColumnName, this.parameters); + + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public void updateDB(ArangoDatabase db, String transId) { + DocumentUpdateOptions updateOptions = new DocumentUpdateOptions().streamTransactionId(transId); + + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(parameterColumnName, this.parameters); + + collection.updateDocument(this.key, bd, updateOptions); + } + + public static GraphCreationLog load(String key, ArangoDatabase db, DocumentReadOptions opt) { + GraphCreationLog gcl = new GraphCreationLog(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + ObjectMapper om = new ObjectMapper(); + String typeIdString = bd.getAttribute(typeColumnName).toString(); + int typeId = Integer.parseInt(typeIdString); + String statusIdString = bd.getAttribute(statusIdColumnName).toString(); + int statusId = Integer.parseInt(statusIdString); + Object obj = bd.getAttribute(parameterColumnName); + + gcl.typeId = typeId; + gcl.statusId = statusId; + gcl.key = key; + gcl.parameters = om.convertValue(obj, Map.class); + } + else { + System.out.println("Empty Document"); + } + return gcl; + } + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "GraphCreationLog: " + n; + ret += "Key : " + this.key + n; + ret += "typeId : " + this.typeId + n; + ret += "statusId : " + this.statusId + n; + ret += "parameters : " + this.parameters.toString() + n; + return ret; + } + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphProcessor.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphProcessor.java index 4e4aeba1..61c8b9ad 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphProcessor.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/GraphProcessor.java @@ -2,22 +2,17 @@ import i5.las2peer.services.ocd.utils.Pair; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; + +import org.apache.jena.atlas.iterator.Iter;//TODO: why this iterator? i think iterator is already in java.util import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.algo.GraphConnectivity; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; -import y.base.NodeList; +import org.graphstream.algorithm.ConnectedComponents; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + +import java.util.*; /** * Pre-processes graphs to facilitate community detection. @@ -35,32 +30,32 @@ public class GraphProcessor { */ public void determineGraphTypes(CustomGraph graph) { graph.clearTypes(); - EdgeCursor edges = graph.edges(); + Iterator edgesIt = graph.edges().iterator(); Edge edge; Edge reverseEdge; - while (edges.ok()) { - edge = edges.edge(); + while (edgesIt.hasNext()) { + edge = edgesIt.next(); double edgeWeight = graph.getEdgeWeight(edge); - if (edgeWeight != 1) { + if (edgeWeight != 1 && !graph.getTypes().contains(GraphType.WEIGHTED)) { graph.addType(GraphType.WEIGHTED); } - if (edgeWeight == 0) { - graph.addType(GraphType.ZERO_WEIGHTS); + if (edgeWeight == 0 && !graph.getTypes().contains(GraphType.ZERO_WEIGHTS)) { + graph.addType(GraphType.ZERO_WEIGHTS ); } - if (edgeWeight < 0) { + if (edgeWeight < 0 && !graph.getTypes().contains(GraphType.NEGATIVE_WEIGHTS)) { graph.addType(GraphType.NEGATIVE_WEIGHTS); } - if (edge.source().equals(edge.target())) { + if (edge.getSourceNode().equals(edge.getTargetNode()) && !graph.getTypes().contains(GraphType.SELF_LOOPS)) { graph.addType(GraphType.SELF_LOOPS); } - reverseEdge = edge.target().getEdgeTo(edge.source()); - if (reverseEdge == null || graph.getEdgeWeight(reverseEdge) != edgeWeight) { + reverseEdge = edge.getTargetNode().getEdgeToward(edge.getSourceNode()); + if ((reverseEdge == null || graph.getEdgeWeight(reverseEdge) != edgeWeight) && !graph.getTypes().contains(GraphType.DIRECTED)) { graph.addType(GraphType.DIRECTED); } - edges.next(); + } if (graph.getPath() != "" && graph.getPath() != null) { - if (graph.edgeCount() == 0) { + if (graph.getEdgeCount() == 0) { graph.addType(GraphType.CONTENT_UNLINKED); } else @@ -80,25 +75,29 @@ public void determineGraphTypes(CustomGraph graph) { * The graph to be transformed. */ public void makeUndirected(CustomGraph graph) { - EdgeCursor edges = graph.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); - double edgeWeight = graph.getEdgeWeight(edge); + + // copy of the input graph to be used for iteration + CustomGraph graphCopy = new CustomGraph(graph); + + Iterator edges = graphCopy.edges().iterator(); + while (edges.hasNext()) { + Edge edge = edges.next(); + double edgeWeight = graphCopy.getEdgeWeight(edge); Edge reverseEdge; - Node target = edge.target(); - Node source = edge.source(); - reverseEdge = target.getEdgeTo(source); - if (reverseEdge != null && reverseEdge.index() > edge.index() && !target.equals(source)) { - edgeWeight += graph.getEdgeWeight(reverseEdge); - graph.setEdgeWeight(edge, edgeWeight); - graph.setEdgeWeight(reverseEdge, edgeWeight); + Node target = edge.getTargetNode(); + Node source = edge.getSourceNode(); + reverseEdge = target.getEdgeToward(source); + if (reverseEdge != null && reverseEdge.getIndex() > edge.getIndex() && !target.equals(source)) { + graph.combineEdgeWeights(target.getId(), source.getId()); + } else if (reverseEdge == null) { - reverseEdge = graph.createEdge(target, source); + reverseEdge = graph.addEdge(UUID.randomUUID().toString(), target.getId(), source.getId()); graph.setEdgeWeight(reverseEdge, edgeWeight); } - edges.next(); + } graph.removeType(GraphType.DIRECTED); + graph.setNodeEdgeCountColumnFields(); //update graph edge count info } /** @@ -110,11 +109,11 @@ public void makeUndirected(CustomGraph graph) { * The graph to be transformed. */ protected void removeMultiEdges(CustomGraph graph) { - EdgeCursor edges = graph.edges(); + Iterator edgesIt = graph.edges().iterator(); Map, Double> nodePairWeights = new HashMap, Double>(); - while (edges.ok()) { - Edge edge = edges.edge(); - Pair nodePair = new Pair(edge.source().index(), edge.target().index()); + while (edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + Pair nodePair = new Pair(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex()); Double edgeWeight = nodePairWeights.get(nodePair); if (edgeWeight == null) { nodePairWeights.put(nodePair, graph.getEdgeWeight(edge)); @@ -123,15 +122,15 @@ protected void removeMultiEdges(CustomGraph graph) { nodePairWeights.put(nodePair, edgeWeight); graph.removeEdge(edge); } - edges.next(); + } - edges.toFirst(); - while (edges.ok()) { - Edge edge = edges.edge(); + edgesIt = graph.edges().iterator(); + while (edgesIt.hasNext()) { + Edge edge = edgesIt.next(); double edgeWeight = nodePairWeights - .get(new Pair(edge.source().index(), edge.target().index())); + .get(new Pair(edge.getSourceNode().getIndex(), edge.getTargetNode().getIndex())); graph.setEdgeWeight(edge, edgeWeight); - edges.next(); + } } @@ -151,20 +150,30 @@ protected void removeMultiEdges(CustomGraph graph) { */ protected void redefineEdges(CustomGraph graph, boolean noNegativeWeights, boolean noZeroWeights, boolean noSelfLoops, boolean setToOne) { - EdgeCursor edges = graph.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + Iterator edgesIt = graph.edges().iterator(); + + /* + this list will hold edges to be removed. This is needed to avoid edge removal + while iterating over edges to avoid unintended side effects. + */ + ArrayList edgesToRemove = new ArrayList(); + + while (edgesIt.hasNext()) { + Edge edge = edgesIt.next(); double edgeWeight = graph.getEdgeWeight(edge); if (noNegativeWeights && edgeWeight < 0) { - graph.removeEdge(edge); + //graph.removeEdge(edge); + edgesToRemove.add(edge); } else if (noZeroWeights && edgeWeight == 0) { - graph.removeEdge(edge); - } else if (noSelfLoops && edge.source().equals(edge.target())) { - graph.removeEdge(edge); + //graph.removeEdge(edge); + edgesToRemove.add(edge); + } else if (noSelfLoops && edge.getSourceNode().equals(edge.getTargetNode())) { + //graph.removeEdge(edge); + edgesToRemove.add(edge); } else if (setToOne) { graph.setEdgeWeight(edge, 1); } - edges.next(); + } if (noSelfLoops) { graph.removeType(GraphType.SELF_LOOPS); @@ -178,6 +187,13 @@ protected void redefineEdges(CustomGraph graph, boolean noNegativeWeights, boole if (noZeroWeights) { graph.removeType(GraphType.ZERO_WEIGHTS); } + + /* + remove edges that were identified for removal + */ + for (Edge edgeToRemove : edgesToRemove){ + graph.removeEdge(edgeToRemove); + } } /** @@ -193,42 +209,46 @@ public List>> divideIntoConnectedComponents(Cu * Iterates over all connected components of the graph creating a copy * for each of them. */ - NodeList[] componentsArray = GraphConnectivity.connectedComponents(graph); + //TODO: Check usage of connected component algorithm here + //NodeList[] componentsArray = GraphConnectivity.connectedComponents(graph); + ConnectedComponents ccAlgo = new ConnectedComponents(graph); + ccAlgo.compute(); + Iterator componentsIterator = ccAlgo.iterator(); List>> componentsList = new ArrayList>>(); - for (int i = 0; i < componentsArray.length; i++) { - CustomGraph component = new CustomGraph(); + while (componentsIterator.hasNext()) { + ConnectedComponents.ConnectedComponent component = componentsIterator.next(); + CustomGraph componentGraph = new CustomGraph(); Map nodeMap = new HashMap(); Map tmpNodeMap = new HashMap(); /* * Sets component nodes */ - NodeCursor nodes = componentsArray[i].nodes(); - while (nodes.ok()) { - Node originalNode = nodes.node(); - Node newNode = component.createNode(); - component.setNodeName(newNode, graph.getNodeName(originalNode)); + Iterator nodesIt = component.nodes().iterator(); + while (nodesIt.hasNext()) { + Node originalNode = nodesIt.next(); + Node newNode = componentGraph.addNode(component.id + originalNode.getId()); + componentGraph.setNodeName(newNode, graph.getNodeName(originalNode)); nodeMap.put(newNode, originalNode); tmpNodeMap.put(originalNode, newNode); - nodes.next(); + } /* * Sets component edges */ - nodes.toFirst(); - while (nodes.ok()) { - Node node = nodes.node(); - EdgeCursor outEdges = node.outEdges(); - while (outEdges.ok()) { - Edge outEdge = outEdges.edge(); - Node target = outEdge.target(); - Edge newEdge = component.createEdge(tmpNodeMap.get(node), tmpNodeMap.get(target)); + nodesIt = component.nodes().iterator(); + while (nodesIt.hasNext()) { + Node node = nodesIt.next(); + Iterator outEdgesIt = node.leavingEdges().iterator(); + while (outEdgesIt.hasNext()) { + Edge outEdge = outEdgesIt.next(); + Node target = outEdge.getTargetNode(); double edgeWeight = graph.getEdgeWeight(outEdge); - component.setEdgeWeight(newEdge, edgeWeight); - outEdges.next(); + Edge newEdge = componentGraph.addEdge(UUID.randomUUID().toString(),tmpNodeMap.get(node), tmpNodeMap.get(target)); + componentGraph.setEdgeWeight(newEdge, edgeWeight); } - nodes.next(); + } - componentsList.add(new Pair>(component, nodeMap)); + componentsList.add(new Pair>(componentGraph, nodeMap)); } return componentsList; } @@ -250,28 +270,28 @@ public Cover mergeComponentCovers(CustomGraph graph, List> componentCover : componentCovers) { totalCommunityCount += componentCover.getFirst().communityCount(); } - Matrix memberships = new CCSMatrix(graph.nodeCount(), totalCommunityCount); + Matrix memberships = new CCSMatrix(graph.getNodeCount(), totalCommunityCount); Cover currentCover = null; CoverCreationLog algo = new CoverCreationLog(CoverCreationType.UNDEFINED, new HashMap(), new HashSet()); if (!componentCovers.isEmpty()) { algo = componentCovers.get(0).getFirst().getCreationMethod(); } - NodeCursor currentNodes; + Iterator currentNodesIt; Node node; int currentCoverFirstCommunityIndex = 0; double belongingFactor; for (Pair> componentCover : componentCovers) { currentCover = componentCover.getFirst(); - currentNodes = currentCover.getGraph().nodes(); - while (currentNodes.ok()) { - node = currentNodes.node(); + currentNodesIt = currentCover.getGraph().nodes().iterator(); + while (currentNodesIt.hasNext()) { + node = currentNodesIt.next(); for (int i = 0; i < currentCover.communityCount(); i++) { belongingFactor = currentCover.getBelongingFactor(node, i); - memberships.set(componentCover.getSecond().get(node).index(), currentCoverFirstCommunityIndex + i, + memberships.set(componentCover.getSecond().get(node).getIndex(), currentCoverFirstCommunityIndex + i, belongingFactor); } - currentNodes.next(); + } currentCoverFirstCommunityIndex += currentCover.communityCount(); if (!currentCover.getCreationMethod().equals(algo)) { @@ -345,18 +365,18 @@ public void makeCompatible(CustomGraph graph, Set compatibleTypes) { * @author YLi */ public void makeDirected(CustomGraph graph) { - EdgeCursor edges = graph.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); + Iterator edgesIt = graph.edges().iterator(); + while (edgesIt.hasNext()) { + Edge edge = edgesIt.next(); double edgeWeight = graph.getEdgeWeight(edge); Edge reverseEdge; - Node target = edge.target(); - Node source = edge.source(); - if (target.index() > source.index()) { - reverseEdge = graph.createEdge(target, source); + Node target = edge.getTargetNode(); + Node source = edge.getSourceNode(); + if (target.getIndex() > source.getIndex()) { + reverseEdge = graph.addEdge(UUID.randomUUID().toString(), target, source); graph.setEdgeWeight(reverseEdge, edgeWeight); } - edges.next(); + } graph.addType(GraphType.DIRECTED); } @@ -372,20 +392,20 @@ public void makeDirected(CustomGraph graph) { */ public CustomGraph copyGraph(CustomGraph graph) { CustomGraph graphCopy = new CustomGraph(); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); Node t[] = new Node[nodeCount]; for (int i = 0; i < nodeCount; i++) { - t[i] = graphCopy.createNode(); + t[i] = graphCopy.addNode(Integer.toString(i)); } - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; - while (edges.ok()) { - edge = edges.edge(); - int source = edge.source().index(); - int target = edge.target().index(); - Edge newEdge = graphCopy.createEdge(t[source], t[target]); + while (edges.hasNext()) { + edge = edges.next(); + int source = edge.getSourceNode().getIndex(); + int target = edge.getTargetNode().getIndex(); + Edge newEdge = graphCopy.addEdge(UUID.randomUUID().toString(),t[source], t[target]); graphCopy.setEdgeWeight(newEdge, graph.getEdgeWeight(edge)); - edges.next(); + } return graphCopy; } @@ -398,13 +418,12 @@ public CustomGraph copyGraph(CustomGraph graph) { * @author Tobias */ public void invertEdgeWeights(CustomGraph graph) { - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); - while(edges.ok()) { - Edge edge = edges.edge(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1/graph.getEdgeWeight(edge)); - - edges.next(); + } } @@ -416,12 +435,15 @@ public void invertEdgeWeights(CustomGraph graph) { * @author Tobias */ public void reverseEdgeDirections(CustomGraph graph) { - EdgeCursor edges = graph.edges(); - - while(edges.ok()) { - Edge edge = edges.edge(); - graph.reverseEdge(edge); - edges.next(); + Iterator edges = graph.edges().iterator(); + + if (graph.isDirected()) { + while(edges.hasNext()) { + //TODO: Finish edge reversal + Edge edge = edges.next(); + graph.addEdge(UUID.randomUUID().toString(), edge.getTargetNode(), edge.getSourceNode()); + graph.removeEdge(edge); + } } } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/PointEntity.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/PointEntity.java deleted file mode 100644 index 8e42b6a0..00000000 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/PointEntity.java +++ /dev/null @@ -1,83 +0,0 @@ -package i5.las2peer.services.ocd.graphs; - -import javax.persistence.Column; -import javax.persistence.Embeddable; - -import y.geom.YPoint; - -/** - * Represents a point for visualization persistence purposes. - * @author Sebastian - * - */ -@Embeddable -public class PointEntity { - - /** - * The x-coordinate of the point. - */ - @Column - private double x; - - /** - * The y-coordinate of the point. - */ - @Column - private double y; - - /** - * Creates a new instance. - */ - protected PointEntity() { - } - - /** - * Copy constructor. - * @param point The point to copy. - */ - protected PointEntity(YPoint point) { - this.x = point.getX(); - this.y = point.getY(); - } - - /** - * Getter for the x-coordinate. - * @return The x-coordinate. - */ - protected double getX() { - return x; - } - - /** - * Setter for the x-coordinate. - * @param x The x-coordinate. - */ - protected void setX(double x) { - this.x = x; - } - - /** - * Getter for the y-coordinate. - * @return The y-coordinate. - */ - protected double getY() { - return y; - } - - /** - * Setter for the y-coordinate. - * @param y The y-coordinate. - */ - protected void setY(double y) { - this.y = y; - } - - /** - * Creates a YPoint corresponding to the point. - * @return The YPoint. - */ - protected YPoint createPoint() { - return new YPoint(x, y); - } - -} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AbstractProperty.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AbstractProperty.java index 79f1079b..44346aa0 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AbstractProperty.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AbstractProperty.java @@ -8,9 +8,9 @@ */ public abstract class AbstractProperty { - public abstract double calculate(CustomGraph graph); + public abstract double calculate(CustomGraph graph) throws InterruptedException; - public double calculate(Community community) { + public double calculate(Community community) throws InterruptedException { if(community == null) throw new IllegalArgumentException("no community"); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AverageDegree.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AverageDegree.java index b591df83..4d088569 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AverageDegree.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/AverageDegree.java @@ -19,7 +19,7 @@ public double calculate(CustomGraph graph) { if (graph == null) throw new IllegalArgumentException(); - double degree = calculate(graph.nodeCount(), graph.edgeCount()); + double degree = calculate(graph.getNodeCount(), graph.getEdgeCount()); if (!graph.isDirected()) return degree / 2; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficient.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficient.java index 3cf263d5..8ce37af1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficient.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficient.java @@ -1,12 +1,10 @@ package i5.las2peer.services.ocd.graphs.properties; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.algo.GraphConnectivity; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; -import y.base.NodeList; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + +import java.util.*; /** * This class handles the clustering coefficient computation of a CustomGraph. @@ -20,23 +18,24 @@ public class ClusteringCoefficient extends AbstractProperty { * @return the clustering coefficient */ @Override - public double calculate(CustomGraph graph) { + public double calculate(CustomGraph graph) throws InterruptedException { if (graph == null) throw new IllegalArgumentException(); - double[] localClusterings = new double[graph.nodeCount()]; + double[] localClusterings = new double[graph.getNodeCount()]; int nodeId = 0; - for (NodeCursor nc = graph.nodes(); nc.ok(); nc.next()) { - Node node = nc.node(); + Iterator nodeIterator = graph.iterator(); + while(nodeIterator.hasNext()) { + Node node = nodeIterator.next(); localClusterings[nodeId] = calculateLocal(node, graph); nodeId++; } double max = 0; double length = localClusterings.length; - for (int i = 0; i < length; i++) { - max += localClusterings[i]; + for (double localClustering : localClusterings) { + max += localClustering; } return (max / length); @@ -48,22 +47,24 @@ public double calculate(CustomGraph graph) { * * @param node the node * @param graph the containing graph - * @return the local clustering coefficient + * @return the local clustering coefficient + * @throws InterruptedException If the executing thread was interrupted. */ - protected double calculateLocal(Node node, CustomGraph graph) { - - NodeList nodeNeighbours = GraphConnectivity.getNeighbors(graph, new NodeList(node), 1); + protected double calculateLocal(Node node, CustomGraph graph) throws InterruptedException { + //TODO: Check if neighbor and out edge iteration behaves similarly to yFiles here + //GraphConnectivity.getNeighbors(graph, new NodeList(node), 1); + Set nodeNeighbours = graph.getNeighbours(node); int links = 0; - for (NodeCursor outerNodeCursor = nodeNeighbours.nodes(); outerNodeCursor.ok(); outerNodeCursor.next()) { - Node neighbour = outerNodeCursor.node(); - for (EdgeCursor ec = neighbour.outEdges(); ec.ok(); ec.next()) { - Edge edge = ec.edge(); - if (nodeNeighbours.contains(edge.target())) + for(Node neighbour : nodeNeighbours) { + Iterator neighborOutEdgeIt = neighbour.leavingEdges().iterator(); + while (neighborOutEdgeIt.hasNext()) { + Edge edge = neighborOutEdgeIt.next(); + if (nodeNeighbours.contains(edge.getTargetNode())) links++; } } - int degree = node.degree() / 2; + int degree = node.getDegree() / 2; if(graph.isDirected()) return localDirected(links, degree); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviation.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviation.java index 220d6e03..2e1217c8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviation.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviation.java @@ -3,8 +3,9 @@ import org.apache.commons.math3.stat.StatUtils; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + +import java.util.Iterator; /** * This class handles the degree deviation computation of a CustomGraph. @@ -23,14 +24,15 @@ public double calculate(CustomGraph graph) { if (graph == null) throw new IllegalArgumentException(); - double[] degrees = new double[graph.nodeCount()]; + double[] degrees = new double[graph.getNodeCount()]; int nodeId = 0; - for (NodeCursor nc = graph.nodes(); nc.ok(); nc.next()) { - Node node = nc.node(); + Iterator nc = graph.iterator(); + while (nc.hasNext()) { + Node node = nc.next(); if(graph.isDirected()) { - degrees[nodeId] = node.degree(); + degrees[nodeId] = node.getDegree(); } else { - degrees[nodeId] = node.degree() / 2; + degrees[nodeId] = node.getDegree() / 2; } nodeId++; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Density.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Density.java index 9d19b356..3c1be73f 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Density.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Density.java @@ -19,7 +19,7 @@ public double calculate(CustomGraph graph) { if (graph == null) throw new IllegalArgumentException(); - return calculate(graph.nodeCount(), graph.edgeCount()); + return calculate(graph.getNodeCount(), graph.getEdgeCount()); } /** diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/GraphProperty.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/GraphProperty.java index 89e7af9e..43e245bd 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/GraphProperty.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/GraphProperty.java @@ -103,8 +103,9 @@ public static GraphProperty lookupProperty(int id) { * * @param graph CustomGraph * @return property list + * @throws InterruptedException If the executing thread was interrupted. */ - public static List getPropertyList(CustomGraph graph) { + public static List getPropertyList(CustomGraph graph) throws InterruptedException { List properties = new ArrayList<>(size()); for (int i = 0; i < size(); i++) { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Size.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Size.java index f483b727..22fe54d9 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Size.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/graphs/properties/Size.java @@ -19,6 +19,6 @@ public double calculate(CustomGraph graph) { if (graph == null) throw new IllegalArgumentException(); - return graph.nodeCount(); + return graph.getNodeCount(); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/CoverData.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/CoverData.java index a701a96f..ef897658 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/CoverData.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/CoverData.java @@ -7,8 +7,9 @@ import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + +import java.util.Iterator; public class CoverData { @@ -60,19 +61,17 @@ public double avgCommunitySize(Cover cover){ } public Integer[] degreeDist(CustomGraph graph){ - Integer[] r = new Integer[graph.edgeCount()+1]; - NodeCursor nodes = graph.nodes(); - while(nodes.ok()){ - Node n = nodes.node(); - if(r[n.degree()] == null){ - r[n.degree()] = 1; + Integer[] r = new Integer[graph.getEdgeCount()+1]; + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()){ + Node n = nodesIt.next(); + if(r[n.getDegree()] == null){ + r[n.getDegree()] = 1; }else{ - int deg = r[n.degree()]; + int deg = r[n.getDegree()]; deg++; - r[n.degree()] = deg; + r[n.getDegree()] = deg; } - - nodes.next(); } /*for(int i = 0; i < res.size(); i++){ @@ -85,7 +84,7 @@ public Integer[] degreeDist(CustomGraph graph){ } public Integer[] communitySizeDist(Cover cover){ - Integer[] res = new Integer[cover.getGraph().nodeCount()+1]; + Integer[] res = new Integer[cover.getGraph().getNodeCount()+1]; for(int i = 0; i < cover.communityCount(); i++){ if(res[cover.getCommunitySize(i)] == null){ res[cover.getCommunitySize(i)] = 1; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetric.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetric.java index 359b60ce..cac4d184 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetric.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetric.java @@ -1,18 +1,14 @@ package i5.las2peer.services.ocd.metrics; +import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.GraphType; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.vector.Vectors; -import y.base.Graph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** @@ -43,27 +39,24 @@ public Set compatibleGraphTypes() { @Override public double measure(Cover cover) throws InterruptedException { double metricValue = 0; - Graph graph = cover.getGraph(); - NodeCursor nodesA = graph.nodes(); - NodeCursor nodesB = graph.nodes(); + CustomGraph graph = cover.getGraph(); + Iterator nodesA = graph.iterator(); + Iterator nodesB = graph.iterator(); Node nodeA; Node nodeB; - while(nodesA.ok()) { - nodeA = nodesA.node(); - nodesB.toFirst(); - while(nodesB.ok()) { - nodeB = nodesB.node(); - if(nodeB.index() > nodeA.index()) { + while(nodesA.hasNext()) { + nodeA = nodesA.next(); + nodesB = graph.iterator(); + while(nodesB.hasNext()) { + nodeB = nodesB.next(); + if(nodeB.getIndex() > nodeA.getIndex()) { break; } - metricValue += - getNodePairModularityContribution(cover, nodesA.node(), nodesB.node()); - nodesB.next(); + metricValue += getNodePairModularityContribution(cover, nodeA, nodeB); } - nodesA.next(); } - if(graph.edgeCount() > 0) { - metricValue /= graph.edgeCount(); + if(graph.getEdgeCount() > 0) { + metricValue /= graph.getEdgeCount(); } return metricValue; } @@ -92,18 +85,18 @@ private double getEdgeBelongingCoefficient(Cover cover, Node sourceNode, Node ta private double getNullModelContribution(Cover cover, Node nodeA, Node nodeB, int communityIndex) { double coeff = cover.getBelongingFactor(nodeA, communityIndex); coeff *= cover.getBelongingFactor(nodeB, communityIndex); - if(nodeA.index() != nodeB.index()) { - coeff *= nodeA.outDegree() * nodeB.inDegree() + nodeA.inDegree() * nodeB.outDegree(); + if(nodeA.getIndex() != nodeB.getIndex()) { + coeff *= nodeA.getOutDegree() * nodeB.getInDegree() + nodeA.getInDegree() * nodeB.getOutDegree(); } else { - coeff *= nodeA.outDegree() * nodeB.inDegree(); + coeff *= nodeA.getOutDegree() * nodeB.getInDegree(); } if(coeff != 0) { - coeff /= Math.pow(cover.getGraph().nodeCount(), 2); + coeff /= Math.pow(cover.getGraph().getNodeCount(), 2); /* * Edge count cannot be 0 here due to the node degrees. */ - coeff /= cover.getGraph().edgeCount(); + coeff /= cover.getGraph().getEdgeCount(); coeff *= Math.pow(cover.getMemberships().getColumn(communityIndex).fold(Vectors.mkManhattanNormAccumulator()), 2); } return coeff; @@ -124,10 +117,10 @@ private double getNodePairModularityContribution(Cover cover, Node nodeA, Node n throw new InterruptedException(); } double coverContribution = 0; - if(nodeA.getEdgeTo(nodeB) != null) { + if(nodeA.getEdgeToward(nodeB) != null) { coverContribution += getEdgeBelongingCoefficient(cover, nodeA, nodeB, i); } - if(nodeB.getEdgeTo(nodeA) != null) { + if(nodeB.getEdgeToward(nodeA) != null) { coverContribution += getEdgeBelongingCoefficient(cover, nodeB, nodeA, i); } double nullModelContribution = getNullModelContribution(cover, nodeA, nodeB, i); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricCoMembership.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricCoMembership.java index d441be33..c645e78d 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricCoMembership.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricCoMembership.java @@ -1,15 +1,12 @@ package i5.las2peer.services.ocd.metrics; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import i5.las2peer.services.ocd.graphs.CustomGraph; + +import java.util.*; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Graph; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class ExtendedModularityMetricCoMembership implements StatisticalMeasure { @@ -37,24 +34,22 @@ public Set compatibleGraphTypes() { @Override public double measure(Cover cover) throws InterruptedException { double metricValue = 0; - Graph graph = cover.getGraph(); - NodeCursor nodesA = graph.nodes(); - NodeCursor nodesB = graph.nodes(); + CustomGraph graph = cover.getGraph(); + Iterator nodesA = graph.iterator(); + Iterator nodesB = graph.iterator(); Node nodeA; Node nodeB; - while(nodesA.ok()) { - nodeA = nodesA.node(); - nodesB.toFirst(); - while(nodesB.ok()) { - nodeB = nodesB.node(); + while(nodesA.hasNext()) { + nodeA = nodesA.next(); + nodesB = graph.iterator(); + while(nodesB.hasNext()) { + nodeB = nodesB.next(); metricValue += getNodePairModularityContribution(cover, nodeA, nodeB); - nodesB.next(); } - nodesA.next(); } - if(graph.edgeCount() > 0) { - metricValue /= (graph.edgeCount() * 2); + if(graph.getEdgeCount() > 0) { + metricValue /= (graph.getEdgeCount() * 2); } return metricValue; } @@ -75,12 +70,12 @@ private double getNodePairModularityContribution(Cover cover, Node nodeA, Node n } double adjacencyEntry = 0; - if(cover.getGraph().containsEdge(nodeA, nodeB)){ + if(nodeA.hasEdgeBetween(nodeB)){ //TODO: Check this method regarding same behaviour to with yFiles containsEdge, in theory this one should be more correct adjacencyEntry = 1; } - degreeProd = nodeA.inDegree() * nodeB.inDegree(); - edgeCont = (adjacencyEntry - (degreeProd / (cover.getGraph().edgeCount() * 2))); + degreeProd = nodeA.getInDegree() * nodeB.getInDegree(); + edgeCont = (adjacencyEntry - (degreeProd / (cover.getGraph().getEdgeCount() * 2))); cont = edgeCont * coMembership; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedNormalizedMutualInformationMetric.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedNormalizedMutualInformationMetric.java index 24ed2871..d615d9d0 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedNormalizedMutualInformationMetric.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ExtendedNormalizedMutualInformationMetric.java @@ -47,7 +47,7 @@ private double calculateArbitraryConditionalEntropy(Cover cover1, Cover cover2, double communityEntropy; double probability_x0; double probability_x1; - int nodeCount = cover1.getGraph().nodeCount(); + int nodeCount = cover1.getGraph().getNodeCount(); for(int i=0; i edges = graph.edges().iterator(); Edge edge; - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edges.next(); int belongingToSameCommunity = 0; int belongingToDiffCommunity = 0; for (int i = 0; i < communityCount; i++) { - if (membership.get(edge.source().index(), i) * membership.get(edge.target().index(), i) != 0.0) { + if (membership.get(edge.getSourceNode().getIndex(), i) * membership.get(edge.getTargetNode().getIndex(), i) != 0.0) { belongingToSameCommunity++; - } else if (membership.get(edge.source().index(), i) * membership.get(edge.target().index(), i) == 0.0 - & (membership.get(edge.source().index(), i) - + membership.get(edge.target().index(), i)) != 0.0) { + } else if (membership.get(edge.getSourceNode().getIndex(), i) * membership.get(edge.getTargetNode().getIndex(), i) == 0.0 + & (membership.get(edge.getSourceNode().getIndex(), i) + + membership.get(edge.getTargetNode().getIndex(), i)) != 0.0) { belongingToDiffCommunity++; } } @@ -119,7 +115,6 @@ public double measure(Cover cover) throws InterruptedException { */ interEdgePositive++; } - edges.next(); } return (weightingParameter * intraEdgeNegative + (1 - weightingParameter) * interEdgePositive) / effectiveEdges; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ModularityMetric.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ModularityMetric.java index d4b1b473..8569d344 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ModularityMetric.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/ModularityMetric.java @@ -14,8 +14,7 @@ import org.la4j.vector.Vectors; import org.la4j.matrix.Matrix; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Node; /** * Implements the modularity metric. @@ -37,16 +36,16 @@ public Map getParameters() { @Override public double measure(Cover cover) throws OcdMetricException, InterruptedException, OcdAlgorithmException { CustomGraph graph = cover.getGraph(); - int edgeCount = graph.edgeCount()/2; + int edgeCount = graph.getEdgeCount()/2; double modularity = 0; Matrix adjacency = graph.getNeighbourhoodMatrix(); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); - for(int i = 0; i < graph.nodeCount(); i++) { + for(int i = 0; i < graph.getNodeCount(); i++) { Node n1 = nodes[i]; double deg1 = graph.getNeighbours(n1).size(); List com1 = cover.getCommunityIndices(n1); - for(int j = i+1; j < graph.nodeCount(); j++) { + for(int j = i+1; j < graph.getNodeCount(); j++) { Node n2 = nodes[j]; List com2 = cover.getCommunityIndices(n2); com2.retainAll(com1); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/NewmanModularityCombined.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/NewmanModularityCombined.java index 1353046a..c4bcbe63 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/NewmanModularityCombined.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/NewmanModularityCombined.java @@ -1,9 +1,6 @@ package i5.las2peer.services.ocd.metrics; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.commons.math3.linear.ArrayRealVector; @@ -13,8 +10,7 @@ import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; /** * Implements the newman modularity combined with the cosine similarity of each of the nodes. @@ -69,19 +65,19 @@ public double measure(Cover cover) throws InterruptedException, OcdAlgorithmExce Similarities sim = new Similarities(); CustomGraph graph = cover.getGraph(); Termmatrix t = new Termmatrix(graph); - NodeCursor nodesA = graph.nodes(); - NodeCursor nodesB = graph.nodes(); + Iterator nodesA = graph.iterator(); + Iterator nodesB = graph.iterator(); Node nodeA; Node nodeB; int indexA; int indexB; double iteration = 0; - while(nodesA.ok()) { - nodeA = nodesA.node(); - nodesB.toFirst(); + while(nodesA.hasNext()) { + nodeA = nodesA.next(); + nodesB = graph.iterator(); indexA = t.getNodeIdList().indexOf(nodeA); - while(nodesB.ok()) { - nodeB = nodesB.node(); + while(nodesB.hasNext()) { + nodeB = nodesB.next(); indexB = t.getNodeIdList().indexOf(nodeB); if(indexB > indexA){ int coMembership = 0; @@ -97,9 +93,7 @@ public double measure(Cover cover) throws InterruptedException, OcdAlgorithmExce metricValue += (alpha * linkStrength(cover, nodeA, nodeB) + ( 1- alpha) * sim.cosineSim((ArrayRealVector)t.getMatrix().getRowVector(indexA), (ArrayRealVector)t.getMatrix().getRowVector(indexB))) * coMembership; } - nodesB.next(); } - nodesA.next(); } return metricValue/iteration; @@ -115,19 +109,19 @@ private double linkStrength(Cover cover, Node nodeA, Node nodeB){ double adjacencyEntry = 0; - if(cover.getGraph().containsEdge(nodeA, nodeB)){ + if(nodeA.hasEdgeBetween(nodeB)){ //TODO: Check this method regarding same behaviour to with yFiles containsEdge, in theory this one should be more correct adjacencyEntry = 1; } - if(cover.getGraph().edgeCount() != 0){ - degreeProd = nodeA.inDegree() * nodeB.inDegree(); - edgeCont = (adjacencyEntry - (degreeProd / (cover.getGraph().edgeCount() * 2))); + if(cover.getGraph().getEdgeCount() != 0){ + degreeProd = nodeA.getInDegree() * nodeB.getInDegree(); + edgeCont = (adjacencyEntry - (degreeProd / (cover.getGraph().getEdgeCount() * 2))); } cont = edgeCont /* * coMembership*/; - if(cover.getGraph().edgeCount() != 0){ - cont /= (cover.getGraph().edgeCount() * 2); + if(cover.getGraph().getEdgeCount() != 0){ + cont /= (cover.getGraph().getEdgeCount() * 2); } return cont; diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLog.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLog.java index 2b84c38c..8d41a5eb 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLog.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLog.java @@ -1,6 +1,7 @@ package i5.las2peer.services.ocd.metrics; import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.GraphCreationLog; import i5.las2peer.services.ocd.utils.ExecutionStatus; import java.util.HashMap; @@ -17,6 +18,14 @@ import javax.persistence.JoinColumns; import javax.persistence.ManyToOne; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * A log representation for an OcdMetric execution. * @author Sebastian @@ -35,20 +44,30 @@ public class OcdMetricLog { public static final String coverIdColumnName = "COVER_ID"; public static final String graphIdColumnName = "GRAPH_ID"; public static final String graphUserColumnName = "USER_NAME"; - private static final String statusIdColumnName = "STATUS"; + public static final String statusIdColumnName = "STATUS"; + //ArangoDB + public static final String coverKeyColumnName = "COVER_KEY"; + private static final String parameterColumnName = "PARAMETER"; + public static final String collectionName = "ocdmetriclog"; /* * Field names */ public static final String STATUS_ID_FIELD_NAME = "statusId"; + public static final String COVER_FIELD_NAME = "cover"; + public static final String ID_FIELD_NAME = "id"; /** * System generated persistence id. */ + private long id; + /** + * System generated persistence key. + */ @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = idColumnName) - private long id; + private String key = ""; /** * The cover the metric was run on. */ @@ -119,7 +138,15 @@ public OcdMetricLog(OcdMetricType type, double value, Map parame public long getId() { return id; } - + + /** + * Returns the log key. + * @return The key. + */ + public String getKey() { + return key; + } + /** * Returns the type of the corresponding metric. * @return The type. @@ -176,4 +203,80 @@ public Cover getCover() { return cover; } + //persistence functions + public void persist( ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(valueColumnName, this.value); + bd.addAttribute(parameterColumnName, this.parameters); + bd.addAttribute(coverKeyColumnName, this.cover.getKey()); + + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public void updateDB( ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + DocumentUpdateOptions updateOpt = new DocumentUpdateOptions().streamTransactionId(transId); + + BaseDocument bd = new BaseDocument(); + bd.addAttribute(typeColumnName, this.typeId); + bd.addAttribute(statusIdColumnName, this.statusId); + bd.addAttribute(valueColumnName, this.value); + bd.addAttribute(parameterColumnName, this.parameters); + bd.addAttribute(coverKeyColumnName, this.cover.getKey()); + + collection.updateDocument(this.key, bd, updateOpt); + } + + + + public static OcdMetricLog load(String key, Cover cover, ArangoDatabase db, DocumentReadOptions opt) { + OcdMetricLog oml = null; + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + + if (bd != null) { + oml = new OcdMetricLog(); + ObjectMapper om = new ObjectMapper(); + String coverKey = bd.getAttribute(coverKeyColumnName).toString(); + if(!coverKey.equals(cover.getKey())) { + System.out.println("cover with key: " + cover.getKey() + " does not fit to cover with CoverKey: " + coverKey); + return null; + } + Object objParameter = bd.getAttribute(parameterColumnName); + String valueString = bd.getAttribute(valueColumnName).toString(); + String typeIdString = bd.getAttribute(typeColumnName).toString(); + String statusIdString = bd.getAttribute(statusIdColumnName).toString(); + + oml.cover = cover; + if (objParameter != null) { + oml.parameters = om.convertValue(objParameter, Map.class); + } + oml.value = Double.parseDouble(valueString); + oml.typeId = Integer.parseInt(typeIdString); + oml.statusId = Integer.parseInt(statusIdString); + oml.key = key; + } + else { + System.out.println("empty OcdMetricLog document"); + } + return oml; + } + + public String String() { + String n = System.getProperty("line.separator"); + String ret = "OcdMetricLog: " + n; + ret += "Key : " + this.key + n; + if(this.cover != null) {ret += "cover attribut existiert";} + ret += "value : " + this.value +n; + ret += "typeId : " + this.typeId + n; + ret += "statusId : " + this.statusId + n; + ret += "parameters : " + this.parameters.toString() + n; + + return ret; + } + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLogId.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLogId.java index 9e60db3a..4ef334b0 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLogId.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OcdMetricLogId.java @@ -10,9 +10,9 @@ public class OcdMetricLogId { /** - * The specific log id. + * The specific log key. */ - private long id; + private String key; /** * The id of the corresponding cover. @@ -21,11 +21,11 @@ public class OcdMetricLogId { /** * Creates a new instance. - * @param id The log id. + * @param key The log key. * @param coverId The id of the corresponding cover. */ - public OcdMetricLogId(long id, CoverId coverId) { - this.id = id; + public OcdMetricLogId(String key, CoverId coverId) { + this.key = key; this.cover = coverId; } @@ -33,7 +33,7 @@ public OcdMetricLogId(long id, CoverId coverId) { public boolean equals(Object object) { if (object instanceof OcdMetricLogId) { OcdMetricLogId pk = (OcdMetricLogId)object; - return cover.equals(cover) && id == pk.id; + return cover.equals(cover) && key.equals(pk.key); } else { return false; } @@ -41,7 +41,7 @@ public boolean equals(Object object) { @Override public int hashCode() { - return (int)(id + cover.hashCode()); + return (int)(key.hashCode() + cover.hashCode()); } /** @@ -53,11 +53,11 @@ public CoverId getCoverId() { } /** - * Returns the specific log id. + * Returns the specific log key. * @return The id. */ - public long getId() { - return id; + public String getKey() { + return key; } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OmegaIndex.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OmegaIndex.java index b519733e..43c7caa8 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OmegaIndex.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/OmegaIndex.java @@ -2,13 +2,9 @@ import i5.las2peer.services.ocd.graphs.Cover; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class OmegaIndex implements KnowledgeDrivenMeasure { @@ -28,20 +24,20 @@ public double measure(Cover cover, Cover groundTruth) throws OcdMetricException, int pairsInAgreementCount = 0; Map sharedCommunityCountsAlgo = new HashMap(); Map sharedCommunityCountsTruth = new HashMap(); - NodeCursor nodesA = cover.getGraph().nodes(); - NodeCursor nodesB = cover.getGraph().nodes(); + Iterator nodesA = cover.getGraph().iterator(); + Iterator nodesB = cover.getGraph().iterator(); /* * Calculates the number of nodes in agreement and of pairs sharing a given number of communities. */ - while(nodesA.ok()) { - Node nodeA = nodesA.node(); - nodesB.toFirst(); - while(nodesB.ok()) { + while(nodesA.hasNext()) { + Node nodeA = nodesA.next(); + nodesB = cover.getGraph().iterator(); + while(nodesB.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - Node nodeB = nodesB.node(); - if(nodeB.index() < nodeA.index()) { + Node nodeB = nodesB.next(); + if(nodeB.getIndex() < nodeA.getIndex()) { Set pair = new HashSet(); pair.add(nodeA); pair.add(nodeB); @@ -76,14 +72,12 @@ public double measure(Cover cover, Cover groundTruth) throws OcdMetricException, else { break; } - nodesB.next(); } - nodesA.next(); } /* * Calculates the actual omega index. */ - int n = cover.getGraph().nodeCount(); + int n = cover.getGraph().getNodeCount(); int pairsCount = ( n * (n - 1) ) / 2; double unadjustedIndex = 1d / pairsCount * pairsInAgreementCount; double expectedIndex = calculateExpectedIndex(sharedCommunityCountsAlgo, sharedCommunityCountsTruth, pairsCount); @@ -101,21 +95,21 @@ private Map, Integer> getSharedCommunities(Cover cover) throws Interru Integer count; Node nodeA; Node nodeB; - NodeCursor nodesA = cover.getGraph().nodes(); - NodeCursor nodesB = cover.getGraph().nodes(); + Iterator nodesA = cover.getGraph().iterator(); + Iterator nodesB = cover.getGraph().iterator(); for(int i = 0; i 0) { - while(nodesB.ok()) { + while(nodesB.hasNext()) { if(Thread.interrupted()) { throw new InterruptedException(); } - nodeB = nodesB.node(); + nodeB = nodesB.next(); /* * Pairs are regarded only once. */ - if(nodeA.index() <= nodeB.index()) { + if(nodeA.getIndex() <= nodeB.getIndex()) { break; } if(cover.getBelongingFactor(nodeB, i) > 0) { @@ -131,13 +125,11 @@ private Map, Integer> getSharedCommunities(Cover cover) throws Interru } sharedCommunityCounts.put(pair, count); } - nodesB.next(); } } - nodesB.toFirst(); - nodesA.next(); + nodesB = cover.getGraph().iterator(); } - nodesA.toFirst(); + nodesA = cover.getGraph().iterator(); } return sharedCommunityCounts; } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/SignedModularityMetric.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/SignedModularityMetric.java index 251b7cc0..74815e87 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/SignedModularityMetric.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/metrics/SignedModularityMetric.java @@ -4,15 +4,11 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.la4j.matrix.Matrix; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; /** * @author YLi @@ -48,20 +44,20 @@ public double measure(Cover cover) throws InterruptedException { /* * calculate the effective number of edges */ - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edges.next(); double edgeWeight = graph.getEdgeWeight(edge); if (edgeWeight > 0) { positiveWeightSum += edgeWeight; } else if (edgeWeight < 0) { negativeWeightSum += Math.abs(edgeWeight); } - int sameCommunity = examCommunityIdentity(cover, edge.source(), edge.target()); + int sameCommunity = examCommunityIdentity(cover, edge.getSourceNode(), edge.getTargetNode()); if (sameCommunity > 1) { if (edgeWeight > 0) { positiveWeightSum = positiveWeightSum + edgeWeight * (sameCommunity - 1); @@ -69,31 +65,29 @@ public double measure(Cover cover) throws InterruptedException { negativeWeightSum = negativeWeightSum - edgeWeight * (sameCommunity - 1); } } - edges.next(); } /* * Another round of iteration must be carried out, as the effective * number of edges has to be certain for calculation. */ - EdgeCursor edgesMod = graph.edges(); + Iterator edgesMod = graph.edges().iterator(); Edge edgeMod; - while (edgesMod.ok()) { + while (edgesMod.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edgeMod = edgesMod.edge(); + edgeMod = edgesMod.next(); double edgeWeight = graph.getEdgeWeight(edgeMod); - int sameCommunity = examCommunityIdentity(cover, edgeMod.source(), edgeMod.target()); + int sameCommunity = examCommunityIdentity(cover, edgeMod.getSourceNode(), edgeMod.getTargetNode()); metricValue += sameCommunity * (edgeWeight - - (graph.getPositiveInDegree(edgeMod.source()) + graph.getPositiveOutDegree(edgeMod.source())) - * (graph.getPositiveOutDegree(edgeMod.target()) - + graph.getPositiveInDegree(edgeMod.target())) + - (graph.getPositiveInDegree(edgeMod.getSourceNode()) + graph.getPositiveOutDegree(edgeMod.getSourceNode())) + * (graph.getPositiveOutDegree(edgeMod.getTargetNode()) + + graph.getPositiveInDegree(edgeMod.getTargetNode())) / (2 * positiveWeightSum) - + (graph.getNegativeInDegree(edgeMod.source()) + graph.getNegativeOutDegree(edgeMod.source())) - * (graph.getNegativeInDegree(edgeMod.target()) - + graph.getNegativeOutDegree(edgeMod.target())) + + (graph.getNegativeInDegree(edgeMod.getSourceNode()) + graph.getNegativeOutDegree(edgeMod.getSourceNode())) + * (graph.getNegativeInDegree(edgeMod.getTargetNode()) + + graph.getNegativeOutDegree(edgeMod.getTargetNode())) / (2 * negativeWeightSum)); - edgesMod.next(); } return metricValue / (2 * positiveWeightSum + 2 * negativeWeightSum); } @@ -110,12 +104,12 @@ public double measure(Cover cover) throws InterruptedException { * @return The number of communities node A and node B both belong to. * */ - private int examCommunityIdentity(Cover cover, Node nodeA, Node nodeB) throws InterruptedException { + private int examCommunityIdentity(Cover cover, Node sourceNode, Node targetNode) throws InterruptedException { int sameCommunity = 0; Matrix membershipMatrix = cover.getMemberships(); int communityCount = cover.communityCount(); for (int i = 0; i < communityCount; i++) { - if (membershipMatrix.get(nodeA.index(), i) > 0 & membershipMatrix.get(nodeB.index(), i) > 0) { + if (membershipMatrix.get(sourceNode.getIndex(), i) > 0 & membershipMatrix.get(targetNode.getIndex(), i) > 0) { sameCommunity++; } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/AlgorithmRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/AlgorithmRunnable.java index 84daafe5..209992e2 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/AlgorithmRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/AlgorithmRunnable.java @@ -55,31 +55,31 @@ public void run() { /* * Set algorithm state to running. */ - CustomGraphId graphId = new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()); - CoverId id = new CoverId(cover.getId(), graphId); + String cKey = cover.getKey(); + String gKey = cover.getGraph().getKey(); + String user = cover.getGraph().getUserName(); + CustomGraphId graphId = new CustomGraphId(gKey, user); + CoverId coverId = new CoverId(cKey, graphId); + RequestHandler requestHandler = new RequestHandler(); - EntityHandler entityHandler = new EntityHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + + Database database = new Database(false); try { - tx.begin(); - Cover cover = em.find(Cover.class, id); - if(cover == null) { + Cover c = database.getCover(user, gKey, cKey); + if(c == null) { + //System.out.println("Cover in AR run was null " + user + gKey + cKey); /* * Should not happen. */ requestHandler.log(Level.SEVERE, "Cover deleted while algorithm running."); throw new IllegalStateException(); } - cover.getCreationMethod().setStatus(ExecutionStatus.RUNNING); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + c.getCreationMethod().setStatus(ExecutionStatus.RUNNING); + database.updateCoverCreationLog(c); + } catch( Exception e ) { error = true; } - em.close(); + /* * Run algorithm. */ @@ -100,7 +100,8 @@ public void run() { error = true; } } - threadHandler.createCover(resultCover, id, error); + threadHandler.createCover(resultCover, coverId, error); + } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralityAlgorithmRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralityAlgorithmRunnable.java index 1c90465c..66a7bc07 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralityAlgorithmRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralityAlgorithmRunnable.java @@ -29,10 +29,7 @@ public class CentralityAlgorithmRunnable implements Runnable { * The thread handler in charge of the runnable execution. */ private ThreadHandler threadHandler; - /** - * The entity handler in charge of accessing persisted data. - */ - private EntityHandler entityHandler = new EntityHandler(); + /** * Creates a new instance. @@ -52,30 +49,35 @@ public void run() { /* * Set algorithm state to running. */ - CustomGraphId graphId = new CustomGraphId(map.getGraph().getId(), map.getGraph().getUserName()); - CentralityMapId id = new CentralityMapId(map.getId(), graphId); + String mKey = map.getKey(); + String gKey = map.getGraph().getKey(); + String user = map.getGraph().getUserName(); + CustomGraphId graphId = new CustomGraphId(gKey, user); + //System.out.println("Map Key : " + mKey + " gKey: " + gKey); + CentralityMapId id = new CentralityMapId(mKey, graphId); + RequestHandler requestHandler = new RequestHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + + Database database = new Database(false); try { - tx.begin(); - CentralityMap map = em.find(CentralityMap.class, id); - if(map == null) { + CentralityMap m = database.getCentralityMap(user, gKey, mKey); + if(m == null) { /* * Should not happen. */ + System.out.println("Centrality map deleted while algorithm running."); requestHandler.log(Level.SEVERE, "Centrality map deleted while algorithm running."); throw new IllegalStateException(); } - map.getCreationMethod().setStatus(ExecutionStatus.RUNNING); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + //System.out.println("CAR set status to running"); + m.getCreationMethod().setStatus(ExecutionStatus.RUNNING); + database.updateCentralityCreationLog(m); + } catch(RuntimeException e ) { error = true; + e.printStackTrace(); + } - em.close(); + /* * Run algorithm. */ diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralitySimulationRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralitySimulationRunnable.java index 18fd3c9d..830e5d90 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralitySimulationRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/CentralitySimulationRunnable.java @@ -28,7 +28,7 @@ public class CentralitySimulationRunnable implements Runnable { /** * The entity handler in charge of accessing persisted data. */ - private EntityHandler entityHandler = new EntityHandler(); + /** * Creates a new instance. @@ -48,30 +48,33 @@ public void run() { /* * Set simulation state to running. */ - CustomGraphId graphId = new CustomGraphId(map.getGraph().getId(), map.getGraph().getUserName()); - CentralityMapId id = new CentralityMapId(map.getId(), graphId); + String mKey = map.getKey(); + String gKey = map.getGraph().getKey(); + String user = map.getGraph().getUserName(); + CustomGraphId graphId = new CustomGraphId(gKey, user); + CentralityMapId id = new CentralityMapId(mKey, graphId); + RequestHandler requestHandler = new RequestHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + + Database database = new Database(false); try { - tx.begin(); - CentralityMap map = em.find(CentralityMap.class, id); - if(map == null) { + CentralityMap m = database.getCentralityMap(user, gKey, mKey); + if(m == null) { /* * Should not happen. */ + System.out.println("Centrality map deleted while simulation running."); requestHandler.log(Level.SEVERE, "Centrality map deleted while simulation running."); throw new IllegalStateException(); } - map.getCreationMethod().setStatus(ExecutionStatus.RUNNING); - tx.commit(); + m.getCreationMethod().setStatus(ExecutionStatus.RUNNING); + database.updateCentralityCreationLog(m); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + + e.printStackTrace(); error = true; } - em.close(); + /* * Run simulation. */ diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/Database.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/Database.java new file mode 100644 index 00000000..40d7dce5 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/Database.java @@ -0,0 +1,1800 @@ +package i5.las2peer.services.ocd.utils; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Properties; +import java.util.logging.Level; + +import javax.persistence.EntityManager; +import javax.persistence.EntityTransaction; +import javax.persistence.TypedQuery; + +import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; + +import i5.las2peer.services.ocd.centrality.data.CentralityMeta; +import i5.las2peer.services.ocd.cooperation.data.simulation.*; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import i5.las2peer.services.ocd.metrics.OcdMetricLogId; +import i5.las2peer.logging.L2pLogger; +import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; +import i5.las2peer.services.ocd.centrality.data.CentralityMap; +import i5.las2peer.services.ocd.centrality.data.CentralityMapId; +import i5.las2peer.services.ocd.graphs.*; + + +import com.arangodb.ArangoDB; +import com.arangodb.ArangoDatabase; +import com.arangodb.DbName; +import com.arangodb.ArangoCollection; +import com.arangodb.mapping.ArangoJack; +import com.arangodb.entity.BaseDocument; +import com.arangodb.entity.CollectionType; +import com.arangodb.entity.StreamTransactionEntity; +import com.arangodb.model.AqlQueryOptions; +import com.arangodb.model.CollectionCreateOptions; +import com.arangodb.model.StreamTransactionOptions; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentDeleteOptions; +import com.arangodb.ArangoCursor; + + +import com.fasterxml.jackson.databind.ObjectMapper; + + +import java.io.File; +import java.io.IOException; + + +import org.apache.commons.io.FileUtils; + + +public class Database { + + /** + * l2p logger + */ + private final static L2pLogger logger = L2pLogger.getInstance(Database.class.getName()); + + private static final DatabaseConfig DBC = new DatabaseConfig(); + private static String HOST; + private static int PORT; + private static String USER; + private static String PASSWORD; + public static String DBNAME_STRING; + private static DbName DBNAME; + private ArangoDB arangoDB; + public ArangoDatabase db; + + private List collectionNames =new ArrayList(13); + + + public Database(boolean testDB) { + Properties props = DBC.getConfigProperties(); + HOST = props.getProperty("HOST"); + String port = props.getProperty("PORT"); + PORT = Integer.parseInt(props.getProperty("PORT")); + USER = props.getProperty("USER"); + PASSWORD = props.getProperty("PASSWORD"); + if(!testDB) { + DBNAME_STRING = props.getProperty("DATABASENAME"); + }else{ + DBNAME_STRING = props.getProperty("TESTDATABASENAME"); + } + DBNAME = DbName.of(DBNAME_STRING); + arangoDB = new ArangoDB.Builder() + .host(HOST, PORT) + .user(USER) + .password(PASSWORD).serializer(new ArangoJack()).build(); + db = arangoDB.db(DBNAME); + init(); + } + + public void init() { + createDatabase(); + createCollections(); + } + + public void createDatabase() { + if(!db.exists()) { + System.out.println("Creating database..."); + db.create(); + } + } + + public void deleteDatabase() { + if(db.exists()) { + db.drop(); + System.out.println("The database " + db.dbName() + " was deleted"); + } + else { + System.out.println("No database was deleted"); + } + } + + public void createCollections() { + ArangoCollection collection; + collectionNames.add(CustomGraph.collectionName); //0 + collection = db.collection(CustomGraph.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(CustomNode.collectionName); //1 + collection = db.collection(CustomNode.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(CustomEdge.collectionName); //2 + collection = db.collection(CustomEdge.collectionName); + if(!collection.exists()) { + db.createCollection(CustomEdge.collectionName, new CollectionCreateOptions().type(CollectionType.EDGES)); + } + collectionNames.add(GraphCreationLog.collectionName); //3 + collection = db.collection(GraphCreationLog.collectionName); + if(!collection.exists()) { + collection.create(); + } + + collectionNames.add(Cover.collectionName); //4 + collection = db.collection(Cover.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(CoverCreationLog.collectionName); //5 + collection = db.collection(CoverCreationLog.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(OcdMetricLog.collectionName); //6 + collection = db.collection(OcdMetricLog.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(Community.collectionName); //7 + collection = db.collection(Community.collectionName); + if(!collection.exists()) { + collection.create(); + } + + collectionNames.add(CentralityMap.collectionName); //8 + collection = db.collection(CentralityMap.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(CentralityCreationLog.collectionName);//9 + collection = db.collection(CentralityCreationLog.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(InactivityData.collectionName); //10 + collection = db.collection(InactivityData.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(SimulationSeries.collectionName); //11 + collection = db.collection(SimulationSeries.collectionName); + if(!collection.exists()) { + collection.create(); + } + collectionNames.add(SimulationSeriesGroup.collectionName); //12 + collection = db.collection(SimulationSeriesGroup.collectionName); + if(!collection.exists()) { + collection.create(); + } + + } + + + + + //////////////////////////////////////////////////////////////////// GRAPHS /////////////////////////////////////////////////////////////////// + + /** + * Persists a CustomGraph + * + * @param graph + * CustomGraph + * @return persistence key of the stored graph + */ + public String storeGraph(CustomGraph graph) { + String transId = getTransactionId(CustomGraph.class, true); + try { + graph.persist(db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + e.printStackTrace(); + } + return graph.getKey(); + } + + /** + * Updates a persisted graph by updating Attributes,nodes,edges and creationMethod + * does NOT update changes in the covers or CentralityMaps that run on the given graph + * + * @param graph + * the graph + */ + public void updateGraph(CustomGraph graph) { //existenz des graphen muss bereits herausgefunden worden sein TESTEN + graph.setNodeEdgeCountColumnFields(); //before persisting to db, update node/edge count information + String transId = this.getTransactionId(CustomGraph.class, true); + try { + graph.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + e.printStackTrace(); + } + } + + /** + * Updates only the GraphCreationLog of a given graph + * mainly used for setting the status of the log + * + * @param graph + * the graph + */ + public void updateGraphCreationLog(CustomGraph graph) { + String transId = this.getTransactionId(GraphCreationLog.class, true); + try { + graph.getCreationMethod().updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + private CustomGraph getGraph(String key) { + String transId = getTransactionId(CustomGraph.class, false); + CustomGraph graph; + try { + graph = CustomGraph.load(key, db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return graph; + } + + /** + * Returns a persisted CustomGraph if it has the right username + * + * @param username + * owner of the graph + * @param key + * key of the graph + * @return the found CustomGraph instance or null if the CustomGraph does not exists or the username is wrong + */ + public CustomGraph getGraph(String username, String key) { + CustomGraph g = getGraph(key); + + if (g == null) { + logger.log(Level.WARNING, "user: " + username + " Graph does not exist: graph key " + key); + } + else if(!username.equals(g.getUserName())) { + logger.log(Level.WARNING, "user: " + username + " is not allowed to use Graph: " + key + " with user: " + g.getUserName()); + g = null; + } + + return g; + } + + /** + * Return all graphs of a user + * + * @param username + * graphs owner + * @return graph list + */ + public List getGraphs(String username) { + String transId = getTransactionId(CustomGraph.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR g IN " + CustomGraph.collectionName + " FILTER g." + CustomGraph.userColumnName + " == @username RETURN g._key"; + Map bindVars = Collections.singletonMap("username",username); + ArangoCursor graphKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : graphKeys) { + queryResults.add(CustomGraph.load(key, db, transId)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + + return queryResults; + } + + /** + * Return specified graphs' meta information of a user using an efficient approach. This approach only necessary + * metadata about graphs. E.g. no information about nodes/edges (other than their count) is loaded. + * + * @param username + * the users username + * @param firstIndex + * id of the first graph + * @param length + * number of graphs + * @param executionStatusIds + * the execution status ids of the graphs + * @return the list of graphs + */ + public ArrayList getGraphMetaDataEfficiently(String username, int firstIndex, int length, + List executionStatusIds){ + String transId = getTransactionId(CustomGraph.class, false); + ObjectMapper objectMapper = new ObjectMapper(); // needed to instantiate CustomGraphMeta from JSON + ArrayList customGraphMetas = new ArrayList(); + + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR g IN " + CustomGraph.collectionName + " FOR gcl IN " + GraphCreationLog.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @username AND gcl._key == g." + CustomGraph.creationMethodKeyColumnName + + " AND gcl." + GraphCreationLog.statusIdColumnName +" IN " + + executionStatusIds + " LIMIT " + firstIndex + "," + length + " RETURN "+ + "{\"key\" : g._key," + + "\"userName\" : g." + CustomGraph.userColumnName + "," + + "\"name\" : g." + CustomGraph.nameColumnName + "," + + "\"nodeCount\" : g." + CustomGraph.nodeCountColumnName + "," + + "\"edgeCount\" : g." + CustomGraph.edgeCountColumnName + "," + + "\"types\" : g." + CustomGraph.typesColumnName + "," + + "\"creationTypeId\" : gcl." + GraphCreationLog.typeColumnName + "," + + "\"creationStatusId\" : gcl." + GraphCreationLog.statusIdColumnName + "}"; + + Map bindVars = Collections.singletonMap("username",username); + ArangoCursor customGraphMetaJson = db.query(queryStr, bindVars, queryOpt, String.class); + + /* Create CustomGraphMeta instances based on the queried results and add them to the list to return */ + while(customGraphMetaJson.hasNext()) { + /* Instantiate CustomGraphMeta from the json string acquired from a query. + Then add it to the list that will be returned*/ + customGraphMetas.add(objectMapper.readValue(customGraphMetaJson.next(), CustomGraphMeta.class)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + e.printStackTrace(); + } + return customGraphMetas; + } + + + /** + * Return a list of specific graphs of a user + * + * @param username + * the users username + * @param firstIndex + * id of the first graph + * @param length + * number of graphs + * @param executionStatusIds + * the execution status ids of the graphs + * @return the list of graphs + */ + public List getGraphs(String username, int firstIndex, int length, List executionStatusIds) { + String transId = getTransactionId(CustomGraph.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR g IN " + CustomGraph.collectionName + " FOR gcl IN " + GraphCreationLog.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @username AND gcl._key == g." + CustomGraph.creationMethodKeyColumnName + + " AND gcl." + GraphCreationLog.statusIdColumnName +" IN " + + executionStatusIds + " LIMIT " + firstIndex + "," + length + " RETURN g._key"; + Map bindVars = Collections.singletonMap("username",username); + ArangoCursor graphKeys = db.query(queryStr, bindVars, queryOpt, String.class); + while(graphKeys.hasNext()) { + String key = graphKeys.next(); + queryResults.add(CustomGraph.load(key, db, transId)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return queryResults; + } + + + + /** + * Return all graphs with the right name + * + * @param name + * graphs name + * @return graph list + */ + public List getGraphsbyName(String name) { + String transId = getTransactionId(CustomGraph.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR g IN " + CustomGraph.collectionName + " FILTER g." + CustomGraph.nameColumnName + " == @name RETURN g._key"; + Map bindVars = Collections.singletonMap("name",name); + ArangoCursor graphKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : graphKeys) { + queryResults.add(CustomGraph.load(key, db, transId)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + + return queryResults; + } + + + private void deleteGraph(String key) { + String transId = this.getTransactionId(null, true); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + try { + ArangoCollection graphCollection = db.collection(CustomGraph.collectionName); + BaseDocument bd = graphCollection.getDocument(key, BaseDocument.class, readOpt); + String gclKey = bd.getAttribute(CustomGraph.creationMethodKeyColumnName).toString(); + + ArangoCollection gclCollection = db.collection(GraphCreationLog.collectionName); + gclCollection.deleteDocument(gclKey, null, deleteOpt); //delete the GraphCreationLog + String query = "FOR n IN " + CustomNode.collectionName + " FILTER n." +CustomNode.graphKeyColumnName + + " == \"" + key +"\" REMOVE n IN " + CustomNode.collectionName; + db.query(query, queryOpt, BaseDocument.class); //delete all nodes + + query = "FOR e IN " + CustomEdge.collectionName + " FILTER e." + CustomEdge.graphKeyColumnName + + " == \"" + key +"\" REMOVE e IN " + CustomEdge.collectionName; + db.query(query, queryOpt, BaseDocument.class); //delete all edges + + /////////////THIS PART SHOULD NOT BE NEEDED BUT ASSURES NO COVER OR CENTRALITY MAP IS MISSED///////////// + query = "FOR c IN " + Cover.collectionName + " FILTER c." + Cover.graphKeyColumnName + + " == \"" + key +"\" RETURN c._key"; + ArangoCursor coverKeys = db.query(query, queryOpt, String.class); + for(String coverKey : coverKeys) { //delete all covers should not be used + deleteCover(coverKey, transId); + } + + query = "FOR cm IN " + CentralityMap.collectionName + " FILTER cm." + CentralityMap.graphKeyColumnName + + " == \"" + key +"\" RETURN cm._key"; + ArangoCursor centralityMapKeys = db.query(query, queryOpt, String.class); + for(String mapKey : centralityMapKeys) { //delete all centrality Maps should not be used + deleteCentralityMap(mapKey, transId); + } + + query = "FOR ss IN " + SimulationSeries.collectionName + " FILTER ss." + SimulationSeries.graphKeyName + + " == \"" + key +"\" RETURN ss._key"; + ArangoCursor seriesKeys = db.query(query, queryOpt, String.class); + for(String seriesKey : seriesKeys) { + deleteSimulationSeries(seriesKey, transId); + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + graphCollection.deleteDocument(key, null, deleteOpt); //delete the graph + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + + /** + * Deletes a CustomGraph from the database + * + * @param username + * owner of the graph + * @param graphKey + * key of the graph + * @param threadHandler + * the threadhandler + * @throws Exception if cover deletion failed + */ + public void deleteGraph(String username, String graphKey, ThreadHandler threadHandler) throws Exception { //SC + CustomGraphId id = new CustomGraphId(graphKey, username); + + synchronized (threadHandler) { + threadHandler.interruptBenchmark(id); + + List coverList = getCovers(username, graphKey); + for (Cover cover : coverList) { + try { + deleteCover(cover, threadHandler); + } catch (Exception e) { + throw e; + } + } + + List centralityMapList = getCentralityMaps(username, graphKey); + for (CentralityMap map : centralityMapList) { + try { + deleteCentralityMap(map, threadHandler); + } catch (Exception e) { + throw e; + } + } + + try { + CustomGraph graph = getGraph(username, graphKey); + + if(graph.getPath() != "" && graph.getPath() != null) { // Delete index folder if graph is content graph + File file = new File(graph.getPath()); + FileUtils.deleteDirectory(file); + } + deleteGraph(graphKey); + + } catch (IOException e) { + throw new RuntimeException("Could not delete folder of content graph"); + } catch(Exception e) { + throw e; + } + } + + } + + + //////////////////////////////////////////////////////////////// COVERS /////////////////////////////////////////////////////// + public String storeCover(Cover cover) { + String transId = this.getTransactionId(Cover.class, true); + try { + cover.persist(db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return cover.getKey(); + } + + private Cover getCover(String key, CustomGraph g) { + String transId = this.getTransactionId(Cover.class, false); + Cover cover; + try { + cover = Cover.load(key, g, db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return cover; + } + + /** + * Get a stored community-cover of a graph by its coverKey + * + * @param username + * the name of the user + * @param graphKey + * key of the graph + * @param coverKey + * key of the cover + * @return the found Cover instance or null if the Cover does not exist + */ + public Cover getCover(String username, String graphKey, String coverKey) { + CustomGraph graph = getGraph(username, graphKey); + Cover cover = null; + if(!(graph == null)) { + cover = getCover(coverKey, graph); + } + if (cover == null) { + logger.log(Level.WARNING, + "user: " + username + ", " + "Cover does not exist: cover id " + coverKey + ", graph id " + graphKey); + } + return cover; + } + + public List getCoversByName(String name, CustomGraph g){ + String transId = getTransactionId(Cover.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR c IN " + Cover.collectionName + " FILTER c." + Cover.nameColumnName + " == @name RETURN c._key"; + Map bindVars = Collections.singletonMap("name",name); + ArangoCursor coverKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : coverKeys) { + queryResults.add(Cover.load(key, g, db, transId)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + + return queryResults; + } + + /** + * Returns all Covers corresponding to a CustomGraph + * + * @param username + * owner of the graph + * @param graphKey + * key of the graph + * @return cover list + */ + public List getCovers(String username, String graphKey) { //TODO testen + CustomGraph g = getGraph(username, graphKey); + String transId = getTransactionId(Cover.class, false); + List covers = new ArrayList(); + if(g == null) { + return covers; + } + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR c IN " + Cover.collectionName + " FILTER c." + Cover.graphKeyColumnName + " == @key RETURN c._key"; + Map bindVars = Collections.singletonMap("key", graphKey); + ArangoCursor coverKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : coverKeys) { + Cover cover = Cover.load(key, g, db, transId); + if(cover!= null) { + covers.add(cover); + } + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return covers; + } + + /** + * @param username + * the name of the user + * @param graphKey + * the key of the graph + * @param executionStatusIds + * the ids of the execution statuses + * @param metricExecutionStatusIds + * the ids of the metric execution statuses + * @param firstIndex + * the first index + * @param length + * the length of the result set + * @return a cover list + */ + public List getCovers(String username, String graphKey, List executionStatusIds, + List metricExecutionStatusIds, int firstIndex, int length) { + String transId = getTransactionId(null, false); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + + List covers = new ArrayList(); + Map graphMap = new HashMap(); + Set graphKeySet = new HashSet(); + try { + ArangoCollection coverColl = db.collection(Cover.collectionName); + Map bindVars; + String queryStr = " FOR c IN " + Cover.collectionName + " FOR a IN " + CoverCreationLog.collectionName + + " FILTER c." + Cover.creationMethodKeyColumnName + " == a._key AND a." + CoverCreationLog.statusIdColumnName + " IN " + executionStatusIds; + if (metricExecutionStatusIds != null && metricExecutionStatusIds.size() > 0) { + queryStr += " FOR m IN " + OcdMetricLog.collectionName + " FILTER m." + OcdMetricLog.coverKeyColumnName + " == c._key AND " +"m." + + OcdMetricLog.statusIdColumnName + " IN " + metricExecutionStatusIds; + } + if(!graphKey.equals("")) { //es gibt einen graphKey + queryStr += " AND c." + Cover.graphKeyColumnName + " == @gKey"; + bindVars = Collections.singletonMap("gKey", graphKey); + } + else { //es gibt keinen graphKey + queryStr += " FOR g IN " + CustomGraph.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @user AND c." + Cover.graphKeyColumnName + " == g._key"; + bindVars = Collections.singletonMap("user", username); + } + queryStr += " LIMIT " + firstIndex + ", " + length + " RETURN DISTINCT c._key"; + + ArangoCursor coverKeys = db.query(queryStr, bindVars, queryOpt, String.class); + List keyList = coverKeys.asListRemaining(); + + //insert graphkeys to set to ensure no graphs appear more than one time + for (String cKey : keyList) { + BaseDocument bd = coverColl.getDocument(cKey, BaseDocument.class, readOpt); + String gKey = bd.getAttribute(Cover.graphKeyColumnName).toString(); + graphKeySet.add(gKey); + } + if(graphKeySet.size()==1) { + CustomGraph g = CustomGraph.load(graphKeySet.iterator().next(), db, transId); + if(username.equals(g.getUserName())) { + for(String cKey : keyList) { + covers.add(Cover.load(cKey, g, db, transId)); + } + } + } + else { //load cover with associated graph + for(String gk : graphKeySet) { + graphMap.put(gk, CustomGraph.load(gk, db, transId)); + + } + + for(String cKey : keyList) { + BaseDocument bd = coverColl.getDocument(cKey, BaseDocument.class, readOpt); + String gKey = bd.getAttribute(Cover.graphKeyColumnName).toString(); + CustomGraph g = graphMap.get(gKey); + covers.add(Cover.load(cKey, g, db, transId)); + } + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + System.out.println("transaction abort"); + throw e; + } + + return covers; + } + + /** + * Returns metadata of covers efficiently, without loading full cover. + * + * @param username + * the name of the user + * @param graphKey + * the key of the graph + * @param executionStatusIds + * the ids of the execution statuses + * @param metricExecutionStatusIds + * the ids of the metric execution statuses + * @param firstIndex + * the first index + * @param length + * the length of the result set + * @return a cover list + */ + public List getCoverMetaDataEfficiently(String username, String graphKey, List executionStatusIds, + List metricExecutionStatusIds, int firstIndex, int length) { + String transId = getTransactionId(null, false); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + + //List covers = new ArrayList(); + Map graphMap = new HashMap(); + Set graphKeySet = new HashSet(); + ObjectMapper objectMapper = new ObjectMapper(); // needed to instantiate Covereta from JSON + ArrayList coverMetas = new ArrayList(); + + try { + ArangoCollection coverColl = db.collection(Cover.collectionName); + Map bindVars; + String queryStr = " FOR c IN " + Cover.collectionName + " FOR a IN " + CoverCreationLog.collectionName + + " FILTER c." + Cover.creationMethodKeyColumnName + " == a._key AND a." + CoverCreationLog.statusIdColumnName + " IN " + executionStatusIds; +// if (metricExecutionStatusIds != null && metricExecutionStatusIds.size() > 0) { +// queryStr += " FOR m IN " + OcdMetricLog.collectionName + " FILTER m." + OcdMetricLog.coverKeyColumnName + " == c._key AND " +"m." + +// OcdMetricLog.statusIdColumnName + " IN " + metricExecutionStatusIds; +// } + if(!graphKey.equals("")) { //es gibt einen graphKey + queryStr += " FOR g IN " + CustomGraph.collectionName + +" FILTER c." + Cover.graphKeyColumnName + " == @gKey AND g._key == @gKey"; + bindVars = Collections.singletonMap("gKey", graphKey); + } + else { //es gibt keinen graphKey + queryStr += " FOR g IN " + CustomGraph.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @user AND c." + Cover.graphKeyColumnName + " == g._key"; + bindVars = Collections.singletonMap("user", username); + } + queryStr += " LIMIT " + firstIndex + ", " + length + " RETURN " + + "{\"key\" : c._key," + + "\"name\" : c." + Cover.nameColumnName + "," + + "\"numberOfCommunities\" : c." + Cover.numberOfCommunitiesColumnName + "," + + "\"graphKey\" : g._key," + + "\"graphName\" : g." + CustomGraph.nameColumnName + "," + + "\"creationTypeId\" : a." + CoverCreationLog.typeColumnName + "," + + "\"creationStatusId\" : a." + GraphCreationLog.statusIdColumnName + + "}"; + + ArangoCursor coverMetaJson = db.query(queryStr, bindVars, queryOpt, String.class); + while(coverMetaJson.hasNext()) { + /* Instantiate CustomGraphMeta from the json string acquired from a query. + Then add it to the list that will be returned*/ + coverMetas.add(objectMapper.readValue(coverMetaJson.next(), CoverMeta.class)); + + } + + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + System.out.println("transaction abort"); + e.printStackTrace(); + } + + return coverMetas; + } + + + + /** + * used for test purposes + * + * @return list of all covers + */ + public List getAllCoverKeys() { + String transId = getTransactionId(Cover.class, false); + List covers = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR c IN " + Cover.collectionName + " RETURN c._key"; + ArangoCursor coverKeys = db.query(queryStr, queryOpt, String.class); + for(String key : coverKeys) { + covers.add(key); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return covers; + } + + /** + * Updates a persisted cover by updateing attributes, creation and metric logs + * and deleting and restoring the communitys + * + * @param cover + * the cover + */ + public void updateCover(Cover cover) { + String transId = this.getTransactionId(Cover.class, true); + try { + cover.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + /** + * Updates only the CoverCreationLog of a given cover + * mainly used for setting the status of the log + * + * @param cover + * the cover + */ + public void updateCoverCreationLog(Cover cover) { + String transId = this.getTransactionId(CoverCreationLog.class, true); + try { + cover.getCreationMethod().updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + private void deleteCover(String key, String transId) { //Always use it inside a transaction + ArangoCollection coverCollection = db.collection(Cover.collectionName); + ArangoCollection cclCollection = db.collection(CoverCreationLog.collectionName); + + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + BaseDocument coverDoc = coverCollection.getDocument(key, BaseDocument.class, readOpt); + + ObjectMapper om = new ObjectMapper(); + Object objCommunityKeys = coverDoc.getAttribute(Cover.communityKeysColumnName); + List communityKeys = om.convertValue(objCommunityKeys, List.class); + for(String communityKey : communityKeys) { //delete all communitys + ArangoCollection communityCollection = db.collection(Community.collectionName); + communityCollection.deleteDocument(communityKey, null, deleteOpt); + } + String queryStr = "FOR m IN " + OcdMetricLog.collectionName + " FILTER m." + OcdMetricLog.coverKeyColumnName + + " == @cKey REMOVE m IN " + OcdMetricLog.collectionName; + Map bindVars = Collections.singletonMap("cKey", key); + db.query(queryStr, bindVars, queryOpt, String.class); //delete all OcdMetricLogs + + String creationMethodKey = coverDoc.getAttribute(Cover.creationMethodKeyColumnName).toString(); + cclCollection.deleteDocument(creationMethodKey, null, deleteOpt); //delete CoverCreationLog + coverCollection.deleteDocument(key, null, deleteOpt); //delete Cover + } + + private void deleteCover(String key) { + String transId = this.getTransactionId(Cover.class, true); + try { + deleteCover(key, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + /** + * Deletes a persisted cover from the database + * + * @param cover + * the cover + * @param threadHandler + * the threadhandler + */ + private void deleteCover(Cover cover, ThreadHandler threadHandler) { //TODO tests + + synchronized (threadHandler) { + threadHandler.interruptAll(cover); + deleteCover(cover.getKey()); + } + } + + /** + * Deletes a persisted cover from the database + * + * Checks whether cover is being calculated by a ground truth benchmark and + * if so deletes the graph instead. + * + * @param username + * owner of the cover + * @param graphKey + * key of the graph + * @param coverKey + * key of the cover + * @param threadHandler + * the thread handler + * @throws IllegalArgumentException + * cover does not exist + * @throws Exception + * if cover deletion failed + */ + public void deleteCover(String username, String graphKey, String coverKey, ThreadHandler threadHandler) throws Exception { + + Cover cover = getCover(username, graphKey, coverKey); + if (cover == null) + throw new IllegalArgumentException("Cover not found"); + + if (cover.getCreationMethod().getType().correspondsGroundTruthBenchmark() + && cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { + + this.deleteGraph(username, graphKey, threadHandler); + } + else { + this.deleteCover(cover, threadHandler); + } + + } + + ////////////////////////////////////////////////// CENTRALITY MAPS //////////////////////////////////////////////////////////// + + /** + * Persists a CentralityMap + * + * @param map + * CentralityMap + * @return persistence key of the stored map + */ + public String storeCentralityMap(CentralityMap map) { + String transId = this.getTransactionId(CentralityMap.class, true); + try { + map.persist(db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return map.getKey(); + } + + private CentralityMap getCentralityMap(String key, CustomGraph g) { + String transId = this.getTransactionId(CentralityMap.class, false); + CentralityMap map; + try { + map = CentralityMap.load(key, g, db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return map; + } + + /** + * Get a stored community-cover of a graph by its index + * + * @param username + * the name of the user + * @param graphKey + * key of the graph + * @param mapKey + * key of the centrality map + * @return the found Cover instance or null if the Cover does not exist + */ + public CentralityMap getCentralityMap(String username, String graphKey, String mapKey) { + CustomGraph graph = getGraph(username, graphKey); + CentralityMap map = null; + if(!(graph == null)) { + map = getCentralityMap(mapKey, graph); + } + if (map == null) { + logger.log(Level.WARNING, + "user: " + username + ", " + "CentralityMap does not exist: map key " + mapKey + ", graph key " + graphKey); + } + return map; + } + + /** + * Returns all centrality maps corresponding to a CustomGraph + * + * @param username + * Owner of the graph + * @param graphKey + * key of the graph + * @return A list of the corresponding centrality maps + */ + public List getCentralityMaps(String username, String graphKey) { + CustomGraph g = getGraph(username, graphKey); + String transId = getTransactionId(CentralityMap.class, false); + List maps = new ArrayList(); + if(g == null) { + return maps; + } + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR c IN " + CentralityMap.collectionName + " FILTER c." + CentralityMap.graphKeyColumnName + " == @key RETURN c._key"; + Map bindVars = Collections.singletonMap("key", graphKey); + ArangoCursor mapKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : mapKeys) { + CentralityMap map = CentralityMap.load(key, g, db, transId); + maps.add(map); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return maps; + } + + /** + * @param username + * the name of the user + * @param graphKey + * the key of the graph + * @param executionStatusIds + * the ids of the execution statuses + * @param firstIndex + * the first index + * @param length + * the length of the result set + * @return a centralityMap list + */ + public List getCentralityMaps(String username, String graphKey, List executionStatusIds, int firstIndex, int length) { //TODO testen + String transId = getTransactionId(null, false); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + HashMap bindVars = new HashMap(); + bindVars.put("user", username); + ArangoCollection mapColl = db.collection(CentralityMap.collectionName); + + List maps = new ArrayList(); + Map graphMap = new HashMap(); + Set graphKeySet = new HashSet(); + try { + String queryStr = " FOR c IN " + CentralityMap.collectionName + " FOR a IN " + CentralityCreationLog.collectionName + " FOR g IN " + CustomGraph.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @user AND c." + CentralityMap.graphKeyColumnName + " == g._key AND c." + + CentralityMap.creationMethodKeyColumnName + " == a._key AND a." + CentralityCreationLog.statusIdColumnName + " IN " + executionStatusIds; + + if(!graphKey.equals("")) { + queryStr += " AND g._key == @gKey " ; + bindVars.put("gKey", graphKey); + } + queryStr += " LIMIT " + firstIndex + ", " + length + " RETURN DISTINCT c._key"; //get each map only once + + //p(queryStr); + ArangoCursor mapDocs = db.query(queryStr, bindVars, queryOpt, String.class); + List mapKeys = mapDocs.asListRemaining(); + + for(String key : mapKeys) { + BaseDocument bd = mapColl.getDocument(key, BaseDocument.class, readOpt); + String gKey = bd.getAttribute(CentralityMap.graphKeyColumnName).toString(); + graphKeySet.add(gKey); + } + //cm mit zugehoerigem graph laden + for(String gKey : graphKeySet) { + graphMap.put(gKey, getGraph(gKey)); + } + for(String key : mapKeys) { + BaseDocument bd = mapColl.getDocument(key, BaseDocument.class, readOpt); + String gKey = bd.getAttribute(CentralityMap.graphKeyColumnName).toString(); + CustomGraph g = graphMap.get(gKey); + maps.add(CentralityMap.load(key, g, db, transId)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return maps; + } + + /** + * Return metadata of centralities efficiently, without loading + * unnecessary graph/cover/centrality data. + * + * @param username + * the name of the user + * @param graphKey + * the key of the graph + * @param executionStatusIds + * the ids of the execution statuses + * @param firstIndex + * the first index + * @param length + * the length of the result set + * @return CentralityMeta list + */ + public List getCentralityMapsEfficiently(String username, String graphKey, List executionStatusIds, int firstIndex, int length) { //TODO testen + String transId = getTransactionId(null, false); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + HashMap bindVars = new HashMap(); + bindVars.put("user", username); + ObjectMapper objectMapper = new ObjectMapper(); // needed to instantiate centralityMeta from JSON + ArrayList centralityMetas = new ArrayList(); + + try { + String queryStr = " FOR c IN " + CentralityMap.collectionName + " FOR a IN " + + CentralityCreationLog.collectionName + " FOR g IN " + CustomGraph.collectionName + + " FILTER g." + CustomGraph.userColumnName + " == @user AND c." + + CentralityMap.graphKeyColumnName + " == g._key AND c." + + CentralityMap.creationMethodKeyColumnName + " == a._key AND a." + + CentralityCreationLog.statusIdColumnName + " IN " + executionStatusIds; + if(!graphKey.equals("")) { + queryStr += " AND g._key == @gKey " ; + bindVars.put("gKey", graphKey); + } + queryStr += " LIMIT " + firstIndex + ", " + length + " RETURN " + + "{\"centralityKey\" : c._key," + + "\"centralityName\" : c." + CentralityMap.nameColumnName + "," + + "\"graphKey\" : c." + CentralityMap.graphKeyColumnName + "," + + "\"graphName\" : g." + CustomGraph.nameColumnName + "," + + "\"creationTypeId\" : a." + CentralityCreationLog.creationTypeColumnName + "," + + "\"creationStatusId\" : a." + CentralityCreationLog.statusIdColumnName + "," + + "\"executionTime\" : a." + CentralityCreationLog.executionTimeColumnName + "}"; + + ArangoCursor centralityMetaJson = db.query(queryStr, bindVars, queryOpt, String.class); + while(centralityMetaJson.hasNext()) { + /* Instantiate centralityMeta from the json string acquired from a query. + Then add it to the list that will be returned */; + centralityMetas.add(objectMapper.readValue(centralityMetaJson.next(), CentralityMeta.class)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + e.printStackTrace(); + } + return centralityMetas; + } + + /** + * Updates a persisted centralityMap, + * + * @param map + * the centralityMap + */ + public void updateCentralityMap(CentralityMap map) { //existenz der map muss bereits herausgefunden worden sein TESTEN + String transId = this.getTransactionId(CentralityMap.class, true); + try { + map.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + /** + * Updates a persisted centralityCreationLog, + * + * @param map + * the centralityMap + */ + public void updateCentralityCreationLog(CentralityMap map) { + String transId = this.getTransactionId(CentralityCreationLog.class, true); + try { + map.getCreationMethod().updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + private void deleteCentralityMap(String key, String transId) { //only use it in transaction + ArangoCollection centralityMapCollection = db.collection(CentralityMap.collectionName); + ArangoCollection cclCollection = db.collection(CentralityCreationLog.collectionName); + + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + BaseDocument centralityMapDoc = centralityMapCollection.getDocument(key, BaseDocument.class, readOpt); + + String cclKey = centralityMapDoc.getAttribute(CentralityMap.creationMethodKeyColumnName).toString(); + cclCollection.deleteDocument(cclKey, null, deleteOpt); //delete the CentralityCreationLog + + centralityMapCollection.deleteDocument(key, null, deleteOpt);//delete CentralityMap + } + + private void deleteCentralityMap(String key) { + String transId = this.getTransactionId(CentralityMap.class, true); + try { + deleteCentralityMap(key, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + e.printStackTrace(); + db.abortStreamTransaction(transId); + throw e; + } + } + /** + * Deletes a persisted CentralityMap from the database + * + * @param map + * The CentralityMap + * @param threadHandler + * The ThreadHandler for algorithm execution + */ + public void deleteCentralityMap(CentralityMap map, ThreadHandler threadHandler) { + synchronized (threadHandler) { + threadHandler.interruptAll(map); + deleteCentralityMap(map.getKey()); + } + } + /** + * Deletes a persisted CentralityMap from the database + * + * @param username + * Owner of the CentralityMap + * @param graphKey + * Key of the graph + * @param mapKey + * Key of the CentralityMap + * @param threadHandler + * The ThreadHandler for algorithm execution + * @throws IllegalArgumentException + * centrality map does not exist + * @throws Exception + * if centrality map deletion failed + */ + public void deleteCentralityMap(String username, String graphKey, String mapKey, ThreadHandler threadHandler) throws Exception{ + CentralityMap map = getCentralityMap(username, graphKey, mapKey); + if (map == null) { + throw new IllegalArgumentException("Centrality map not found"); + } + deleteCentralityMap(map, threadHandler); + } + + + /////////////////////////////////////////////// OCDMETRICLOG /////////////////////////////////////////////////////////////////////// + + private OcdMetricLog getOcdMetricLog(String key, Cover c) { + String transId = this.getTransactionId(OcdMetricLog.class, false); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + OcdMetricLog metric; + try { + metric = OcdMetricLog.load(key, c, db, readOpt); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return metric; + } + + /** + * Get a stored OcdMetricLog of a cover + * + * @param username + * the name of the user + * @param graphKey + * key of the graph + * @param coverKey + * key of the cover + * @param metricKey + * key of the OcdMetricLog + * @return the found OcdMetricLog instance or null if the Cover or Graph does not exist + */ + public OcdMetricLog getOcdMetricLog(String username, String graphKey, String coverKey, String metricKey) { + Cover cover = getCover(username, graphKey, coverKey); + + OcdMetricLog metric = null; + if(!(cover == null)) { + metric = getOcdMetricLog(metricKey, cover); + } + if (metric == null) { + logger.log(Level.WARNING, + "user: " + username + ", " + "OcdMetricLog does not exist: cover id " + coverKey + ", graph id " + graphKey + ", metric id " + metricKey); + } + return metric; + } + /** + * Get a stored OcdMetricLog of a cover + * + * @param logId + * the Id of the log + * @return the found OcdMetricLog instance or null if the Cover or Graph does not exist + */ + public OcdMetricLog getOcdMetricLog(OcdMetricLogId logId) { + CoverId cId = logId.getCoverId(); + CustomGraphId gId = cId.getGraphId(); + String user = gId.getUser(); + String gKey = gId.getKey(); + String cKey = cId.getKey(); + String mKey = logId.getKey(); + return getOcdMetricLog(user, gKey, cKey, mKey); + } + /** + * Updates a persisted OcdMetricLog. + * + * @param metricLog + * the OcdMetricLog + */ + public void updateOcdMetricLog(OcdMetricLog metricLog) { + String transId = this.getTransactionId(OcdMetricLog.class, true); + try { + metricLog.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + //////////////////////////////////////////////////////////////// SIMULATIONS ////////////////////////////////////// + + /////////////////// SimulationSeries /////////////////// + + public String storeSimulationSeries(SimulationSeries simulationSeries) { + String transId = this.getTransactionId(SimulationSeries.class, true); + try { + simulationSeries.persist(db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeries.getKey(); + } + + public String storeSimulationSeries(SimulationSeries simulationSeries, String userId) { + String transId = this.getTransactionId(SimulationSeries.class, true); + try { + simulationSeries.persist(db, transId, userId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeries.getKey(); + } + + + public void updateSimulationSeries(SimulationSeries simulationSeries) { + String transId = this.getTransactionId(SimulationSeries.class, true); + try { + simulationSeries.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + public SimulationSeries getSimulationSeries(String key) { + String transId = getTransactionId(SimulationDataset.class, false); + SimulationSeries simulationSeries; + try { + simulationSeries = SimulationSeries.load(key, db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeries; + } + + /** + * + * @param userId Id of the user + * @param returnSubset True if subset of SimulationSeries should be returned. + * @param firstIndex Index of the first simulation to return (only relevant if return Subset is true) + * @param length Number of simulations (only relevant if returnSubset is true) + * @param graphKey The graph's key + * @return List of SimulationSeries of a specific user + */ + public List getSimulationSeriesByUser(String userId, Boolean returnSubset, int firstIndex, int length, String graphKey){ + + String transId = getTransactionId(SimulationSeries.class, false); + List seriesList = new ArrayList(); + HashMap bindVars = new HashMap(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR ss IN " + SimulationSeries.collectionName + " FILTER ss." + SimulationSeries.userIdColumnName + " == @username "; + if (graphKey != ""){ + queryStr += " AND ss." + SimulationSeries.simulationSeriesParametersColumnName + ".graphKey == @gKey "; // graphKey refers to graphKey field in SimulationSeriesParameters + bindVars.put("gKey", graphKey); + } + if (returnSubset){ + queryStr += " LIMIT " + firstIndex + ", " + length; + } + queryStr += " RETURN ss._key"; + + bindVars.put("username",userId); + + ArangoCursor mapKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : mapKeys) { + SimulationSeries series = SimulationSeries.load(key, db, transId); + seriesList.add(series); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + + return seriesList; + } + + /** + * @param userId the users id + * @return all SimulationSeries of a specific user + */ + public List getSimulationSeriesByUser(String userId) { + // get all simulations of a user (not limited to a subset) + return getSimulationSeriesByUser(userId, false,0,0, ""); + } + + /** + * @param userId Id of the user + * @param firstIndex Id of the first simulation + * @param length Number of simulations + * @return List of SimulationSeries of a specific user + */ + public List getSimulationSeriesByUser(String userId, int firstIndex, int length){ + return getSimulationSeriesByUser(userId,true, firstIndex, length, ""); + } + + private void deleteSimulationSeries(String key, String transId) { + ArangoCollection simulationDatasetCollection = db.collection(SimulationSeries.collectionName); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + simulationDatasetCollection.deleteDocument(key, null, deleteOpt); + + /* Delete simulation series groups of which the deleted simulation series was a part of */ + String query = "FOR ssg IN " + SimulationSeriesGroup.collectionName + " FILTER \"" + key + "\" IN ssg." + SimulationSeriesGroup.simulationSeriesKeysColumnName + +" RETURN ssg._key"; + ArangoCursor simulationSeriesGroupKeys = db.query(query, queryOpt, String.class); + for(String simulationSeriesGroup : simulationSeriesGroupKeys) { + deleteSimulationSeriesGroup(simulationSeriesGroup, transId); + } + + } + + + public void deleteSimulationSeries(String key) { + String transId = this.getTransactionId(SimulationSeries.class, true); + try { + deleteSimulationSeries(key, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + e.printStackTrace(); + db.abortStreamTransaction(transId); + throw e; + } + } + + /** + * Returns a list of SimulationSeries filtered by the graphId + * + * @param userId the users id + * @param firstIndex the first index + * @param length the length of the result set + * @param graphKey the graphs key + * @return simulation series list + */ + public List getSimulationSeriesByUser(String userId, String graphKey, int firstIndex, int length){ + return getSimulationSeriesByUser(userId,true,firstIndex,length,graphKey); + } + + /////////////////// SimulationSeriesGroup /////////////////// + + public String storeSimulationSeriesGroup(SimulationSeriesGroup simulationSeriesGroup) { + String transId = this.getTransactionId(SimulationSeriesGroup.class, true); + try { + simulationSeriesGroup.persist(db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeriesGroup.getKey(); + } + + public String storeSimulationSeriesGroup(SimulationSeriesGroup simulationSeriesGroup, String userId) { + String transId = this.getTransactionId(SimulationSeriesGroup.class, true); + try { + simulationSeriesGroup.persist(db, transId, userId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeriesGroup.getKey(); + } + + public void updateSimulationSeriesGroup(SimulationSeriesGroup simulationSeriesGroup) { + String transId = this.getTransactionId(SimulationSeriesGroup.class, true); + try { + simulationSeriesGroup.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + public SimulationSeriesGroup getSimulationSeriesGroup(String key) { + String transId = getTransactionId(SimulationSeriesGroup.class, false); + SimulationSeriesGroup simulationSeriesGroup; + try { + simulationSeriesGroup = SimulationSeriesGroup.load(key, db, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeriesGroup; + } + + public List getSimulationSeriesGroups(String userId, Boolean returnSubset, int firstIndex, int length) { + String transId = getTransactionId(SimulationSeriesGroup.class, false); + List simulationSeriesGroupList = new ArrayList(); + HashMap bindVars = new HashMap(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + String queryStr = "FOR ssg IN " + SimulationSeriesGroup.collectionName + " FILTER ssg." + + SimulationSeries.userIdColumnName + " == @username "; + if (returnSubset){ + queryStr += " LIMIT " + firstIndex + ", " + length; + } + queryStr += " RETURN ssg._key"; + bindVars.put("username", userId); + ArangoCursor simulationSeriesGroupKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : simulationSeriesGroupKeys) { + SimulationSeriesGroup simulationSeriesGroup = SimulationSeriesGroup.load(key, db, transId); + simulationSeriesGroupList.add(simulationSeriesGroup); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return simulationSeriesGroupList; + } + + /** + * @param userId the users id + * @return all SimulationSeries of a specific user + */ + public List getSimulationSeriesGroups(String userId) { + // get all simulations of a user (not limited to a subset) + return getSimulationSeriesGroups(userId, false,0,0); + } + + /** + * @param userId Id of the user + * @param firstIndex Id of the first simulation + * @param length Number of simulations + * @return List of SimulationSeries of a specific user + */ + public List getSimulationSeriesGroups(String userId, int firstIndex, int length){ + return getSimulationSeriesGroups(userId,true, firstIndex, length); + } + + + + public void deleteSimulationSeriesGroup(String key, String transId) { + ArangoCollection groupParametersCollection = db.collection(SimulationSeriesGroup.collectionName); + DocumentDeleteOptions deleteOpt = new DocumentDeleteOptions().streamTransactionId(transId); + groupParametersCollection.deleteDocument(key, null, deleteOpt); + } + + public void deleteSimulationSeriesGroup(String key) { + String transId = this.getTransactionId(SimulationSeriesGroup.class, true); + try { + deleteSimulationSeriesGroup(key, transId); + db.commitStreamTransaction(transId); + }catch(Exception e) { + e.printStackTrace(); + db.abortStreamTransaction(transId); + throw e; + } + } + + + /////////////////////////// InactivityData /////////////////////////// + + /** + * Persists the InactivityData + * + * @param inData + * the InactivityData + * @return persistence key of the stored InactivityData + */ + public String storeInactivityData(InactivityData inData) { + String transId = getTransactionId(InactivityData.class, true); + DocumentCreateOptions createOpt = new DocumentCreateOptions().streamTransactionId(transId); + try { + inData.persist(db, createOpt); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return inData.getKey(); + } + + /** + * get the InactivityData of a specific user that is stored in the database + * + * @param username + * the username of the user + * @return A List of the InactivityData of a user + */ + public List getInactivityData(String username) { + String transId = getTransactionId(InactivityData.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + + String queryStr = "FOR d IN " + InactivityData.collectionName + " FILTER d." + InactivityData.userColumnName + + " == @username RETURN d._key"; + Map bindVars = Collections.singletonMap("username", username); + ArangoCursor dataKeys = db.query(queryStr, bindVars, queryOpt, String.class); + for(String key : dataKeys) { + queryResults.add(InactivityData.load(key, db, readOpt)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return queryResults; + } + + /** + * get every InactivityData stored in the database + * + * @return A List of every InactivityData + */ + public List getAllInactivityData() { + String transId = getTransactionId(InactivityData.class, false); + List queryResults = new ArrayList(); + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + DocumentReadOptions readOpt = new DocumentReadOptions().streamTransactionId(transId); + + String queryStr = "FOR d IN " + InactivityData.collectionName + " RETURN d._key"; + ArangoCursor dataKeys = db.query(queryStr, queryOpt, String.class); + for(String key : dataKeys) { + queryResults.add(InactivityData.load(key, db, readOpt)); + } + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + return queryResults; + } + + /** + * Updates the persisted InactivityData by updating the Attributes + * + * @param inData + * the inactivityData + */ + public void updateInactivityData(InactivityData inData) { + String transId = this.getTransactionId(InactivityData.class, true); + try { + inData.updateDB(db, transId); + db.commitStreamTransaction(transId); + } catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + + /** + * Removes username from the InactivityData table from the database. This is to ensure that for users whose content + * has been deleted and who are inactive, no processing power is wasted for checking their data. + * + * @param username Username to remove from the table. + * @param threadHandler the ThreadHandler. + */ + public void deleteUserInactivityData(String username, ThreadHandler threadHandler) { + if(threadHandler == null) { + threadHandler = new ThreadHandler(); + } + String transId = this.getTransactionId(InactivityData.class, true); + synchronized (threadHandler) { + try { + AqlQueryOptions queryOpt = new AqlQueryOptions().streamTransactionId(transId); + + String query = "FOR d IN " + InactivityData.collectionName + " FILTER d." + InactivityData.userColumnName + + " == @username REMOVE d IN " + InactivityData.collectionName; + Map bindVars = Collections.singletonMap("username", username); + db.query(query, bindVars, queryOpt, BaseDocument.class); + db.commitStreamTransaction(transId); + }catch(Exception e) { + db.abortStreamTransaction(transId); + throw e; + } + } + } + + + + + public String getTransactionId(Class c, boolean write) { + String [] collections; + if(c == CustomGraph.class) { + collections = collectionNames.subList(0, 4).toArray(new String[4]); + } + else if(c == Cover.class) { + collections = collectionNames.subList(4, 8).toArray(new String[4]); + } + else if(c == CentralityMap.class) { + collections = collectionNames.subList(8, 10).toArray(new String[2]); + } + else if(c == OcdMetricLog.class) { + collections = collectionNames.subList(6, 7).toArray(new String[1]); + } + else if(c == GraphCreationLog.class) { + collections = collectionNames.subList(3, 4).toArray(new String[1]); + } + else if(c == CoverCreationLog.class) { + collections = collectionNames.subList(5, 6).toArray(new String[1]); + } + else if(c == CentralityCreationLog.class) { + collections = collectionNames.subList(9, 10).toArray(new String[1]); + } + else if(c == InactivityData.class) { + collections = collectionNames.subList(10, 11).toArray(new String[1]); + } + else if(c == SimulationSeries.class){ + collections = collectionNames.subList(11,13).toArray(new String[1]); + } + else if(c == SimulationSeriesGroup.class){ + collections = collectionNames.subList(11,13).toArray(new String[1]); + } + else { + collections = collectionNames.subList(0, 13).toArray(new String[10]); + } + StreamTransactionEntity tx; + if(write) { + tx = db.beginStreamTransaction(new StreamTransactionOptions().writeCollections(collections)); + }else { + tx = db.beginStreamTransaction(new StreamTransactionOptions().readCollections(collections)); + } + return tx.getId(); + } + + public String printDB() { + String n = System.getProperty("line.separator"); + String res = "DB Name :" + db.dbName().get() + n; + for(String colName : collectionNames) { + String queryStr = "FOR x IN " + colName + " LIMIT 5 RETURN x"; + ArangoCursor docs = db.query(queryStr, BaseDocument.class); + res += "Collection : " + colName + n; + int i=0; + while(docs.hasNext()) { + i += 1; + if( i >= 0) { + BaseDocument doc = docs.next(); + res += "Doc " + i + " : " + doc.toString() + n; + } + } + res += "Size : " + i + n; + } + return res; + } + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/DatabaseConfig.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/DatabaseConfig.java new file mode 100644 index 00000000..306725be --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/DatabaseConfig.java @@ -0,0 +1,30 @@ +package i5.las2peer.services.ocd.utils; + +import java.io.FileWriter; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.util.Properties; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.FileInputStream; + +public class DatabaseConfig { + + private static final String PATH = "ocd/arangoDB/"; + private static final String FILENAME = "config.properties"; + private static final File CONFIG_FILE = new File(PATH+FILENAME); + private static Properties props = new Properties(); + + public Properties getConfigProperties() { + try { + FileInputStream inputStream = new FileInputStream(CONFIG_FILE); + props.load(inputStream); + }catch(IOException e) { + e.printStackTrace(); + } + return props; + } + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/EntityHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/EntityHandler.java deleted file mode 100644 index 286126d3..00000000 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/EntityHandler.java +++ /dev/null @@ -1,587 +0,0 @@ -package i5.las2peer.services.ocd.utils; - -import java.util.List; -import java.util.logging.Level; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; -import javax.persistence.TypedQuery; - -import i5.las2peer.logging.L2pLogger; -import i5.las2peer.p2p.AgentNotRegisteredException; -import i5.las2peer.services.ocd.centrality.data.CentralityMap; -import i5.las2peer.services.ocd.centrality.data.CentralityMapId; -import i5.las2peer.services.ocd.graphs.Cover; -import i5.las2peer.services.ocd.graphs.CoverCreationLog; -import i5.las2peer.services.ocd.graphs.CoverId; -import i5.las2peer.services.ocd.graphs.CustomGraph; -import i5.las2peer.services.ocd.graphs.CustomGraphId; -import i5.las2peer.services.ocd.graphs.GraphCreationLog; -import i5.las2peer.services.ocd.metrics.OcdMetricLog; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; - -import org.apache.commons.io.FileUtils; - -/** - * Manages the access on persisted data for the Service Class. - * - */ -public class EntityHandler { - - /** - * l2p logger - */ - private final static L2pLogger logger = L2pLogger.getInstance(EntityHandler.class.getName()); - - /** - * Default name of the persistence unit used for the creation of entity - * managers. - */ - private static final String defaultPersistenceUnitName = "ocd"; - - /** - * The factory used for the creation of entity managers. - */ - private static EntityManagerFactory emf = Persistence.createEntityManagerFactory(defaultPersistenceUnitName); - - /** - * Sets the persistence unit for entity managers produced by any handler. - * - * @param persistenceUnitName - * The name of the persistence unit. - */ - public static void setPersistenceUnit(String persistenceUnitName) { - emf = Persistence.createEntityManagerFactory(persistenceUnitName); - } - - /** - * Creates a new instance. Also initiates the database connection. - */ - public EntityHandler() { - EntityManager em = emf.createEntityManager(); - em.close(); - } - - /** - * Creates a new entity manager. - * - * @return The entity manager. - */ - public EntityManager getEntityManager() { - return emf.createEntityManager(); - } - - /////////////////////////// GRAPHS /////////////////////////// - - /** - * Persists a CustomGraph - * - * @param graph - * CustomGraph - * @return persistence id of the stored graph - */ - public long storeGraph(CustomGraph graph) { - - EntityManager em = getEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - tx.commit(); - } catch (RuntimeException e) { - e.printStackTrace(); - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - return graph.getId(); - } - - /** - * Returns a persisted CustomGraph - * - * @param username - * owner of the graph - * @param graphId - * id of the graph - * @return the found CustomGraph instance or null if the CustomGraph does - * not exist - */ - public CustomGraph getGraph(String username, long graphId) { - - CustomGraphId identity = new CustomGraphId(graphId, username); - CustomGraph graph = null; - EntityManager em = getEntityManager(); - EntityTransaction tx = em.getTransaction(); - - try { - tx.begin(); - graph = em.find(CustomGraph.class, identity); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - - if (graph == null) { - logger.log(Level.WARNING, "user: " + username + ", " + "Graph does not exist: graph id " + graphId); - } - return graph; - } - - /** - * Deletes a CustomGraph from the database - * - * @param username - * owner of the graph - * @param graphId - * id of the graph - * @param threadHandler - * the threadhandler - * @throws Exception if cover deletion failed - */ - public void deleteGraph(String username, long graphId, ThreadHandler threadHandler) throws Exception { - - EntityManager em = getEntityManager(); - CustomGraphId id = new CustomGraphId(graphId, username); - - synchronized (threadHandler) { - - threadHandler.interruptBenchmark(id); - - List coverList = getCovers(username, graphId); - for (Cover cover : coverList) { - try { - deleteCover(username, cover, threadHandler); - } catch (Exception e) { - throw e; - } - } - - List centralityMapList = getCentralityMaps(username, graphId); - for (CentralityMap map : centralityMapList) { - try { - deleteCentralityMap(username, map, threadHandler); - } catch (Exception e) { - throw e; - } - } - - EntityTransaction tx = em.getTransaction(); - try { - tx = em.getTransaction(); - tx.begin(); - - CustomGraph graph = em.getReference(CustomGraph.class, id); - - if(graph.getPath() != "" && graph.getPath() != null) { // Delete index folder if graph is content graph - File file = new File(graph.getPath()); - FileUtils.deleteDirectory(file); - } - - em.remove(graph); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } catch (IOException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - - throw new RuntimeException("Could not delete folder of content graph"); - } - } - - } - - /** - * Return all graphs of a user - * - * @param username - * graphs owner - * @return graph list - * @throws AgentNotRegisteredException if the agent was not registered - */ - public List getGraphs(String username) throws AgentNotRegisteredException { - - List queryResults; - EntityManager em = getEntityManager(); - String queryStr = "SELECT g FROM " + CustomGraph.class.getName() + " g WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username"; - TypedQuery query = em.createQuery(queryStr, CustomGraph.class); - query.setParameter("username", username); - queryResults = query.getResultList(); - em.close(); - - return queryResults; - } - - /** - * Return a list of specific graphs of a user - * - * @param username - * the users username - * @param firstIndex - * id of the first graph - * @param length - * number of graphs - * @param executionStatusIds - * the execution status ids of the graphs - * @return the list of graphs - */ - public List getGraphs(String username, int firstIndex, int length, List executionStatusIds) { - - List queryResults; - EntityManager em = getEntityManager(); - String queryStr = "SELECT g FROM " + CustomGraph.class.getName() + " g" + " JOIN g." + CustomGraph.CREATION_METHOD_FIELD_NAME + " b" - + " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username" + " AND b." - + GraphCreationLog.STATUS_ID_FIELD_NAME + " IN :execStatusIds"; - TypedQuery query = em.createQuery(queryStr, CustomGraph.class); - query.setFirstResult(firstIndex); - query.setMaxResults(length); - query.setParameter("username", username); - query.setParameter("execStatusIds", executionStatusIds); - queryResults = query.getResultList(); - em.close(); - - return queryResults; - } - - /////////////////////////// COVERS /////////////////////////// - - /** - * Get a stored community-cover of a graph by its index - * - * @param username - * the name of the user - * @param coverId - * id of the cover - * @param graphId - * id of the graph - * @return the found Cover instance or null if the Cover does not exist - */ - public Cover getCover(String username, long graphId, long coverId) { - - EntityManager em = getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CoverId cId = new CoverId(coverId, gId); - EntityTransaction tx = em.getTransaction(); - Cover cover; - - try { - tx.begin(); - cover = em.find(Cover.class, cId); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - if (cover == null) { - logger.log(Level.WARNING, - "user: " + username + ", " + "Cover does not exist: cover id " + coverId + ", graph id " + graphId); - } - return cover; - } - - /** - * Deletes a persisted cover from the database - * - * Checks whether cover is being calculated by a ground truth benchmark and - * if so deletes the graph instead. - * - * @param username - * owner of the cover - * @param coverId - * id of the cover - * @param graphId - * id of the graph - * @param threadHandler - * the thread handler - * @throws IllegalArgumentException - * cover does not exist - * @throws Exception - * if cover deletion failed - */ - public void deleteCover(String username, long graphId, long coverId, ThreadHandler threadHandler) throws Exception { - - Cover cover = getCover(username, graphId, coverId); - if (cover == null) - throw new IllegalArgumentException("Cover not found"); - - if (cover.getCreationMethod().getType().correspondsGroundTruthBenchmark() - && cover.getCreationMethod().getStatus() != ExecutionStatus.COMPLETED) { - - this.deleteGraph(username, graphId, threadHandler); - } - - this.deleteCover(username, cover, threadHandler); - } - - /** - * Deletes a persisted cover from the database - * - * @param username - * owner of the cover - * @param cover - * the cover - * @param threadHandler - * the threadhandler - */ - public void deleteCover(String username, Cover cover, ThreadHandler threadHandler) { - - synchronized (threadHandler) { - - threadHandler.interruptAll(cover); - EntityManager em = getEntityManager(); - EntityTransaction tx = em.getTransaction(); - - CoverId id = new CoverId(cover.getId(), new CustomGraphId(cover.getGraph().getId(), username)); - try { - tx.begin(); - em.remove(em.getReference(Cover.class, id)); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - } - } - - /** - * Removes username from the InactivityData table from the database. This is to ensure that for users whose content - * has been deleted and who are inactive, no processing power is wasted for checking their data. - * - * @param username Username to remove from the table. - * @param threadHandler the ThreadHandler. - */ - public void deleteUserInactivityData(String username, ThreadHandler threadHandler) { - - synchronized (threadHandler) { - EntityManager em = getEntityManager(); - EntityTransaction tx = em.getTransaction(); - - try { - tx.begin(); - ; - - // find user to delete - String queryStr = "DELETE FROM " + InactivityData.class.getName() + " d WHERE d." + InactivityData.USER_NAME_FIELD_NAME + " = :username"; - TypedQuery query = em.createQuery(queryStr, InactivityData.class); - query.setParameter("username", username); - query.executeUpdate(); - - tx.commit(); - - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - } - } - - /** - * Returns all Covers corresponding to a CustomGraph - * - * @param username - * owner of the graph - * @param graphId - * id of the graph - * @return cover list - */ - public List getCovers(String username, long graphId) { - - EntityManager em = getEntityManager(); - String queryStr = "SELECT c from Cover c" + " JOIN c." + Cover.GRAPH_FIELD_NAME + " g" + " WHERE g." - + CustomGraph.USER_NAME_FIELD_NAME + " = :username" + " AND g." + CustomGraph.ID_FIELD_NAME + " = " - + graphId; - TypedQuery query = em.createQuery(queryStr, Cover.class); - query.setParameter("username", username); - - return query.getResultList(); - } - - /** - * @param username - * the name of the user - * @param graphId - * the id of the graph - * @param executionStatusIds - * the ids of the execution statuses - * @param metricExecutionStatusIds - * the ids of the metric execution statuses - * @param firstIndex - * the first index - * @param length - * the length of the result set - * @param includeMeta - * boolean whether to include meta info or not - * @return a cover list - */ - public List getCovers(String username, long graphId, List executionStatusIds, - List metricExecutionStatusIds, int firstIndex, int length, boolean includeMeta) { - - EntityManager em = getEntityManager(); - - String queryStr = "SELECT c from Cover c" + " JOIN c." + Cover.GRAPH_FIELD_NAME + " g" + " JOIN c." - + Cover.CREATION_METHOD_FIELD_NAME + " a"; - if (metricExecutionStatusIds != null && metricExecutionStatusIds.size() > 0) { - queryStr += " JOIN c." + Cover.METRICS_FIELD_NAME + " m"; - } - queryStr += " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username" + " AND a." - + CoverCreationLog.STATUS_ID_FIELD_NAME + " IN :execStatusIds"; - if (metricExecutionStatusIds != null && metricExecutionStatusIds.size() > 0) { - queryStr += " AND m." + OcdMetricLog.STATUS_ID_FIELD_NAME + " IN :metricExecStatusIds"; - } - if (graphId >= 0) { - queryStr += " AND g." + CustomGraph.ID_FIELD_NAME + " = " + graphId; - } - queryStr += " GROUP BY c"; - - TypedQuery query = em.createQuery(queryStr, Cover.class); - query.setFirstResult(firstIndex); - query.setMaxResults(length); - query.setParameter("username", username); - query.setParameter("execStatusIds", executionStatusIds); - - if (metricExecutionStatusIds != null && metricExecutionStatusIds.size() > 0) { - query.setParameter("metricExecStatusIds", metricExecutionStatusIds); - } - List queryResults = query.getResultList(); - em.close(); - return queryResults; - } - - //////////////////////// CENTRALITY //////////////////////// - - /** - * Get a stored centrality map. - * - * @param username - * Owner of the CentralityMap - * @param graphId - * Id of the graph the CentralityMap is based on - * @param mapId - * Id the of CentralityMap - * @return The found CentralityMap instance or null if the CentralityMap does not exist - */ - public CentralityMap getCentralityMap(String username, long graphId, long mapId) { - - EntityManager em = getEntityManager(); - CustomGraphId gId = new CustomGraphId(graphId, username); - CentralityMapId cId = new CentralityMapId(mapId, gId); - /* - * Finds CentralityMap - */ - EntityTransaction tx = em.getTransaction(); - CentralityMap map; - try { - tx.begin(); - map = em.find(CentralityMap.class, cId); - tx.commit(); - } - catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - if (map == null) { - logger.log(Level.WARNING, - "user: " + username + ", " + "Centrality map does not exist: centrality map id " + mapId + ", graph id " + graphId); - } - return map; - } - - /** - * Deletes a persisted CentralityMap from the database - * - * @param username - * Owner of the CentralityMap - * @param graphId - * Id of the graph - * @param mapId - * Id of the CentralityMap - * @param threadHandler - * The ThreadHandler for algorithm execution - * @throws IllegalArgumentException if the centrality map was not found - */ - public void deleteCentralityMap(String username, long graphId, long mapId, ThreadHandler threadHandler) { - CentralityMap map = getCentralityMap(username, graphId, mapId); - if (map == null) - throw new IllegalArgumentException("Centrality map not found"); - - deleteCentralityMap(username, map, threadHandler); - } - - /** - * Deletes a persisted CentralityMap from the database - * - * @param username - * Owner of the CentralityMap - * @param map - * The CentralityMap - * @param threadHandler - * The ThreadHandler for algorithm execution - */ - public void deleteCentralityMap(String username, CentralityMap map, ThreadHandler threadHandler) { - synchronized (threadHandler) { - threadHandler.interruptAll(map); - EntityManager em = getEntityManager(); - EntityTransaction tx = em.getTransaction(); - - CentralityMapId id = new CentralityMapId(map.getId(), new CustomGraphId(map.getGraph().getId(), username)); - try { - tx.begin(); - em.remove(em.getReference(CentralityMap.class, id)); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); - } - } - - /** - * Returns all centrality maps corresponding to a CustomGraph - * - * @param username - * Owner of the graph - * @param graphId - * Id of the graph - * @return A list of the corresponding centrality maps - */ - public List getCentralityMaps(String username, long graphId) { - - EntityManager em = getEntityManager(); - String queryStr = "SELECT c from CentralityMap c" + " JOIN c." + CentralityMap.GRAPH_FIELD_NAME + " g" + " WHERE g." - + CustomGraph.USER_NAME_FIELD_NAME + " = :username" + " AND g." + CustomGraph.ID_FIELD_NAME + " = " - + graphId; - TypedQuery query = em.createQuery(queryStr, CentralityMap.class); - query.setParameter("username", username); - - return query.getResultList(); - } -} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GeneralLogger.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GeneralLogger.java new file mode 100644 index 00000000..967e0492 --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GeneralLogger.java @@ -0,0 +1,80 @@ +package i5.las2peer.services.ocd.utils; + +import i5.las2peer.logging.L2pLogger; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Formatter; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +/** + * This is a logging class that can be used anywhere within the WebOCD Service. It logs in two file, service.log using + * Mobsos message format, general-log.txt is using better human-readable format. + */ +public class GeneralLogger { + private static GeneralLogger generalLogger; + private static L2pLogger logger; + private static FileHandler fileHandler; + private static SimpleFormatter formatter; + + + /** + * Path to the file where logger should write + */ + private static final String FILE_PATH = "log/general-log.%g.txt"; + + /** + * The size of the logging file in bytes + */ + private static final int LOGGING_FILE_SIZE = 1024 * 1000 * 100; + + /** + * Maximum number of logging files to generate as logging files reach maximum size + */ + private static final int MAX_NUMBER_OF_LOGGING_FILES = 50; + + + public GeneralLogger(){ + System.out.println("inside constructor for general logger"); + // Singleton class + if (generalLogger != null){ + return; + } + System.out.println("creating the logger"); + // Create log file + try{ + Files.createDirectories(Paths.get("log")); + fileHandler = new FileHandler(FILE_PATH,LOGGING_FILE_SIZE,MAX_NUMBER_OF_LOGGING_FILES,true); + }catch(Exception e){ + e.printStackTrace(); + } + + formatter = new SimpleFormatter(); + fileHandler.setFormatter(formatter); + logger = L2pLogger.getInstance("GeneralLogger"); + + //logger = Logger.getLogger("GeneralLogger"); // this logger is a singleton + logger.addHandler(fileHandler); + logger.setLevel(Level.FINEST); + + try{ + logger.setLogDirectory("log/"); + }catch(Exception e){ + e.printStackTrace(); + } + + generalLogger = this; + + + + } + + public L2pLogger getLogger(){ + return GeneralLogger.logger; + } + + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GroundTruthBenchmarkRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GroundTruthBenchmarkRunnable.java index b69d4ebb..93412115 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GroundTruthBenchmarkRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/GroundTruthBenchmarkRunnable.java @@ -5,6 +5,7 @@ import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CoverId; import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.graphs.CustomGraphId; import java.util.logging.Level; @@ -50,13 +51,17 @@ public void run() { * Set algorithm and benchmark status to running. */ RequestHandler requestHandler = new RequestHandler(); - EntityHandler entityHandler = new EntityHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + + Database database = new Database(false); + + String cKey = coverId.getKey(); + CustomGraphId gId = coverId.getGraphId(); + String user = gId.getUser(); + String gKey = gId.getKey(); try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { + System.out.println("Cover in GroundTruthBenchmarkRunnable runnable was null " + user + gKey + cKey); /* * Should not happen. */ @@ -66,14 +71,11 @@ public void run() { CustomGraph graph = cover.getGraph(); cover.getCreationMethod().setStatus(ExecutionStatus.RUNNING); graph.getCreationMethod().setStatus(ExecutionStatus.RUNNING); - tx.commit(); + database.updateGraphCreationLog(graph); //TODO both in one transaction? + database.updateCoverCreationLog(cover); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } error = true; } - em.close(); Cover groundTruthCover = null; if(!error) { try { diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityData.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityData.java index fdfa2ed4..62d9df48 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityData.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityData.java @@ -1,7 +1,18 @@ package i5.las2peer.services.ocd.utils; import javax.persistence.*; +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDatabase; +import com.arangodb.entity.BaseDocument; +import com.arangodb.model.DocumentCreateOptions; +import com.arangodb.model.DocumentReadOptions; +import com.arangodb.model.DocumentUpdateOptions; +import com.fasterxml.jackson.databind.ObjectMapper; + +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; import java.time.LocalDate; +import java.util.Map; /** * Represents user inactivity information. Instance of this class will store when the user logged in and when is the @@ -19,7 +30,11 @@ public class InactivityData { public static final String USER_COLUMN_NAME = "USER_NAME"; public static final String LAST_LOGIN_DATE_COLUMN_NAME = "LAST_LOGIN_DATE"; public static final String DELETION_DATE_COLUMN_NAME = "DELETION_DATE"; - + //ArangoDB + public static final String collectionName = "inactivitydata"; + public static final String userColumnName = "USER_NAME"; + private static final String lastLoginDateColumnName = "LAST_LOGIN_DATE"; + private static final String deletetionDateColumnName = "DELETION_DATE"; /* * Field name definitions for JPQL queries. @@ -36,7 +51,11 @@ public class InactivityData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - + + /** + * System generated persistence id. + */ + private String key; /** * Username for which the info is stored. */ @@ -72,6 +91,14 @@ public Long getId() { return id; } + /** + * Getter for system-generated user inactivity entry key. + * + * @return return auto-generated unique key of InactivityData entry. + */ + public String getKey() { + return key; + } /** * Setter for system-generated user inactivity entry id. @@ -165,7 +192,7 @@ public void setLastLoginDate(LocalDate lastLoginDate) { * @return LocalDate representing content deletion date of the user. */ public LocalDate getDeletionDate() { - + return deletionDate; } @@ -180,4 +207,49 @@ public void setDeletionDate(LocalDate deletionDate) { this.deletionDate = deletionDate; } + + //persistence functions + public void persist( ArangoDatabase db, DocumentCreateOptions opt) { + ArangoCollection collection = db.collection(collectionName); + BaseDocument bd = new BaseDocument(); + bd.addAttribute(userColumnName, this.username); + bd.addAttribute(lastLoginDateColumnName, this.lastLoginDate.toString()); + bd.addAttribute(deletetionDateColumnName, this.deletionDate.toString()); + + collection.insertDocument(bd, opt); + this.key = bd.getKey(); + } + + public static InactivityData load(String key, ArangoDatabase db, DocumentReadOptions opt) { + InactivityData inData = new InactivityData(); + ArangoCollection collection = db.collection(collectionName); + + BaseDocument bd = collection.getDocument(key, BaseDocument.class, opt); + if (bd != null) { + inData.username = bd.getAttribute(userColumnName).toString(); + String lastLogin = bd.getAttribute(lastLoginDateColumnName).toString(); + String deletion = bd.getAttribute(deletetionDateColumnName).toString(); + inData.lastLoginDate = LocalDate.parse(lastLogin); + inData.deletionDate = LocalDate.parse(deletion); + inData.key = key; + } + else { + System.out.println("empty InactivityData document"); + } + return inData; + } + + public void updateDB(ArangoDatabase db, String transId) { + ArangoCollection collection = db.collection(collectionName); + DocumentUpdateOptions updateOpt = new DocumentUpdateOptions().streamTransactionId(transId); + + BaseDocument bd = new BaseDocument(); + bd.addAttribute(userColumnName, this.username); + bd.addAttribute(lastLoginDateColumnName, this.lastLoginDate.toString()); + bd.addAttribute(deletetionDateColumnName, this.deletionDate.toString()); + + collection.updateDocument(this.key, bd, updateOpt); + } + + } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityHandler.java index ed5afa8b..62d52248 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityHandler.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InactivityHandler.java @@ -1,3 +1,4 @@ + package i5.las2peer.services.ocd.utils; @@ -26,10 +27,10 @@ public class InactivityHandler { /** - * Entity Handler for interacting with the database. + * Database. */ - EntityHandler entityHandler; + Database database; /** * The thread handler used for algorithm, benchmark and metric execution. */ @@ -40,11 +41,6 @@ public class InactivityHandler { */ ExecutorService executor; - /** - * Number of days of inactivity allowed, before user content gets removed. - */ - int maxInactiveDays; // number of days of inactivity before user data gets deleted - /** * Map to track last login date and data deletion date of a user */ @@ -55,64 +51,57 @@ public class InactivityHandler { */ ServiceClass service; + /** + * Handler for user specific as well as default limits including content removal + */ + UserLimitsHandler userLimitsHandler; + /** * Constructor for InactivityHandler * - * @param entityHandler EntityHandler passed from ServiceClass + * @param database Database passed from ServiceClass * @param threadHandler ThreadHandler passed from ServiceClass * @param serviceClass ServiceClass instance */ - public InactivityHandler(EntityHandler entityHandler, ThreadHandler threadHandler, ServiceClass serviceClass) { - this.entityHandler = entityHandler; + public InactivityHandler(Database database, ThreadHandler threadHandler, ServiceClass serviceClass) { + this.threadHandler = threadHandler; this.executor = ThreadHandler.getExecutor(); this.service = serviceClass; - this.maxInactiveDays = this.readAllowedInactivityDays(); - + this.userLimitsHandler = new UserLimitsHandler(database); + this.database = database; // part of the code that will be executed regularly ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(() -> { try { - - // get fresh maxInactivityDays in case it was changed since last check. - maxInactiveDays = this.readAllowedInactivityDays(); - - // get up-to-date user inactivity info + /* get up-to-date user inactivity info */ inactivityTracker = this.getDeletionData(); - - + /* Check if user data needs to be deleted. If yes, delete the data. */ for (String user : inactivityTracker.keySet()) { - - System.out.println("checking inactivity of " + user + " lastLoginDate: " + inactivityTracker.get(user).getFirst() + " DeletionDate: " + inactivityTracker.get(user).getSecond()); if (shouldDelete(inactivityTracker.get(user))) { - - // get all graphs of a user to delete - List userGraphs = entityHandler.getGraphs(user); - + List userGraphs = database.getGraphs(user); System.out.println("need to delete " + user + " data. which has " + userGraphs.size() + " graphs."); - // check that user has graphs, to avoid unnecessary computations if (userGraphs.size() > 0) { // System.out.println("Deleting graphs of user " + user + " due to inactivity."); // System.out.print("Deleted graph ids: "); // delete all graphs of a user for (CustomGraph graph : userGraphs) { - entityHandler.deleteGraph(user, graph.getId(), threadHandler); - System.out.print(graph.getId() + ", "); + database.deleteGraph(user, graph.getKey(), threadHandler); + System.out.print(graph.getKey() + ", "); } System.out.println(); } else { // System.out.println("nothing to delete for " + user); // user has no graphs, so remove the user from known users. - entityHandler.deleteUserInactivityData(user, threadHandler); + database.deleteUserInactivityData(user, threadHandler); } } - } } catch (Exception e) { @@ -124,8 +113,8 @@ public InactivityHandler(EntityHandler entityHandler, ThreadHandler threadHandle /** - * Checks whether user content should be removed. This is done by comparing if the deletion date is greater or equal - * to the current date. + * Checks whether user content should be removed. This is done by comparing + * if the deletion date is greater or equal to the current date. * * @param userDeletionInfo Pair object that holds last login and content deletion dates of user. * @return true if content of the user should be removed at the time of calling this method. @@ -138,43 +127,43 @@ public boolean shouldDelete(Pair userDeletionInfo) { } - /** - * Refreshes user's last login and deletion dates. + * Refreshes user's last login and deletion dates and returns deletion date * * @param username user for which the refreshment should be done. + * @param update true if user inactivity data should be updated (used when user logs in). + * @return user content deletion date */ - public void refreshUserInactivityData(String username) { - - LocalDate currentDate = LocalDate.now(); // current day - LocalDate deletionDate = currentDate.plusDays(this.maxInactiveDays); // when user data should be deleted if user does not relog + public LocalDate getAndUpdateUserInactivityData(String username, boolean update) { - EntityManager em = this.entityHandler.getEntityManager(); - em.getTransaction().begin(); + // current day + LocalDate currentDate = LocalDate.now(); + // date when user data should be deleted if user does not relogin + LocalDate deletionDate = currentDate.plusDays(userLimitsHandler.getAllowedInactivityDays(username)); // try to find deletion info for user with a given username - String queryStr = "SELECT d FROM " + InactivityData.class.getName() + " d WHERE d." + InactivityData.USER_NAME_FIELD_NAME + " = :username"; - TypedQuery query = em.createQuery(queryStr, InactivityData.class); - query.setParameter("username", username); - List queryResults = query.getResultList(); - - if (queryResults.isEmpty()) { - System.out.println("username " + username + " unknown. creating entry for it."); - // user unknown, create user entry. - Pair userInactivityTracker = new Pair(currentDate, deletionDate); - InactivityData inData = new InactivityData(username, userInactivityTracker); - System.out.println("created entry " + inData.getUsername() + " last login date: " + inData.getLastLoginDate() + " content deletion date: " + inData.getDeletionDate()); - em.persist(inData); - - } else { - // user known, update deletion info. - System.out.println(username + " is known, refresh data"); - queryResults.get(0).setLastLoginDate(currentDate); - queryResults.get(0).setDeletionDate(deletionDate); + List queryResults = database.getInactivityData(username); + + if (update) { + /* If user not known, add an entry for it. If user is known, update the entry. */ + if (queryResults.isEmpty()) { + System.out.println("username " + username + " unknown. creating entry for it."); + // user unknown, create user entry. + Pair userInactivityTracker = new Pair(currentDate, deletionDate); + InactivityData inData = new InactivityData(username, userInactivityTracker); + System.out.println("Created entry for " + inData.getUsername() + ". Last login date: " + inData.getLastLoginDate() + ". Content deletion date: " + inData.getDeletionDate()); + database.storeInactivityData(inData); + } else { + // user known, update deletion info. + System.out.println("User " + username + " is known. Last login date: " + currentDate + ". Content deletion date: " + deletionDate); + InactivityData inData = queryResults.get(0); + inData.setLastLoginDate(currentDate); + inData.setDeletionDate(deletionDate); + database.updateInactivityData(inData); + } } - em.getTransaction().commit(); - em.close(); + return deletionDate; } @@ -187,19 +176,11 @@ public void refreshUserInactivityData(String username) { public HashMap> getDeletionData() { HashMap> inactivityTracker = new HashMap>(); - - EntityManager em = entityHandler.getEntityManager(); - - List queryResults; - String queryStr = "SELECT d FROM " + InactivityData.class.getName() + " d"; - TypedQuery query = em.createQuery(queryStr, InactivityData.class); - queryResults = query.getResultList(); - - em.close(); + List queryResults = database.getAllInactivityData(); for (InactivityData data : queryResults) { - // we recalculate deletion date here in case maxInactivityDays has changed. - LocalDate deletionDate = data.lastLoginDate.plusDays(this.maxInactiveDays); + /* recalculate deletion date in case it has changed. */ + LocalDate deletionDate = data.lastLoginDate.plusDays(userLimitsHandler.getAllowedInactivityDays(data.getUsername())); inactivityTracker.put(data.getUsername(), new Pair(data.lastLoginDate, deletionDate)); } @@ -207,24 +188,25 @@ public HashMap> getDeletionData() { } /** - * Reads in value of allowed inactivity days before user content gets removed. - * This value can be adjusted in i5.las2peer.services.ocd.ServiceClass.properties + * Reads in value of allowed inactivity days before user content gets removed. This value can be adjusted in + * etc/userLimitInformation.json + * * @return Number of days allowed for user to be inactive, before content deletion. */ - public int readAllowedInactivityDays() { + public int readDefaultAllowedInactivityDays() { + /* if for some reason no default value exists, this value will be used.*/ int allowed_inactivity_days = 30; - service.setFreshFieldValues(); // update field values in case modifications were made - - int read_MaxInactivityValue = service.getMaxInactiveDays(); + /* read the default allowed inactivity value from the JSON file */ + int readDefaultMaxInactivityValue = userLimitsHandler.getAllowedInactivityDays("default"); - if (read_MaxInactivityValue >= 0) { - allowed_inactivity_days = read_MaxInactivityValue; + if (readDefaultMaxInactivityValue >= 0) { + allowed_inactivity_days = readDefaultMaxInactivityValue; } return allowed_inactivity_days; } -} \ No newline at end of file +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InvocationHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InvocationHandler.java index a2e02d5e..faad6a7a 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InvocationHandler.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/InvocationHandler.java @@ -1,15 +1,15 @@ package i5.las2peer.services.ocd.utils; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; /** * Handles Remote Method Invocation calls from other services in the las2peer @@ -18,7 +18,7 @@ */ public class InvocationHandler { - private EntityHandler entityHandler = new EntityHandler(); + //private EntityHandler entityHandler = new EntityHandler(); //////////// GRAPH //////////// @@ -35,7 +35,7 @@ public class InvocationHandler { */ public List> getAdjList(CustomGraph graph) { - int size = graph.nodeCount(); + int size = graph.getNodeCount(); List> adjList = new ArrayList<>(size+1); adjList.add(0, new ArrayList()); @@ -43,14 +43,14 @@ public List> getAdjList(CustomGraph graph) { List list = new ArrayList<>(); adjList.add(i, list); } - - for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) { - Edge edge = ec.edge(); - Node source = edge.source(); - Node target = edge.target(); - - int sourceId = Integer.valueOf(graph.getNodeName(source)); - int targetId = Integer.valueOf(graph.getNodeName(target)); + Iterator ec = graph.edges().iterator(); + while(ec.hasNext()) { + Edge edge = ec.next(); + Node source = edge.getSourceNode(); + Node target = edge.getTargetNode(); + + int sourceId = Integer.parseInt(graph.getNodeName(source)); + int targetId = Integer.parseInt(graph.getNodeName(target)); adjList.get(sourceId).add(targetId); } @@ -83,30 +83,30 @@ public List> getCommunityMemberList(Cover cover) { return communityMemberList; } - public List getCoverIdsByGraphId(long graphId, String username) { - - List queryResults; - EntityManager em = entityHandler.getEntityManager(); - - String queryStr = "SELECT c from Cover c" + " JOIN c." + Cover.GRAPH_FIELD_NAME + " g"; - queryStr += " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username"; - queryStr += " AND g." + CustomGraph.ID_FIELD_NAME + " = " + graphId; - - queryStr += " GROUP BY c"; - TypedQuery query = em.createQuery(queryStr, Cover.class); - - query.setParameter("username", username); - queryResults = query.getResultList(); - em.close(); - - int size = queryResults.size(); - ArrayList coverIds = new ArrayList(size); - for (int i = 0; i < size; i++) { - coverIds.add((int) queryResults.get(i).getId()); - } - - return coverIds; - - } +// public List getCoverIdsByGraphId(long graphId, String username) { //TODO is not used +// +// List queryResults; +// EntityManager em = entityHandler.getEntityManager(); +// +// String queryStr = "SELECT c from Cover c" + " JOIN c." + Cover.GRAPH_FIELD_NAME + " g"; +// queryStr += " WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username"; +// queryStr += " AND g." + CustomGraph.ID_FIELD_NAME + " = " + graphId; +// +// queryStr += " GROUP BY c"; +// TypedQuery query = em.createQuery(queryStr, Cover.class); +// +// query.setParameter("username", username); +// queryResults = query.getResultList(); +// em.close(); +// +// int size = queryResults.size(); +// ArrayList coverIds = new ArrayList(size); +// for (int i = 0; i < size; i++) { +// coverIds.add((int) queryResults.get(i).getId()); +// } +// +// return coverIds; +// +// } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/KnowledgeDrivenMeasureRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/KnowledgeDrivenMeasureRunnable.java index d1328fb1..3685b3b9 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/KnowledgeDrivenMeasureRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/KnowledgeDrivenMeasureRunnable.java @@ -1,6 +1,8 @@ package i5.las2peer.services.ocd.utils; import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.CoverId; +import i5.las2peer.services.ocd.graphs.CustomGraphId; import i5.las2peer.services.ocd.metrics.KnowledgeDrivenMeasure; import i5.las2peer.services.ocd.metrics.OcdMetricExecutor; import i5.las2peer.services.ocd.metrics.OcdMetricLog; @@ -58,18 +60,18 @@ public KnowledgeDrivenMeasureRunnable(OcdMetricLogId logId, KnowledgeDrivenMeasu @Override public void run() { + boolean error = false; /* * Set metric state to running. */ RequestHandler requestHandler = new RequestHandler(); - EntityHandler entityHandler = new EntityHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + Database database = new Database(false); + try { - tx.begin(); - OcdMetricLog persistedLog = em.find(OcdMetricLog.class, logId); + OcdMetricLog persistedLog = database.getOcdMetricLog(logId); if(persistedLog == null) { + System.out.println("metric log deleted while metric running"); /* * Should not happen. */ @@ -77,14 +79,10 @@ public void run() { throw new IllegalStateException(); } persistedLog.setStatus(ExecutionStatus.RUNNING); - tx.commit(); + database.updateOcdMetricLog(persistedLog); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } error = true; } - em.close(); /* * Run metric. */ diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/RequestHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/RequestHandler.java index afa61b0b..da89e9c1 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/RequestHandler.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/RequestHandler.java @@ -20,14 +20,12 @@ import i5.las2peer.services.ocd.adapters.graphOutput.GraphOutputAdapter; import i5.las2peer.services.ocd.adapters.graphOutput.GraphOutputAdapterFactory; import i5.las2peer.services.ocd.adapters.graphOutput.GraphOutputFormat; +import i5.las2peer.services.ocd.adapters.metaOutput.*; import i5.las2peer.services.ocd.centrality.data.CentralityMap; import i5.las2peer.services.ocd.centrality.data.CentralityMeasureType; +import i5.las2peer.services.ocd.centrality.data.CentralityMeta; import i5.las2peer.services.ocd.centrality.data.CentralitySimulationType; -import i5.las2peer.services.ocd.graphs.Cover; -import i5.las2peer.services.ocd.graphs.CoverCreationType; -import i5.las2peer.services.ocd.graphs.CustomGraph; -import i5.las2peer.services.ocd.graphs.GraphCreationType; -import i5.las2peer.services.ocd.graphs.GraphType; +import i5.las2peer.services.ocd.graphs.*; import i5.las2peer.services.ocd.metrics.OcdMetricLog; import i5.las2peer.services.ocd.metrics.OcdMetricType; @@ -37,6 +35,7 @@ import java.io.StringWriter; import java.io.Writer; import java.text.ParseException; +import java.time.LocalDate; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -52,6 +51,7 @@ import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.math3.linear.RealMatrix; +import org.mockito.cglib.core.Local; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -79,7 +79,8 @@ public class RequestHandler { /** * The logger used for request logging. */ - private static final Logger log = Logger.getLogger("Service API"); + //private static final Logger log = Logger.getLogger("Service API"); + private static final GeneralLogger log = new GeneralLogger(); /** * The factory used for creating cover output adapters. @@ -122,7 +123,7 @@ public class RequestHandler { * The exception. */ public synchronized void log(Level level, String message, Exception e) { - log.log(level, message, e); + log.getLogger().log(level, message, e); } /** @@ -134,7 +135,7 @@ public synchronized void log(Level level, String message, Exception e) { * The entry message. */ public synchronized void log(Level level, String message) { - log.log(level, message); + log.getLogger().log(level, message); } /** @@ -166,6 +167,34 @@ public Response writeError(Error error, String errorMessage) { } } + /** + * Creates an xml document string that holds user, user's content + * deletion date and the number of days until the deletion + * @param username User for which the deletion date info is generated + * @param deletionDate Deletion date of the user's content + * @return Xml string of user's content deletion date info + * @throws ParserConfigurationException + */ + public String writeDeletionDate(String username, LocalDate deletionDate) throws ParserConfigurationException { + LocalDate currentDate = LocalDate.now(); + long daysTillDeletion = deletionDate.toEpochDay() - currentDate.toEpochDay(); + + Document doc = getDocument(); + Element deletionInfoElt = doc.createElement("DeletionInfo"); + Element userElt = doc.createElement("User"); + userElt.appendChild(doc.createTextNode(username)); + deletionInfoElt.appendChild(userElt); + Element dateElt = doc.createElement("DeletionDate"); + dateElt.appendChild(doc.createTextNode(String.valueOf(deletionDate))); + deletionInfoElt.appendChild(dateElt); + Element daysTillDeletionElt = doc.createElement("DaysTillDeletion"); + daysTillDeletionElt.appendChild(doc.createTextNode(String.valueOf(daysTillDeletion))); + deletionInfoElt.appendChild(daysTillDeletionElt); + doc.appendChild(deletionInfoElt); + return writeDoc(doc); + } + ///////////////////////// + /** * Transforms a parameter xml into a parameter map. * @@ -264,6 +293,26 @@ public String writeGraphIds(List graphs) throws ParserConfiguration return writeDoc(doc); } + /** + * Creates an XML document containing multiple graph ids. + * This method uses efficient approach and only loads necessary data + * (e.g. no node/edge info is loaded) + * + * @param graphMetas + * The graph meta instances holding graph meta information. + * @return The document. + * @throws ParserConfigurationException if parser config failed + */ + public String writeGraphIdsEfficiently(List graphMetas) throws ParserConfigurationException { + Document doc = getDocument(); + Element graphsElt = doc.createElement("Graphs"); + for (int i = 0; i < graphMetas.size(); i++) { + graphsElt.appendChild(getIdElt(graphMetas.get(i), doc)); + } + doc.appendChild(graphsElt); + return writeDoc(doc); + } + /** * Creates an XML document containing multiple cover ids. * @@ -282,6 +331,26 @@ public String writeCoverIds(List covers) throws ParserConfigurationExcept return writeDoc(doc); } + /** + * Creates an XML document containing multiple cover ids efficiently, + * using CoverMeta instance instead of cover instance. + * + * @param coverMetas + * The covers. + * @return The document. + * @throws ParserConfigurationException if parser config failed + */ + public String writeCoverIdsEfficiently(List coverMetas) throws ParserConfigurationException { + Document doc = getDocument(); + Element coversElt = doc.createElement("Covers"); + for (int i = 0; i < coverMetas.size(); i++) { + coversElt.appendChild(getIdElt(coverMetas.get(i), doc)); + } + doc.appendChild(coversElt); + return writeDoc(doc); + } + + /** * Creates an XML document containing multiple CentralityMap ids. * @param maps The CentralityMaps. @@ -297,7 +366,24 @@ public String writeCentralityMapIds(List maps) throws ParserConfi doc.appendChild(centralityMapElt); return writeDoc(doc); } - + + + /** + * Creates an XML document containing multiple CentralityMap ids. + * @param centralityMetas The meta information list. + * @return The document. + * @throws ParserConfigurationException if parser config failed + */ + public String writeCentralityMapIdsEfficiently(List centralityMetas) throws ParserConfigurationException { + Document doc = getDocument(); + Element centralityMapElt = doc.createElement("CentralityMaps"); + for(int i=0; i graphs) throws AdapterException, return writeDoc(doc); } + /** + * Creates an XML document containing meta information about multiple + * graphs. This is an efficient method that does not load more data + * than necessary (e.g. no node/edge info is loaded) + * + * @param graphMetass The list of graph meta instances that hold graph meta information. + * @return The document. + * @throws AdapterException if adapter failed + * @throws ParserConfigurationException if parser config failed + * @throws IOException if reading failed + * @throws SAXException if parsing failed + * @throws InstantiationException if instantiation failed + * @throws IllegalAccessException if an illegal access occurred on the instance + */ + public String writeGraphMetasEfficiently(List graphMetass) throws AdapterException, ParserConfigurationException, + IOException, SAXException, InstantiationException, IllegalAccessException { + Document doc = getDocument(); + Element graphsElt = doc.createElement("Graphs"); + for (CustomGraphMeta graphMeta : graphMetass) { + String metaDocStr = writeGraphEfficiently(graphMeta); + Node metaDocNode = parseDocumentToNode(metaDocStr); + Node importNode = doc.importNode(metaDocNode, true); + graphsElt.appendChild(importNode); + } + doc.appendChild(graphsElt); + return writeDoc(doc); + } + /** * Creates an XML document containing meta information about multiple * covers. @@ -353,6 +467,34 @@ public String writeCoverMetas(List covers) throws AdapterException, Parse return writeDoc(doc); } + /** + * Creates an XML document containing meta information about multiple + * covers. + * + * @param coverMetas + * The covers' meta information. + * @return The document. + * @throws AdapterException if adapter failed + * @throws ParserConfigurationException if parser config failed + * @throws IOException if reading failed + * @throws SAXException if parsing failed + * @throws InstantiationException if instantiation failed + * @throws IllegalAccessException if an illegal access occurred on the instance + */ + public String writeCoverMetasEfficiently(List coverMetas) throws AdapterException, ParserConfigurationException, + IOException, SAXException, InstantiationException, IllegalAccessException { + Document doc = getDocument(); + Element coversElt = doc.createElement("Covers"); + for (CoverMeta coverMeta : coverMetas) { + String metaDocStr = writeCoverEfficiently(coverMeta); + Node metaDocNode = parseDocumentToNode(metaDocStr); + Node importNode = doc.importNode(metaDocNode, true); + coversElt.appendChild(importNode); + } + doc.appendChild(coversElt); + return writeDoc(doc); + } + /** * Creates an XML document containing meta information about multiple centrality maps. * @param maps The centrality maps. @@ -376,7 +518,32 @@ public String writeCentralityMapMetas(List maps) throws AdapterEx doc.appendChild(mapsElt); return writeDoc(doc); } - + + + /** + * Creates an XML document containing meta information about multiple centrality maps. + * @param centralityMetas The centrality meta information list. + * @return The document. + * @throws AdapterException if adapter failed + * @throws ParserConfigurationException if parser config failed + * @throws IOException if reading failed + * @throws SAXException if parsing failed + * @throws InstantiationException if instantiation failed + * @throws IllegalAccessException if an illegal access occurred on the instance + */ + public String writeCentralityMapMetasEfficiently(List centralityMetas) throws AdapterException, ParserConfigurationException, IOException, SAXException, InstantiationException, IllegalAccessException { + Document doc = getDocument(); + Element mapsElt = doc.createElement("CentralityMaps"); + for(CentralityMeta centralityMetaInfo : centralityMetas) { + String metaDocStr = writeCentralityMapEfficiently(centralityMetaInfo); + Node metaDocNode = parseDocumentToNode(metaDocStr); + Node importNode = doc.importNode(metaDocNode, true); + mapsElt.appendChild(importNode); + } + doc.appendChild(mapsElt); + return writeDoc(doc); + } + /** * Creates an XML document containing the id of a single graph. * @@ -452,6 +619,25 @@ public String writeGraph(CustomGraph graph, GraphOutputFormat outputFormat) return writer.toString(); } + /** + * Creates a graph output in a MetaXml format. This method uses efficient approach. + * Only necessary information is loaded (e.g. no node/edge info) + * The graph. + * + * @param graphMeta + * Graph meta information + * @return The graph output. + * @throws AdapterException if adapter failed + */ + public String writeGraphEfficiently(CustomGraphMeta graphMeta) + throws AdapterException{ + GraphMetaOutputAdapter adapter = new MetaXmlGraphMetaOutputAdapter(); + Writer writer = new StringWriter(); + adapter.setWriter(writer); + adapter.writeGraph(graphMeta); + return writer.toString(); + } + /** * Creates a cover output in a specified format. * @@ -473,6 +659,26 @@ public String writeCover(Cover cover, CoverOutputFormat outputFormat) return writer.toString(); } + /** + * Creates a cover output efficiently in MetaXml format + * + * @param coverMeta + * The cover meta information. + * @return The cover output. + * @throws AdapterException if adapter failed + * @throws InstantiationException if instantiation failed + * @throws IllegalAccessException if an illegal access occurred on the instance + */ + public String writeCoverEfficiently(CoverMeta coverMeta) + throws AdapterException, InstantiationException, IllegalAccessException { + Writer writer = new StringWriter(); + CoverMetaOutputAdapter adapter = new MetaXmlCoverMetaOutputAdapter(); + adapter.setWriter(writer); + adapter.writeCover(coverMeta); + return writer.toString(); + + } + /** * Creates a CentralityMap output. * @param map The CentralityMap. @@ -491,6 +697,25 @@ public String writeCentralityMap(CentralityMap map, CentralityOutputFormat outpu return writer.toString(); } + + /** + * Creates a CentralityMap output in MetaXml format. + * @param centralityMeta + * Metadata about centrality + * @return The CentralityMap output. + * @throws AdapterException if adapter failed + * @throws ParserConfigurationException if parser config failed + * @throws InstantiationException if instantiation failed + * @throws IllegalAccessException if an illegal access occurred on the instance + */ + public String writeCentralityMapEfficiently(CentralityMeta centralityMeta) throws AdapterException, InstantiationException, IllegalAccessException, ParserConfigurationException { + Writer writer = new StringWriter(); + CentralityMetaOutputAdapter adapter = new MetaXmlCentralityMetaOutputAdapter(); + adapter.setWriter(writer); + adapter.writeCentralityMap(centralityMeta); + return writer.toString(); + } + public String writeCentralityMapTopNodes(CentralityMap map, int k) throws AdapterException, InstantiationException, IllegalAccessException, ParserConfigurationException { Writer writer = new StringWriter(); DefaultXmlCentralityOutputAdapter adapter = new DefaultXmlCentralityOutputAdapter(); @@ -706,7 +931,7 @@ public CentralityMap parseCentralityMap(String contentStr, CustomGraph graph, Ce } /** - * Returns an XML element node representing the id of a graph. + * Returns an XML element node representing the id (key) of a graph. * * @param graph * The graph. @@ -717,7 +942,24 @@ public CentralityMap parseCentralityMap(String contentStr, CustomGraph graph, Ce protected Node getIdElt(CustomGraph graph, Document doc) { Element graphElt = doc.createElement("Graph"); Element graphIdElt = doc.createElement("Id"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(graph.getId()))); + graphIdElt.appendChild(doc.createTextNode(graph.getKey())); //done + graphElt.appendChild(graphIdElt); + return graphElt; + } + + /** + * Returns an XML element node representing the id of a graph. + * + * @param graphMeta + * The graph meta information. + * @param doc + * The document to create the element node for. + * @return The element node. + */ + protected Node getIdElt(CustomGraphMeta graphMeta, Document doc) { + Element graphElt = doc.createElement("Graph"); + Element graphIdElt = doc.createElement("Id"); + graphIdElt.appendChild(doc.createTextNode(graphMeta.getKey())); graphElt.appendChild(graphIdElt); return graphElt; } @@ -735,10 +977,32 @@ protected Node getIdElt(Cover cover, Document doc) { Element coverElt = doc.createElement("Cover"); Element idElt = doc.createElement("Id"); Element coverIdElt = doc.createElement("CoverId"); - coverIdElt.appendChild(doc.createTextNode(Long.toString(cover.getId()))); + coverIdElt.appendChild(doc.createTextNode(cover.getKey())); //done + idElt.appendChild(coverIdElt); + Element graphIdElt = doc.createElement("GraphId"); + graphIdElt.appendChild(doc.createTextNode(cover.getGraph().getKey())); //done + idElt.appendChild(graphIdElt); + coverElt.appendChild(idElt); + return coverElt; + } + + /** + * Returns an XML element node representing the id (key) of a cover. + * + * @param coverMeta + * The cover meta information. + * @param doc + * The document to create the element node for. + * @return The element node. + */ + protected Node getIdElt(CoverMeta coverMeta, Document doc) { + Element coverElt = doc.createElement("Cover"); + Element idElt = doc.createElement("Id"); + Element coverIdElt = doc.createElement("CoverId"); + coverIdElt.appendChild(doc.createTextNode(coverMeta.getKey())); idElt.appendChild(coverIdElt); Element graphIdElt = doc.createElement("GraphId"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(cover.getGraph().getId()))); + graphIdElt.appendChild(doc.createTextNode(coverMeta.getGraphKey())); idElt.appendChild(graphIdElt); coverElt.appendChild(idElt); return coverElt; @@ -754,15 +1018,34 @@ protected Node getIdElt(CentralityMap map, Document doc) { Element centralityMapElt = doc.createElement("CentralityMap"); Element idElt = doc.createElement("Id"); Element centralityMapIdElt = doc.createElement("CentralityMapId"); - centralityMapIdElt.appendChild(doc.createTextNode(Long.toString(map.getId()))); + centralityMapIdElt.appendChild(doc.createTextNode(map.getKey())); idElt.appendChild(centralityMapIdElt); Element graphIdElt = doc.createElement("GraphId"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(map.getGraph().getId()))); + graphIdElt.appendChild(doc.createTextNode(map.getGraph().getKey())); //done idElt.appendChild(graphIdElt); centralityMapElt.appendChild(idElt); return centralityMapElt; } + /** + * Returns an XML element node representing the id of a CentralityMap. + * @param centralityMeta The CentralityMap. + * @param doc The document to create the element node for. + * @return The element node. + */ + protected Node getIdElt(CentralityMeta centralityMeta, Document doc) { + Element centralityMapElt = doc.createElement("CentralityMap"); + Element idElt = doc.createElement("Id"); + Element centralityMapIdElt = doc.createElement("CentralityMapId"); + centralityMapIdElt.appendChild(doc.createTextNode(centralityMeta.getCentralityKey())); + idElt.appendChild(centralityMapIdElt); + Element graphIdElt = doc.createElement("GraphId"); + graphIdElt.appendChild(doc.createTextNode(centralityMeta.getGraphKey())); + idElt.appendChild(graphIdElt); + centralityMapElt.appendChild(idElt); + return centralityMapElt; + } + /** * Returns an XML element node representing the id of a metric log. * @@ -776,13 +1059,13 @@ protected Node getIdElt(OcdMetricLog metricLog, Document doc) { Element metricElt = doc.createElement("Metric"); Element idElt = doc.createElement("Id"); Element metricIdElt = doc.createElement("MetricId"); - metricIdElt.appendChild(doc.createTextNode(Long.toString(metricLog.getId()))); + metricIdElt.appendChild(doc.createTextNode(metricLog.getKey())); //done idElt.appendChild(metricIdElt); Element coverIdElt = doc.createElement("CoverId"); - coverIdElt.appendChild(doc.createTextNode(Long.toString(metricLog.getCover().getId()))); + coverIdElt.appendChild(doc.createTextNode(metricLog.getCover().getKey())); //done idElt.appendChild(coverIdElt); Element graphIdElt = doc.createElement("GraphId"); - graphIdElt.appendChild(doc.createTextNode(Long.toString(metricLog.getCover().getGraph().getId()))); + graphIdElt.appendChild(doc.createTextNode(metricLog.getCover().getGraph().getKey())); //done idElt.appendChild(graphIdElt); metricElt.appendChild(idElt); return metricElt; @@ -974,7 +1257,7 @@ public String writePrecisionResult(List maps, double[] precisionV nameElt.appendChild(doc.createTextNode(map.getName())); mapElt.appendChild(nameElt); Element mapIdElt = doc.createElement("CentralityMapId"); - mapIdElt.appendChild(doc.createTextNode(Long.toString(map.getId()))); + mapIdElt.appendChild(doc.createTextNode(map.getKey())); //done mapElt.appendChild(mapIdElt); Element precisionElt = doc.createElement("Precision"); mapElt.appendChild(precisionElt); diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/StatisticalMeasureRunnable.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/StatisticalMeasureRunnable.java index c46c7843..8d35ad04 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/StatisticalMeasureRunnable.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/StatisticalMeasureRunnable.java @@ -56,12 +56,9 @@ public void run() { * Set metric state to running. */ RequestHandler requestHandler = new RequestHandler(); - EntityHandler entityHandler = new EntityHandler(); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + Database database = new Database(false); try { - tx.begin(); - OcdMetricLog persistedLog = em.find(OcdMetricLog.class, logId); + OcdMetricLog persistedLog = database.getOcdMetricLog(logId); if(persistedLog == null) { /* * Should not happen. @@ -70,14 +67,10 @@ public void run() { throw new IllegalStateException(); } persistedLog.setStatus(ExecutionStatus.RUNNING); - tx.commit(); + database.updateOcdMetricLog(persistedLog); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } error = true; } - em.close(); /* * Run metric. */ diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/ThreadHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/ThreadHandler.java index 63bf882c..18e15e47 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/ThreadHandler.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/ThreadHandler.java @@ -74,7 +74,11 @@ public class ThreadHandler { /** * Creates a new instance. */ - private EntityHandler entityHandler = new EntityHandler(); + private static Database database; + + public ThreadHandler() { + database = new Database(false); + } /** * Runs an algorithm. * @param cover The cover that is already persisted but not holding any valid information aside the graph and id. @@ -82,8 +86,8 @@ public class ThreadHandler { * @param componentNodeCountFilter The node count filter used by the OcdAlgorithmExecutor. */ public void runAlgorithm(Cover cover, OcdAlgorithm algorithm, int componentNodeCountFilter) { - CustomGraphId gId = new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()); - CoverId coverId = new CoverId(cover.getId(), gId); + CustomGraphId gId = new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName()); + CoverId coverId = new CoverId(cover.getKey(), gId); AlgorithmRunnable runnable = new AlgorithmRunnable(cover, algorithm, componentNodeCountFilter, this); CoverCreationLog log = cover.getCreationMethod(); synchronized (algorithms) { @@ -98,8 +102,8 @@ public void runAlgorithm(Cover cover, OcdAlgorithm algorithm, int componentNodeC * @param algorithm The algorithm to calculate the centrality values with. */ public void runCentralityAlgorithm(CentralityMap map, CentralityAlgorithm algorithm) { - CustomGraphId gId = new CustomGraphId(map.getGraph().getId(), map.getGraph().getUserName()); - CentralityMapId mapId = new CentralityMapId(map.getId(), gId); + CustomGraphId gId = new CustomGraphId(map.getGraph().getKey(), map.getGraph().getUserName()); + CentralityMapId mapId = new CentralityMapId(map.getKey(), gId); CentralityAlgorithmRunnable runnable = new CentralityAlgorithmRunnable(map, algorithm, this); CentralityCreationLog log = map.getCreationMethod(); synchronized (centralityAlgorithms) { @@ -114,8 +118,8 @@ public void runCentralityAlgorithm(CentralityMap map, CentralityAlgorithm algori * @param simulation The CentralitySimulation to calculate the centrality values with */ public void runCentralitySimulation(CentralityMap map, CentralitySimulation simulation) { - CustomGraphId gId = new CustomGraphId(map.getGraph().getId(), map.getGraph().getUserName()); - CentralityMapId mapId = new CentralityMapId(map.getId(), gId); + CustomGraphId gId = new CustomGraphId(map.getGraph().getKey(), map.getGraph().getUserName()); + CentralityMapId mapId = new CentralityMapId(map.getKey(), gId); CentralitySimulationRunnable runnable = new CentralitySimulationRunnable(map, simulation, this); CentralityCreationLog log = map.getCreationMethod(); synchronized (centralityAlgorithms) { @@ -130,8 +134,8 @@ public void runCentralitySimulation(CentralityMap map, CentralitySimulation simu * @param benchmark The benchmark model to calculate the ground truth cover with. */ public void runGroundTruthBenchmark(Cover cover, GroundTruthBenchmark benchmark) { - CustomGraphId gId = new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()); - CoverId coverId = new CoverId(cover.getId(), gId); + CustomGraphId gId = new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName()); + CoverId coverId = new CoverId(cover.getKey(), gId); GroundTruthBenchmarkRunnable runnable = new GroundTruthBenchmarkRunnable(coverId, benchmark, this); GraphCreationLog log = cover.getGraph().getCreationMethod(); synchronized (benchmarks) { @@ -147,9 +151,9 @@ public void runGroundTruthBenchmark(Cover cover, GroundTruthBenchmark benchmark) * @param cover The cover the metric shall run on. */ public void runStatisticalMeasure(OcdMetricLog metricLog, StatisticalMeasure metric, Cover cover) { - CustomGraphId gId = new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()); - CoverId coverId = new CoverId(cover.getId(), gId); - OcdMetricLogId logId = new OcdMetricLogId(metricLog.getId(), coverId); + CustomGraphId gId = new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName()); + CoverId coverId = new CoverId(cover.getKey(), gId); + OcdMetricLogId logId = new OcdMetricLogId(metricLog.getKey(), coverId); StatisticalMeasureRunnable runnable = new StatisticalMeasureRunnable(logId, metric, cover, this); synchronized (metrics) { Future future = executor.submit(runnable, metricLog); @@ -165,9 +169,9 @@ public void runStatisticalMeasure(OcdMetricLog metricLog, StatisticalMeasure met * @param groundTruth The ground truth cover to be used by the metric. */ public void runKnowledgeDrivenMeasure(OcdMetricLog metricLog, KnowledgeDrivenMeasure metric, Cover cover, Cover groundTruth) { - CustomGraphId gId = new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()); - CoverId coverId = new CoverId(cover.getId(), gId); - OcdMetricLogId logId = new OcdMetricLogId(metricLog.getId(), coverId); + CustomGraphId gId = new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName()); + CoverId coverId = new CoverId(cover.getKey(), gId); + OcdMetricLogId logId = new OcdMetricLogId(metricLog.getKey(), coverId); KnowledgeDrivenMeasureRunnable runnable = new KnowledgeDrivenMeasureRunnable(logId, metric, cover, groundTruth, this); synchronized (metrics) { Future future = executor.submit(runnable, metricLog); @@ -190,11 +194,8 @@ public void createMetric(OcdMetricLog log, OcdMetricLogId logId, boolean error) return; } if(!error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - OcdMetricLog persistedLog = em.find(OcdMetricLog.class, logId); + try { + OcdMetricLog persistedLog = database.getOcdMetricLog(logId); if(persistedLog == null) { /* * Should not happen. @@ -204,21 +205,17 @@ public void createMetric(OcdMetricLog log, OcdMetricLogId logId, boolean error) } persistedLog.setValue(log.getValue()); persistedLog.setStatus(ExecutionStatus.COMPLETED); - tx.commit(); + database.updateOcdMetricLog(persistedLog); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + error = true; } - em.close(); + } if(error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - OcdMetricLog persistedLog = em.find(OcdMetricLog.class, logId); + OcdMetricLog persistedLog = database.getOcdMetricLog(logId); if(persistedLog == null) { /* * Should not happen. @@ -227,13 +224,11 @@ public void createMetric(OcdMetricLog log, OcdMetricLogId logId, boolean error) throw new IllegalStateException(); } persistedLog.setStatus(ExecutionStatus.ERROR); - tx.commit(); + database.updateOcdMetricLog(persistedLog); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + e.printStackTrace(); } - em.close(); + } unsynchedInterruptMetric(logId); } @@ -248,17 +243,19 @@ public void createMetric(OcdMetricLog log, OcdMetricLogId logId, boolean error) * @param error Indicates whether an error occurred (true) during the calculation. */ public void createGroundTruthCover(Cover calculatedCover, CoverId coverId, boolean error) { + String cKey = coverId.getKey(); + CustomGraphId gId = coverId.getGraphId(); + String user = gId.getUser(); + String gKey = gId.getKey(); synchronized (benchmarks) { if(Thread.interrupted()) { Thread.currentThread().interrupt(); return; } if(!error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { /* * Should not happen. @@ -266,19 +263,18 @@ public void createGroundTruthCover(Cover calculatedCover, CoverId coverId, boole requestHandler.log(Level.WARNING, "Cover deleted while benchmark running."); throw new IllegalStateException(); } - cover.getGraph().setStructureFrom(calculatedCover.getGraph()); - cover.getGraph().getCreationMethod().setStatus(ExecutionStatus.COMPLETED); - tx.commit(); + CustomGraph graph = cover.getGraph(); + graph.setStructureFrom(calculatedCover.getGraph()); + graph.getCreationMethod().setStatus(ExecutionStatus.COMPLETED); + graph.setNodeEdgeCountColumnFields(); // before persisting to db, update node/edge count information + database.updateGraph(graph); } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); + error = true; } - em.close(); - em = entityHandler.getEntityManager(); - tx = em.getTransaction(); + try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { /* * Should not happen. @@ -288,19 +284,17 @@ public void createGroundTruthCover(Cover calculatedCover, CoverId coverId, boole } cover.setMemberships(calculatedCover.getMemberships()); cover.getCreationMethod().setStatus(ExecutionStatus.COMPLETED); - tx.commit(); + database.updateCover(cover); } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); + error = true; } - em.close(); + } if(error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { /* * Should not happen. @@ -310,17 +304,15 @@ public void createGroundTruthCover(Cover calculatedCover, CoverId coverId, boole } CustomGraph graph = cover.getGraph(); cover.getCreationMethod().setStatus(ExecutionStatus.ERROR); + database.updateCoverCreationLog(cover); //TODO optimieren graph.getCreationMethod().setStatus(ExecutionStatus.ERROR); - tx.commit(); + database.updateGraphCreationLog(graph); //TODO muss beides in transaktion? } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + } - em.close(); + } - CustomGraphId graphId = coverId.getGraphId(); - unsynchedInterruptBenchmark(graphId); + unsynchedInterruptBenchmark(gId); } } @@ -333,17 +325,19 @@ public void createGroundTruthCover(Cover calculatedCover, CoverId coverId, boole * @param error States whether an error occurred (true) during execution. */ public void createCover(Cover calculatedCover, CoverId coverId, boolean error) { + String cKey = coverId.getKey(); + CustomGraphId gId = coverId.getGraphId(); + String user = gId.getUser(); + String gKey = gId.getKey(); synchronized (algorithms) { if(Thread.interrupted()) { Thread.currentThread().interrupt(); return; } if(!error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { /* * Should not happen. @@ -357,21 +351,16 @@ public void createCover(Cover calculatedCover, CoverId coverId, boolean error) { log.setStatus(ExecutionStatus.COMPLETED); cover.addMetric(log); cover.getCreationMethod().setStatus(ExecutionStatus.COMPLETED); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + database.updateCover(cover); + } catch(Exception e ) { error = true; } - em.close(); + } if(error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - Cover cover = em.find(Cover.class, coverId); + Cover cover = database.getCover(user, gKey, cKey); if(cover == null) { /* * Should not happen. @@ -380,13 +369,11 @@ public void createCover(Cover calculatedCover, CoverId coverId, boolean error) { throw new IllegalStateException(); } cover.getCreationMethod().setStatus(ExecutionStatus.ERROR); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + database.updateCoverCreationLog(cover); + } catch( Exception e ) { + e.printStackTrace(); } - em.close(); + } unsynchedInterruptAlgorithm(coverId); } @@ -401,17 +388,19 @@ public void createCover(Cover calculatedCover, CoverId coverId, boolean error) { * @param error States whether an error occurred (true) during execution. */ public void createCentralityMap(CentralityMap calculatedMap, CentralityMapId mapId, boolean error) { + String mKey = mapId.getKey(); + CustomGraphId gId = mapId.getGraphId(); + String user = gId.getUser(); + String gKey = gId.getKey(); synchronized (centralityAlgorithms) { if(Thread.interrupted()) { Thread.currentThread().interrupt(); return; } if(!error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - CentralityMap map = em.find(CentralityMap.class, mapId); + CentralityMap map = database.getCentralityMap(user, gKey, mKey); if(map == null) { /* * Should not happen. @@ -422,21 +411,16 @@ public void createCentralityMap(CentralityMap calculatedMap, CentralityMapId map map.setMap(calculatedMap.getMap()); map.getCreationMethod().setStatus(ExecutionStatus.COMPLETED); map.getCreationMethod().setExecutionTime(calculatedMap.getCreationMethod().getExecutionTime()); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + database.updateCentralityMap(map); + } catch(RuntimeException e ) { error = true; } - em.close(); + } if(error) { - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); + try { - tx.begin(); - CentralityMap map = em.find(CentralityMap.class, mapId); + CentralityMap map = database.getCentralityMap(user, gKey, mKey); if(map == null) { /* * Should not happen. @@ -445,13 +429,11 @@ public void createCentralityMap(CentralityMap calculatedMap, CentralityMapId map throw new IllegalStateException(); } map.getCreationMethod().setStatus(ExecutionStatus.ERROR); - tx.commit(); + database.updateCentralityCreationLog(map); } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } + } - em.close(); + } unsynchedInterruptAlgorithm(mapId); } @@ -496,7 +478,7 @@ public void interruptMetric(OcdMetricLogId logId) { */ public void interruptAll(Cover cover) { synchronized (algorithms) { - unsynchedInterruptAlgorithm(new CoverId(cover.getId(), new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName()))); + unsynchedInterruptAlgorithm(new CoverId(cover.getKey(), new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName()))); } synchronized (metrics) { unsynchedInterruptAllMetrics(cover); @@ -509,7 +491,7 @@ public void interruptAll(Cover cover) { */ public void interruptAll(CentralityMap map) { synchronized (centralityAlgorithms) { - unsynchedInterruptAlgorithm(new CentralityMapId(map.getId(), new CustomGraphId(map.getGraph().getId(), map.getGraph().getUserName()))); + unsynchedInterruptAlgorithm(new CentralityMapId(map.getKey(), new CustomGraphId(map.getGraph().getKey(), map.getGraph().getUserName()))); } } @@ -551,7 +533,7 @@ private void unsynchedInterruptBenchmark(CustomGraphId graphId) { /** * Interrupts a metric execution without synchronization. - * @param cover The cover the metric is run on. + * @param logId The id of the reserved persisted log the metric is calculating. */ private void unsynchedInterruptMetric(OcdMetricLogId logId) { @@ -567,9 +549,9 @@ private void unsynchedInterruptMetric(OcdMetricLogId logId) { * @param cover The cover. */ private void unsynchedInterruptAllMetrics(Cover cover) { - CoverId coverId = new CoverId(cover.getId(), new CustomGraphId(cover.getGraph().getId(), cover.getGraph().getUserName())); + CoverId coverId = new CoverId(cover.getKey(), new CustomGraphId(cover.getGraph().getKey(), cover.getGraph().getUserName())); for(OcdMetricLog log : cover.getMetrics()) { - OcdMetricLogId logId = new OcdMetricLogId(log.getId(), coverId); + OcdMetricLogId logId = new OcdMetricLogId(log.getKey(), coverId); unsynchedInterruptMetric(logId); } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/UserLimitsHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/UserLimitsHandler.java new file mode 100644 index 00000000..02a1929f --- /dev/null +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/utils/UserLimitsHandler.java @@ -0,0 +1,148 @@ +package i5.las2peer.services.ocd.utils; + +import i5.las2peer.services.ocd.graphs.CustomGraph; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; + +import java.io.FileReader; +import java.util.List; + +/** + * This class handles limits both to specific users. The limits are read from + * etc/userLimitInformation.json file. If no user specific limits are given, + * then the default limits apply. Limits relate to how long the user can + * refrain from logging in before user content gets removed, as well as + * the number and size of graphs/covers etc. + */ +public class UserLimitsHandler { + + /** + * Parser for user limit data from the input json file + */ + private JSONParser jsonParser = new JSONParser(); + + /** + * JSON Object to hold default limit information used for users who don't have custom limits set + */ + private JSONObject defaultUserLimits; + + /** + * Database. + */ + + private Database database; + + + public UserLimitsHandler(Database database) { + this.database = database; + } + + /** + * This method returns json object with information about various limits applied to the given user. Limits are set + * in etc/userLimitInformation.json + * + * @param username username the limits of which should be returned + * @return json object with user limit info + */ + public JSONObject getUserLimits(String username) { + + // limits set for user in userLimitInformation.json file + JSONObject userLimits; + try { + /* try to find specified user limits */ + JSONArray userLimitsJson = (JSONArray) jsonParser.parse(new FileReader("etc/userLimitInformation.json")); + for (Object o : userLimitsJson) { + userLimits = (JSONObject) o; + String limitedUser = (String) userLimits.get("username"); + if (limitedUser.equals(username)) { + return userLimits; + } + if (limitedUser.equals("default")) { + defaultUserLimits = userLimits; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + /* if user limit was not found, apply default limits */ + return defaultUserLimits; + } + + /** + * Returns number of days a given user can be inactive before user content is removed + * + * @param username User for which the inactivity should be checked + * @return Number of inactive days allowed + */ + public int getAllowedInactivityDays(String username) { + + // limits set for user in userLimitInformation.json file + JSONObject userLimits = getUserLimits(username); + if (userLimits != null) { + // Graph count limit check + if (userLimits.get("allowedInactiveDays") != null) { + /* If user has inactivity limit set then return it */ + return Integer.parseInt((String) userLimits.get("allowedInactiveDays")); + } + } + /* If code came here then no user limit is set. Return default inactivity limit */ + userLimits = getUserLimits("default"); + return Integer.parseInt((String) userLimits.get("allowedInactiveDays")); + } + + /** + * Check whether user has limit on number of graphs it can generate. + * + * @param username user to check the limits for + * @return true if the limit is reached + */ + public Boolean reachedGraphCountLimit(String username) { + // limits set for user in userLimitInformation.json file + JSONObject userLimits = getUserLimits(username); + if (userLimits != null) { + // Graph count limit check + try { + List userGraphs = database.getGraphs(username); + if (userLimits.get("graphCount") != null + && userGraphs.size() >= Integer.parseInt((String) userLimits.get("graphCount"))) { + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return false; + } + + /** + * Check whether user has limit on number of covers it can generate. + * + * @param username user to check the limits for + * @return true if the limit is reached + */ + public Boolean reachedCoverCountLimit(String username) { + // limits set for user in userLimitInformation.json file + JSONObject userLimits = getUserLimits(username); + if (userLimits != null) { + // Graph count limit check + try { + List userGraphs = database.getGraphs(username); + // Cover count limit check + int numberOfUserCovers = 0; + for (CustomGraph userGraph : userGraphs) { + numberOfUserCovers += database.getCovers(username, userGraph.getKey()).size(); + } + if (userLimits.get("coverCount") != null + && numberOfUserCovers >= Integer.parseInt((String) userLimits.get("coverCount"))) { + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return false; + } + + +} diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/LayoutHandler.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/LayoutHandler.java index 18dd684d..53dd3b9f 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/LayoutHandler.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/LayoutHandler.java @@ -13,27 +13,22 @@ import i5.las2peer.services.ocd.viewer.utils.CentralityVisualizationType; import java.awt.Color; +import java.util.Iterator; import java.util.List; +import java.util.concurrent.TimeUnit; -import y.base.Edge; -import y.base.EdgeCursor; -import y.base.Node; -import y.base.NodeCursor; -import y.view.Arrow; -import y.view.DefaultGraph2DRenderer; -import y.view.EdgeLabel; -import y.view.EdgeRealizer; -import y.view.Graph2DView; -import y.view.NodeLabel; -import y.view.NodeRealizer; -import y.view.ShapeNodeRealizer; -import y.view.SmartNodeLabelModel; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + +import org.graphstream.ui.layout.Layout; +import org.graphstream.ui.layout.springbox.implementations.SpringBox; /** * Manages the integration of all layouting phases. * @author Sebastian * */ +//TODO: Currently we need to work solely with the ui.style attribute of elements since the SVG visualization of graphstream refuses to look at other attributes, we should change to use single attributes when it it is possible public class LayoutHandler { private static final Color CENTRALITY_COLOR = Color.BLUE; private static final Color CENTRALITY_GRADIENT_MIN = Color.GREEN; @@ -61,22 +56,23 @@ public class LayoutHandler { * @param maxNodeSize Defines the maximum size of a node. Must be at least as high as the defined minimum size. * @throws InstantiationException if instantiation failed * @throws IllegalAccessException if an illegal access occurred on the instance + * @throws InterruptedException If the executing thread was interrupted. */ public void doLayout(CustomGraph graph, GraphLayoutType layoutType, boolean doLabelNodes, boolean doLabelEdges, - double minNodeSize, double maxNodeSize) throws InstantiationException, IllegalAccessException { + double minNodeSize, double maxNodeSize) throws InstantiationException, IllegalAccessException, InterruptedException { setLayoutDefaults(graph, minNodeSize, maxNodeSize); labelGraph(graph, doLabelNodes, doLabelEdges); GraphLayouter layouter = graphLayouterFactory.getInstance(layoutType); layouter.doLayout(graph); - setViewDefaults(new Graph2DView(graph)); + setViewDefaults(graph); } /** * Sets the default layout attributes for a graph, such as node and edge shapes and node sizes. * @param graph the graph */ - private void setLayoutDefaults(CustomGraph graph, double minNodeSize, double maxNodeSize) { - NodeCursor nodes = graph.nodes(); + private void setLayoutDefaults(CustomGraph graph, double minNodeSize, double maxNodeSize) throws InterruptedException { + Iterator nodesIt = graph.iterator(); Node node; /* * Node size scaling factor @@ -85,48 +81,25 @@ private void setLayoutDefaults(CustomGraph graph, double minNodeSize, double max double maxDegree = graph.getMaxWeightedInDegree(); double degreeDifference = (maxDegree == minDegree) ? 1.0 : (maxDegree - minDegree); double scalingFactor = (maxNodeSize - minNodeSize) / degreeDifference; - while(nodes.ok()) { - node = nodes.node(); - ShapeNodeRealizer nRealizer = new ShapeNodeRealizer(graph.getRealizer(node)); - graph.setRealizer(node, nRealizer); - nRealizer.setShapeType(ShapeNodeRealizer.ELLIPSE); + while(nodesIt.hasNext()) { + node = nodesIt.next(); + double curNodeSize = minNodeSize + (graph.getWeightedInDegree(node) - minDegree) * scalingFactor; - nRealizer.setSize(curNodeSize, curNodeSize); - nodes.next(); - } - EdgeCursor edges = graph.edges(); - Edge edge; - while(edges.ok()) { - edge = edges.edge(); - EdgeRealizer eRealizer = graph.getRealizer(edge); - if(graph.isOfType(GraphType.DIRECTED)) { - eRealizer.setArrow(Arrow.STANDARD); - } - edges.next(); - } - } - - /** - * Sets the layout attributes of a graph for visualizing a CentralityMap. - * @param graph The graph of the CentralityMap that is visualized - */ - private void setCentralityLayoutDefaults(CustomGraph graph) { - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); - ShapeNodeRealizer nRealizer = new ShapeNodeRealizer(graph.getRealizer(node)); - graph.setRealizer(node, nRealizer); - nRealizer.setShapeType(ShapeNodeRealizer.ELLIPSE); - nodes.next(); + //"Declare" nodestyles + node.setAttribute("ui.style", "fill-color: rgba(" + 200 + "," + 200 + "," + 240 + "," + 255 + ");" + + "shape: circle; size: "+ curNodeSize +";"); + node.setAttribute("ui.size", curNodeSize); // needed for JsonVisualOutputAdapter } + + String arrowShape = "none"; if(graph.isOfType(GraphType.DIRECTED)) { - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); - EdgeRealizer eRealizer = graph.getRealizer(edge); - eRealizer.setArrow(Arrow.STANDARD); - edges.next(); - } + arrowShape = "arrow"; + } + Iterator edgesIt = graph.edges().iterator(); + + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("ui.style", "arrow-shape: "+ arrowShape + ";"); //TODO: Doesnt currently have any effect since we have to use graphstream directed type edges and SVG does not style them based on the style attribute } } @@ -141,18 +114,55 @@ private void setCentralityLayoutDefaults(CustomGraph graph) { * @param paintingType The painting type defining which cover painter to use. * @throws InstantiationException if instantiation failed * @throws IllegalAccessException if an illegal access occurred on the instance + * @throws InterruptedException If the executing thread was interrupted. */ public void doLayout(Cover cover, GraphLayoutType layoutType, boolean doLabelNodes, boolean doLabelEdges, - double minNodeSize, double maxNodeSize, CoverPaintingType paintingType) throws InstantiationException, IllegalAccessException { + double minNodeSize, double maxNodeSize, CoverPaintingType paintingType) throws InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = cover.getGraph(); - setLayoutDefaults(graph, minNodeSize, maxNodeSize); + setCoverLayoutDefaults(graph, minNodeSize, maxNodeSize); labelGraph(graph, doLabelNodes, doLabelEdges); GraphLayouter layouter = graphLayouterFactory.getInstance(layoutType); layouter.doLayout(graph); CoverPainter painter = coverPainterFactory.getInstance(paintingType); painter.doPaint(cover); paintNodes(cover); - setViewDefaults(new Graph2DView(graph)); + setViewDefaults(graph); + + } + + /** + * Sets the default layout attributes for a graph visualizing a cover, such as node and edge shapes and node sizes. + * @param graph the graph + */ + private void setCoverLayoutDefaults(CustomGraph graph, double minNodeSize, double maxNodeSize) throws InterruptedException { + Iterator nodesIt = graph.iterator(); + Node node; + /* + * Node size scaling factor + */ + double minDegree = graph.getMinWeightedInDegree(); + double maxDegree = graph.getMaxWeightedInDegree(); + double degreeDifference = (maxDegree == minDegree) ? 1.0 : (maxDegree - minDegree); + double scalingFactor = (maxNodeSize - minNodeSize) / degreeDifference; + while(nodesIt.hasNext()) { + node = nodesIt.next(); + double curNodeSize = minNodeSize + (graph.getWeightedInDegree(node) - minDegree) * scalingFactor; + //"Declare" nodestyles + node.setAttribute("ui.style", "shape: circle; size: "+ curNodeSize +";"); + //TODO: Ideally we shouldn't need a separate ui.size attribute and should be able to use the size from ui.style + node.setAttribute("ui.size", curNodeSize); // set directly accessible attribute for node size + } + + String arrowShape = "none"; + if(graph.isOfType(GraphType.DIRECTED)) { + arrowShape = "arrow"; + } + Iterator edgesIt = graph.edges().iterator(); + + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("ui.style", "arrow-shape: "+ arrowShape + ";"); + } } /** @@ -183,18 +193,49 @@ public void doLayout(CentralityMap map, GraphLayoutType layoutType, boolean doLa setProportionalNodeSizes(map); break; } - setViewDefaults(new Graph2DView(graph)); + setViewDefaults(graph); + } + + /** + * Sets the layout attributes of a graph for visualizing a CentralityMap. + * @param graph The graph of the CentralityMap that is visualized + */ + private void setCentralityLayoutDefaults(CustomGraph graph) { + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); + node.setAttribute("ui.shape", "circle;"); + + int defaultCentralityNodeSize = 30; + node.setAttribute("ui.style","size: "+ defaultCentralityNodeSize +";"+ "fill-color: rgba(" + 200 + "," + 200 + "," + 240 + "," + 255 + ");"); // default color + + + } + + String arrowShape = "none"; + if(graph.isOfType(GraphType.DIRECTED)) { + arrowShape = "arrow"; + } + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("ui.style", "arrow-shape: "+ arrowShape + ";"); + } } /** * Sets the view default attributes, such as the rendering order. - * @param view the graph view + * @param graph the graph view */ - private void setViewDefaults(Graph2DView view) { - DefaultGraph2DRenderer renderer = new DefaultGraph2DRenderer(); - view.setGraph2DRenderer(renderer); - renderer.setDrawEdgesFirst(true); - view.fitContent(); + private void setViewDefaults(CustomGraph graph) { + graph.setAttribute("ui.stylesheet", + "node {" + + " z-index: 2;" + + "}" + + "edge {" + + " z-index: 1;" + + "}"); + } /** @@ -205,31 +246,33 @@ private void setViewDefaults(Graph2DView view) { */ private void labelGraph(CustomGraph graph, boolean doLabelNodes, boolean doLabelEdges) { if(doLabelNodes) { - NodeCursor nodes = graph.nodes(); - while (nodes.ok()) { - Node node = nodes.node(); - // gets node realizer - NodeRealizer nRealizer = graph.getRealizer(node); + Iterator nodes = graph.iterator(); + while (nodes.hasNext()) { + Node node = nodes.next(); // adds name label - NodeLabel nameLabel = nRealizer.createNodeLabel(); - nameLabel.setText(graph.getNodeName(node)); - SmartNodeLabelModel nameModel = new SmartNodeLabelModel(); - nameLabel.setLabelModel(nameModel, nameModel.createDiscreteModelParameter(SmartNodeLabelModel.POSITION_CENTER)); - nRealizer.addLabel(nameLabel); - nodes.next(); + node.setAttribute("label", graph.getNodeName(node)); //For SVG Viz label needs to not have "ui." in front, for graphstream desktop UIs it does + String initial_string = ""; + if(node.getAttribute("ui.style") != null){ + initial_string += node.getAttribute("ui.style"); + } + node.setAttribute("ui.style",initial_string + "text-alignment: center;" + + "text-size: 12;" + + "text-style: bold;" + + "text-font: Arial;"); } } - if(doLabelEdges) { - EdgeCursor edges = graph.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); - // gets edge realizer - EdgeRealizer eRealizer = graph.getRealizer(edge); - // adds weight label - EdgeLabel weightLabel = eRealizer.createEdgeLabel(); - weightLabel.setText(Double.toString(graph.getEdgeWeight(edge))); - eRealizer.addLabel(weightLabel); - edges.next(); + + Iterator edgesIt = graph.edges().iterator(); + while (edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + // adds weight label + + if(doLabelEdges) { + edge.setAttribute("label", graph.getEdgeWeight(edge)); //For SVG Viz label needs to not have "ui." in front, for graphstream desktop UIs it does + edge.setAttribute("ui.style",edge.getAttribute("ui.style") + "text-alignment: along;" + + "text-size: 12;" + + "text-style: bold;" + + "text-font: Arial;"); } } } @@ -243,13 +286,13 @@ private void labelGraph(CustomGraph graph, boolean doLabelNodes, boolean doLabel */ private void paintNodes(Cover cover) { CustomGraph graph = cover.getGraph(); - NodeCursor nodes = graph.nodes(); + Iterator nodesIt = graph.iterator(); float[] curColorCompArray = new float[4]; float[] colorCompArray; Node node; - while(nodes.ok()) { + while(nodesIt.hasNext()) { colorCompArray = new float[4]; - node = nodes.node(); + node = nodesIt.next(); List communityIndices = cover.getCommunityIndices(node); for(int index : communityIndices) { Color comColor = cover.getCommunityColor(index); @@ -258,9 +301,11 @@ private void paintNodes(Cover cover) { colorCompArray[i] += curColorCompArray[i] * cover.getBelongingFactor(node, index); } } - NodeRealizer nRealizer = graph.getRealizer(node); - nRealizer.setFillColor(new Color(colorCompArray[0], colorCompArray[1], colorCompArray[2], colorCompArray[3])); - nodes.next(); + //TODO: Make nicer so that java color is not needed + Color color = new Color(colorCompArray[0], colorCompArray[1], colorCompArray[2], colorCompArray[3]); + node.setAttribute("ui.style",node.getAttribute("ui.style") + "fill-color: rgba(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," + color.getAlpha() + ");"); + //TODO: Ideally we shouldn't need a separate ui.fill-color attribute and should be able to use the value from ui.style + node.setAttribute("ui.fill-color", new float[]{color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()/255}); // set directly accessible color attribute for node } } @@ -277,14 +322,13 @@ private void paintNodesWithSingleColor(CentralityMap map) { double min = map.getMinValue(); double max = map.getMaxValue(); CustomGraph graph = map.getGraph(); - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); - NodeRealizer nRealizer = graph.getRealizer(node); + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); float nodeSaturation = (float) ((map.getNodeValue(node) - min) / (max - min)); - Color nodeColor = Color.getHSBColor(hsbValues[0], nodeSaturation, hsbValues[2]); - nRealizer.setFillColor(nodeColor); - nodes.next(); + Color color = Color.getHSBColor(hsbValues[0], nodeSaturation, hsbValues[2]); // Use HSB for saturation here + node.setAttribute("ui.style",node.getAttribute("ui.style") + "fill-color: rgba(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," + color.getAlpha() + ");"); + node.setAttribute("ui.fill-color", new float[]{color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()/255}); // TODO: new. set directly accessible color attribute for node, used for JSON visiualization adapter } } @@ -306,15 +350,15 @@ private void paintNodesWithColorGradient(CentralityMap map) { double min = map.getMinValue(); double max = map.getMaxValue(); CustomGraph graph = map.getGraph(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); - NodeRealizer nRealizer = graph.getRealizer(node); + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); double centralityValue = map.getNodeValue(node); float hue = (float) (hsbValuesMin[0] + (hsbValuesMax[0] - hsbValuesMin[0]) * (centralityValue - min) / (max - min)); - Color nodeColor = Color.getHSBColor(hue, 1.0f, 1.0f); - nRealizer.setFillColor(nodeColor); - nc.next(); + Color color = Color.getHSBColor(hue, 1.0f, 1.0f); + node.setAttribute("ui.style",node.getAttribute("ui.style") + "fill-color: rgba(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," + color.getAlpha() + ");"); + node.setAttribute("ui.fill-color", new float[]{color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()/255}); // set directly accessible color attribute for node + } } @@ -326,15 +370,18 @@ private void paintNodesWithColorGradient(CentralityMap map) { private void setProportionalNodeSizes(CentralityMap map) { double min = map.getMinValue(); double max = map.getMaxValue(); + if (max == min){ + // avoid division by 0 + max++; + } CustomGraph graph = map.getGraph(); - NodeCursor nc = graph.nodes(); - while(nc.ok()) { - Node node = nc.node(); - NodeRealizer nRealizer = graph.getRealizer(node); + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); double centralityValue = map.getNodeValue(node); - double nodeSize = MIN_NODE_SIZE + (MAX_NODE_SIZE - MIN_NODE_SIZE) * (centralityValue - min) / (max - min); - nRealizer.setSize(nodeSize, nodeSize); - nc.next(); + double nodeSize = MIN_NODE_SIZE + (MAX_NODE_SIZE - MIN_NODE_SIZE) * (centralityValue - min) / (max - min); + node.setAttribute("ui.style",node.getAttribute("ui.style") + "size:" + nodeSize +";"); + node.setAttribute("ui.size", nodeSize); // needed for JsonVisualOutputAdapter } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/layouters/OrganicGraphLayouter.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/layouters/OrganicGraphLayouter.java index 1933b2dc..f6300cad 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/layouters/OrganicGraphLayouter.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/layouters/OrganicGraphLayouter.java @@ -2,40 +2,63 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.layout.ParallelEdgeLayouter; -import y.layout.organic.SmartOrganicLayouter; -import y.layout.router.OrganicEdgeRouter; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + +import java.util.Iterator; /** * Organic layouter, based on the Organic Layout Style of the yFiles library. * @author Sebastian * */ +//TODO: Check how all of the yFiles attributes can even be realized +//TODO: Might have to freeze layout at some point (->when?) public class OrganicGraphLayouter implements GraphLayouter { @Override public void doLayout(CustomGraph graph) { - SmartOrganicLayouter layouter = new SmartOrganicLayouter(); - layouter.setMinimalNodeDistance(45); - layouter.setConsiderNodeLabelsEnabled(true); - layouter.setNodeOverlapsAllowed(false); - layouter.setCompactness(0.2); - if(graph.isOfType(GraphType.DIRECTED)) { - ParallelEdgeLayouter parallelLayouter = new ParallelEdgeLayouter(layouter); - parallelLayouter.setDirectedModeEnabled(true); - parallelLayouter.setLineDistance(10); - parallelLayouter.setLeadingEdgeAdjustmentEnabled(false); - parallelLayouter.doLayout(graph); + graph.setAttribute("ui.stylesheet", + "graph {" + + " padding: 2;" + + "" + + "}" + + "node {" + + " text-mode: normal;" + + "}"); + Iterator nodesIt = graph.nodes().iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); + node.setAttribute("ui.style",node.getAttribute("ui.style") + "stroke-mode: plain;" + + "stroke-color: black;" + + "stroke-width: 1;"); } - else { - OrganicEdgeRouter router = new OrganicEdgeRouter(); - router.setCoreLayouter(layouter); - router.setEdgeNodeOverlapAllowed(false); - router.setMinimalDistance(5); - router.setRoutingAll(true); - router.setUsingBends(false); - router.doLayout(graph); + if (graph.isOfType(GraphType.DIRECTED)) { + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("ui.style", edge.getAttribute("ui.style") + "fill-color: black; shape: line; size: 1.5;"); + } + } else { + Iterator edgesIt = graph.edges().iterator(); + while(edgesIt.hasNext()) { + Edge edge = edgesIt.next(); + edge.setAttribute("ui.style", edge.getAttribute("ui.style") + "fill-color: black; shape: line; size: 1.5;"); + } } + + graph.layout.shake(); + graph.layout.compute(); + + while (graph.layout.getStabilization() < 0.95) { + graph.layout.compute(); + } + //For Debugging + //System.setProperty("org.graphstream.ui", "swing"); + //graph.display(); + + //while(true); + //For Debugging } } diff --git a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/utils/CentralityVisualizationType.java b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/utils/CentralityVisualizationType.java index 69fac1c0..87da5ab4 100644 --- a/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/utils/CentralityVisualizationType.java +++ b/rest_ocd_services/src/main/java/i5/las2peer/services/ocd/viewer/utils/CentralityVisualizationType.java @@ -25,7 +25,6 @@ public enum CentralityVisualizationType implements EnumDisplayNames { /** * Creates a new instance. - * @param adapterClass Defines the adapterClass attribute. * @param id Defines the id attribute. */ private CentralityVisualizationType(String displayName, int id) { diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/DatabaseInitializer.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/DatabaseInitializer.java deleted file mode 100644 index 3f51b6d3..00000000 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/DatabaseInitializer.java +++ /dev/null @@ -1,111 +0,0 @@ -package i5.las2peer.services.ocd; - -import i5.las2peer.services.ocd.adapters.AdapterException; -import i5.las2peer.services.ocd.algorithms.OcdAlgorithm; -import i5.las2peer.services.ocd.algorithms.OcdAlgorithmExecutor; -import i5.las2peer.services.ocd.algorithms.RandomWalkLabelPropagationAlgorithm; -import i5.las2peer.services.ocd.algorithms.SpeakerListenerLabelPropagationAlgorithm; -import i5.las2peer.services.ocd.algorithms.utils.OcdAlgorithmException; -import i5.las2peer.services.ocd.graphs.Cover; -import i5.las2peer.services.ocd.graphs.CoverId; -import i5.las2peer.services.ocd.graphs.CustomGraph; -import i5.las2peer.services.ocd.graphs.CustomGraphId; -import i5.las2peer.services.ocd.metrics.ExtendedModularityMetric; -import i5.las2peer.services.ocd.metrics.OcdMetricException; -import i5.las2peer.services.ocd.metrics.OcdMetricExecutor; -import i5.las2peer.services.ocd.metrics.StatisticalMeasure; -import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; - -import java.io.FileNotFoundException; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; - -import org.junit.Ignore; -import org.junit.Test; - -/** - * This class is designed for database initialization through jUnit tests. - * All tests will be executed when running the 'database' target of the ant build file. - */ -@Ignore -public class DatabaseInitializer { - - EntityManagerFactory emf = Persistence.createEntityManagerFactory("ocd"); - - private final String username = "User"; - - public CustomGraphId createGraph(CustomGraph graph) { - graph.setUserName(username); - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); - return new CustomGraphId(graph.getId(), username); - } - - public CoverId createRealWorldCover(OcdAlgorithm algorithm, CustomGraphId gId, String name, List statMetrics) throws OcdAlgorithmException, InterruptedException, OcdMetricException { - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - CustomGraph graph; - Cover cover; - try { - tx.begin(); - graph = em.find(CustomGraph.class, gId); - OcdAlgorithmExecutor algoExecutor = new OcdAlgorithmExecutor(); - cover = algoExecutor.execute(graph, algorithm, 0); - OcdMetricExecutor metricExecutor = new OcdMetricExecutor(); - for(StatisticalMeasure metric : statMetrics) { - metricExecutor.executeStatisticalMeasure(cover, metric); - } - cover.setName(name); - em.persist(cover); - tx.commit(); - } catch( RuntimeException e ) { - if( tx != null && tx.isActive() ) { - tx.rollback(); - } - throw e; - } - em.close(); - return new CoverId(cover.getId(), gId); - } - - @Test - public void initDatabase() throws AdapterException, FileNotFoundException, OcdAlgorithmException, OcdMetricException, InterruptedException { - CustomGraph graph = OcdTestGraphFactory.getAperiodicTwoCommunitiesGraph(); - CustomGraphId aperiodicId = createGraph(graph); - graph = OcdTestGraphFactory.getSawmillGraph(); - CustomGraphId sawmillId = createGraph(graph); - graph = OcdTestGraphFactory.getDolphinsGraph(); - createGraph(graph); - graph = OcdTestGraphFactory.getDirectedAperiodicTwoCommunitiesGraph(); - createGraph(graph); - DecimalFormat df = new DecimalFormat("00"); - for(int i=0; i<10; i++) { - graph = OcdTestGraphFactory.getMiniServiceTestGraph(); - graph.setName(graph.getName() + " " + df.format(i)); - createGraph(graph); - } - List statMetrics = new ArrayList(); - statMetrics.add(new ExtendedModularityMetric()); - createRealWorldCover(new SpeakerListenerLabelPropagationAlgorithm(), aperiodicId, "SLPA on ATC", statMetrics); - createRealWorldCover(new SpeakerListenerLabelPropagationAlgorithm(), sawmillId, "SLPA on Sawmill", new ArrayList()); - createRealWorldCover(new RandomWalkLabelPropagationAlgorithm(), sawmillId, "RAW LPA on Sawmill", statMetrics); - } - -} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/IntegrationTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/IntegrationTest.java index 20ce585d..3fd15275 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/IntegrationTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/IntegrationTest.java @@ -106,7 +106,7 @@ // if(graph == null) { // throw new IllegalArgumentException(); // } -// cover = new Cover(graph, new CCSMatrix(graph.nodeCount(), 0)); +// cover = new Cover(graph, new CCSMatrix(graph.getNodeCount(), 0)); // log = new CoverCreationLog(algorithmType, parameters, algorithm.compatibleGraphTypes()); // cover.setCreationMethod(log); // em.persist(cover); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceDatabaseTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceDatabaseTest.java new file mode 100644 index 00000000..2b2ee549 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceDatabaseTest.java @@ -0,0 +1,44 @@ +package i5.las2peer.services.ocd; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.ArrayList; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.utils.Database; +import i5.las2peer.services.ocd.utils.DatabaseConfig; + +public class ServiceDatabaseTest { + + + private static Database database; + + @BeforeClass + public static void clearDatabase() { + database = new Database(true); + } + + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + @Test + public void test() { + List l = new ArrayList(); + l.add(1);l.add(2); + List covers = database.getCovers("cralem", "", l, null, 5, 5); + System.out.println(covers.toString()); + database.printDB(); + database.deleteDatabase(); + } + +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceTest.java index a63f7caf..e0f26be1 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/ServiceTest.java @@ -8,6 +8,8 @@ import java.io.PrintStream; import java.util.HashMap; +import i5.las2peer.services.ocd.utils.DatabaseConfig; +import i5.las2peer.services.ocd.utils.Database; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.xml.parsers.ParserConfigurationException; @@ -27,8 +29,8 @@ import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeries; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; -import i5.las2peer.services.ocd.utils.EntityHandler; import i5.las2peer.services.ocd.utils.RequestHandler; +import i5.las2peer.services.ocd.utils.ThreadHandler; import i5.las2peer.testing.MockAgentFactory; import i5.las2peer.tools.LocalNodeStarter; import i5.las2peer.connectors.webConnector.WebConnector; @@ -54,12 +56,13 @@ public class ServiceTest { private static final String testServiceClass = "i5.las2peer.services.ocd.ServiceClass"; private static final String mainPath = "ocd/"; - private static long SawmillGraphId; - private static long DolphinsGraphId; - private static long AperiodicTwoCommunitiesGraphId; - + private static String SawmillGraphKey; + private static String DolphinsGraphKey; + private static String AperiodicTwoCommunitiesGraphKey; + + private static Database database; private static RequestHandler requestHandler = new RequestHandler(); - private static EntityHandler entityHandler = new EntityHandler(); + /** * Called before the tests start. @@ -121,15 +124,16 @@ private static void setupDatabase() throws AdapterException, FileNotFoundExcepti /* * Set db content */ + database = new Database(false); CustomGraph graph = OcdTestGraphFactory.getAperiodicTwoCommunitiesGraph(); createGraph(graph); - AperiodicTwoCommunitiesGraphId = graph.getId(); + AperiodicTwoCommunitiesGraphKey = graph.getKey(); graph = OcdTestGraphFactory.getDolphinsGraph(); createGraph(graph); - DolphinsGraphId = graph.getId(); + DolphinsGraphKey = graph.getKey(); graph = OcdTestGraphFactory.getSawmillGraph(); createGraph(graph); - SawmillGraphId = graph.getId(); + SawmillGraphKey = graph.getKey(); } @@ -144,50 +148,25 @@ private static void setupDatabase() throws AdapterException, FileNotFoundExcepti public static void createGraph(CustomGraph graph) throws AdapterException, FileNotFoundException, ParserConfigurationException { graph.setUserName(testAgent.getLoginName()); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - em.flush(); - tx.commit(); - } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } - throw e; - } - em.close(); + database.storeGraph(graph); System.out.println(requestHandler.writeId(graph)); } - + /** * Persists a simulation for database setup. - * + * * @param simulation - * @throws AdapterException - * @throws FileNotFoundException * @throws ParserConfigurationException */ - public static long createSimulation(SimulationSeries simulation) - throws AdapterException, FileNotFoundException, ParserConfigurationException { + public static String createSimulation(SimulationSeries simulation) + throws ParserConfigurationException { simulation.setUserId(testAgent.getIdentifier()); - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - long sId; + String sId; try { - tx.begin(); - em.persist(simulation); - em.flush(); - sId = simulation.getId(); - tx.commit(); + sId = database.storeSimulationSeries(simulation); } catch (RuntimeException e) { - if (tx != null && tx.isActive()) { - tx.rollback(); - } throw e; } - em.close(); return sId; } @@ -199,7 +178,13 @@ public static long createSimulation(SimulationSeries simulation) */ @AfterClass public static void shutDownServer() throws Exception { - + ThreadHandler t = new ThreadHandler(); + String user = testAgent.getLoginName(); + database.deleteGraph(user, AperiodicTwoCommunitiesGraphKey, t); + database.deleteGraph(user, DolphinsGraphKey, t); + database.deleteGraph(user, SawmillGraphKey, t); + database.deleteUserInactivityData("adam", null); + connector.stop(); node.shutDown(); @@ -247,16 +232,17 @@ public void getGraphMetaXMLFormat() throws AdapterException, FileNotFoundExcepti c.setLogin(testAgent.getIdentifier(), testPass); ClientResponse result = c.sendRequest("GET", - mainPath + "graphs/" + SawmillGraphId + "?outputFormat=META_XML", ""); + mainPath + "graphs/" + SawmillGraphKey + "?outputFormat=META_XML", ""); + System.out.println("Result of 'testGetGraphs' on Sawmill: " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); - result = c.sendRequest("GET", mainPath + "graphs/" + DolphinsGraphId + "?outputFormat=META_XML", ""); + result = c.sendRequest("GET", mainPath + "graphs/" + DolphinsGraphKey + "?outputFormat=META_XML", ""); System.out.println("Result of 'testGetGraphs' on Dolphins: " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); result = c.sendRequest("GET", - mainPath + "graphs/" + AperiodicTwoCommunitiesGraphId + "?outputFormat=META_XML", ""); + mainPath + "graphs/" + AperiodicTwoCommunitiesGraphKey + "?outputFormat=META_XML", ""); System.out.println("Result of 'testGetGraphs' on AperiodicTwoCommunities: " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); } catch (Exception e) { @@ -273,7 +259,7 @@ public void getGraphPropertiesXMLFormat() throws AdapterException, FileNotFoundE c.setLogin(testAgent.getIdentifier(), testPass); ClientResponse result = c.sendRequest("GET", - mainPath + "graphs/" + DolphinsGraphId + "?outputFormat=PROPERTIES_XML", ""); + mainPath + "graphs/" + DolphinsGraphKey + "?outputFormat=PROPERTIES_XML", ""); //TODO changes System.out.println("Result of 'testGetGraphs' on Dolphins: " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); @@ -320,74 +306,87 @@ public void getEnumListingProperties() throws AdapterException, FileNotFoundExce } ///////////////////////////// Simulations ///////////////////////////// - @Test public void getSimulation() throws AdapterException, FileNotFoundException { MiniClient c = new MiniClient(); c.setConnectorEndpoint(HTTP_ADDRESS +":"+ HTTP_PORT); - + SimulationSeries s1 = new SimulationSeries(); s1.setName("name"); - long id1 = 0; + String id1 = "0"; SimulationSeries s2 = new SimulationSeries(); - s1.setName("name2"); - long id2 = 0; - + s2.setName("name2"); + String id2 = "0"; + try { id1 = createSimulation(s1); id2 = createSimulation(s2); } catch (ParserConfigurationException e1) { e1.printStackTrace(); - } + } System.out.print(id1); - + try { c.setLogin(testAgent.getIdentifier(), testPass); + ClientResponse result; - ClientResponse result = c.sendRequest("GET", + result = c.sendRequest("GET", mainPath + "simulation/" + 124, ""); System.out.println("Result of 'getSimulation' " + result.getResponse().trim()); - assertEquals(400, result.getHttpCode()); - + String resultString = result.getResponse().trim(); // trimmed response string + String[] afterSplit = resultString.split(",")[0].split(":"); // value of simulation key + System.out.println(result.getResponse()); + assertEquals("null", afterSplit[1]); // returned key value should be null (keys are strings) + result = c.sendRequest("GET", mainPath + "simulation/" + id1, ""); System.out.println("Result of 'getSimulation' " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); - + result = c.sendRequest("GET", mainPath + "simulation/" + id2, ""); System.out.println("Result of 'getSimulation' " + result.getResponse().trim()); assertEquals(200, result.getHttpCode()); + result = c.sendRequest("DELETE", + mainPath + "simulation/" + id1, ""); + System.out.println("Result of 'deleteSimulation' " + result.getResponse().trim()); + assertEquals(200, result.getHttpCode()); + + result = c.sendRequest("DELETE", + mainPath + "simulation/" + id2, ""); + System.out.println("Result of 'deleteSimulation' " + result.getResponse().trim()); + assertEquals(200, result.getHttpCode()); + } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e); } } - + @Test public void startSimulation() throws AdapterException, FileNotFoundException { MiniClient c = new MiniClient(); c.setConnectorEndpoint(HTTP_ADDRESS +":"+ HTTP_PORT); - + try { c.setLogin(testAgent.getIdentifier(), testPass); ClientResponse result = c.sendRequest("POST", mainPath + "simulation" , "{\"graphId\":2,\"dynamic\":\"Moran\",\"dynamicValues\":[],\"payoffCC\":1.0,\"payoffCD\":1.0,\"payoffDC\":1.0,\"payoffDD\":1.0,\"iterations\":20}", "application/json", "", new HashMap<>()); System.out.println("Result of 'startSimulation' " + result.getResponse().trim()); assertEquals(400, result.getHttpCode()); - + c.setLogin(testAgent.getIdentifier(), testPass); result = c.sendRequest("POST", mainPath + "simulation" , "{\"graphId\":2,\"dynamic\":\"Moran\",\"dynamicValues\":[],\"payoffValues\":[1.0,2.0,3.1,0.0],\"iterations\":20}", "application/json", "", new HashMap<>()); System.out.println("Result of 'startSimulation' " + result.getResponse().trim()); assertEquals(400, result.getHttpCode()); - + } catch (Exception e) { e.printStackTrace(); fail("Exception: " + e); } } - + } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsInputAdapterTest.java index 1bc4b500..3a081f76 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/CommunityMemberListsInputAdapterTest.java @@ -31,8 +31,8 @@ public void testOnSawmill() throws AdapterException, FileNotFoundException { @Test public void testOnFacebook() throws AdapterException, FileNotFoundException { CustomGraph graph = OcdTestGraphFactory.getFacebookGraph(); - System.out.println("Nodes: " + graph.nodeCount()); - System.out.println("Edges: " + graph.edgeCount()); + System.out.println("Nodes: " + graph.getNodeCount()); + System.out.println("Edges: " + graph.getEdgeCount()); Cover cover; CoverInputAdapter adapter = new CommunityMemberListsCoverInputAdapter(new FileReader(OcdTestConstants.facebookGroundTruthCommunityMemberListxInputPath)); cover = adapter.readCover(graph); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapterTest.java index d3fb2811..06484f44 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverInput/LabeledMembershipMatrixCoverInputAdapterTest.java @@ -11,11 +11,11 @@ import java.io.FileNotFoundException; import java.io.FileReader; +import java.util.Iterator; import org.junit.Test; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class LabeledMembershipMatrixCoverInputAdapterTest { @@ -30,14 +30,13 @@ public void testReadCoverOnSawmill() throws AdapterException, FileNotFoundExcept cover = adapter.readCover(graph); assertEquals(4, cover.communityCount()); assertEquals(graph, cover.getGraph()); - NodeCursor nodes = graph.nodes(); + Iterator nodes = graph.iterator(); Node node14 = null; - while(nodes.ok()) { - Node node = nodes.node(); + while(nodes.hasNext()) { + Node node = nodes.next(); if(graph.getNodeName(node).equals("14")) { node14 = node; } - nodes.next(); } assertNotNull(node14); assertEquals(0.629, cover.getBelongingFactor(node14, 0), 0.001); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverOutput/XmlCoverOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverOutput/XmlCoverOutputAdapterTest.java index 2a65bbd3..62b9424e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverOutput/XmlCoverOutputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/coverOutput/XmlCoverOutputAdapterTest.java @@ -17,13 +17,14 @@ import java.io.IOException; import java.util.HashMap; import java.util.HashSet; +import java.util.UUID; import org.junit.Test; import org.la4j.matrix.Matrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class XmlCoverOutputAdapterTest { @@ -37,15 +38,15 @@ public void test() throws AdapterException, IOException { CustomGraph graph = new CustomGraph(); graph.setUserName(userName); graph.setName(graphName); - Node nodeA = graph.createNode(); - Node nodeB = graph.createNode(); - Node nodeC = graph.createNode(); + Node nodeA = graph.addNode("A"); + Node nodeB = graph.addNode("B"); + Node nodeC = graph.addNode("C"); graph.setNodeName(nodeA, "A"); graph.setNodeName(nodeB, "B"); graph.setNodeName(nodeC, "C"); - Edge edgeAB = graph.createEdge(nodeA, nodeB); + Edge edgeAB = graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); graph.setEdgeWeight(edgeAB, 5); - Edge edgeBC = graph.createEdge(nodeB, nodeC); + Edge edgeBC = graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeC); graph.setEdgeWeight(edgeBC, 2.5); Matrix memberships = new CCSMatrix(3, 2); memberships.set(0, 0, 1); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/AdjacencyMatrixGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/AdjacencyMatrixGraphInputAdapterTest.java index a831879d..92a506cf 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/AdjacencyMatrixGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/AdjacencyMatrixGraphInputAdapterTest.java @@ -4,14 +4,14 @@ import java.io.FileNotFoundException; import java.io.FileReader; +import java.util.Iterator; import org.junit.Test; import i5.las2peer.services.ocd.adapters.AdapterException; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.testsUtils.OcdTestConstants; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class AdjacencyMatrixGraphInputAdapterTest { @@ -20,14 +20,13 @@ public void readGraph() throws FileNotFoundException, AdapterException { GraphInputAdapter inputAdapter = new AdjacencyMatrixGraphInputAdapter(new FileReader(OcdTestConstants.sawmillAdjacencyMatrixInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(36, graph.nodeCount()); - assertEquals(62, graph.edgeCount()); - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); - assertEquals(graph.getNodeName(node), Integer.toString(node.index()+1)); - nodes.next(); + assertEquals(36, graph.getNodeCount()); + assertEquals(62, graph.getEdgeCount()); + Iterator nodes = graph.iterator(); + while(nodes.hasNext()) { + Node node = nodes.next(); + assertEquals(graph.getNodeName(node), Integer.toString(node.getIndex()+1)); } } - } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapterTest.java index 54915e1b..5c20f21e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GmlGraphInputAdapterTest.java @@ -9,6 +9,8 @@ import java.io.FileReader; import java.io.IOException; +import org.graphstream.graph.Node; + import org.junit.Test; public class GmlGraphInputAdapterTest { @@ -18,11 +20,11 @@ public void testOnDolphins() throws AdapterException, IOException, OcdAlgorithmE GraphInputAdapter inputAdapter = new GmlGraphInputAdapter(); inputAdapter.setReader(new FileReader(OcdTestConstants.dolphinsGmlInputPath)); CustomGraph graph = inputAdapter.readGraph(); - System.out.println("Nodes: " + graph.nodeCount()); - System.out.println("Edges: " + graph.edgeCount()); - assertEquals(62, graph.nodeCount()); - assertEquals(159, graph.edgeCount()); - assertEquals("Beak", graph.getNodeName(graph.getNodeArray()[0])); + System.out.println("Nodes: " + graph.getNodeCount()); + System.out.println("Edges: " + graph.getEdgeCount()); + assertEquals(62, graph.getNodeCount()); + assertEquals(159, graph.getEdgeCount()); + assertEquals("Beak", graph.getNodeName(graph.nodes().toArray(Node[]::new)[0])); } @Test @@ -30,11 +32,11 @@ public void testOnZachary() throws AdapterException, IOException, OcdAlgorithmEx GraphInputAdapter inputAdapter = new GmlGraphInputAdapter(); inputAdapter.setReader(new FileReader(OcdTestConstants.zacharyGmlInputPath)); CustomGraph graph = inputAdapter.readGraph(); - System.out.println("Nodes: " + graph.nodeCount()); - System.out.println("Edges: " + graph.edgeCount()); - assertEquals(34, graph.nodeCount()); - assertEquals(78, graph.edgeCount()); - assertEquals("0", graph.getNodeName(graph.getNodeArray()[0])); + System.out.println("Nodes: " + graph.getNodeCount()); + System.out.println("Edges: " + graph.getEdgeCount()); + assertEquals(34, graph.getNodeCount()); + assertEquals(78, graph.getEdgeCount()); + assertEquals("1", graph.getNodeName(graph.nodes().toArray(Node[]::new)[0])); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapterTest.java index 0e5a4fcc..701e97f0 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/GraphMlGraphInputAdapterTest.java @@ -10,6 +10,9 @@ import java.io.FileNotFoundException; import java.io.FileReader; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; + import org.junit.Test; public class GraphMlGraphInputAdapterTest { @@ -19,10 +22,10 @@ public void test() throws AdapterException, FileNotFoundException { GraphInputAdapter inputAdapter = new GraphMlGraphInputAdapter(); inputAdapter.setReader(new FileReader(OcdTestConstants.sawmillGraphMlInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(36, graph.nodeCount()); - assertEquals(124, graph.edgeCount()); - assertEquals(2, graph.getEdgeWeight(graph.getEdgeArray()[0]), 0); - assertEquals("1", graph.getNodeName(graph.getNodeArray()[0])); + assertEquals(36, graph.getNodeCount()); + assertEquals(124, graph.getEdgeCount()); + assertEquals(2, graph.getEdgeWeight(graph.edges().toArray(Edge[]::new)[0]), 0); + assertEquals("n0", graph.getNodeName(graph.nodes().toArray(Node[]::new)[0])); } @Test diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapterTest.java index 4cfdb465..9a777e72 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/LmsTripleStoreGraphInputAdapterTest.java @@ -10,6 +10,7 @@ import org.junit.Test; +//TODO: Refactor Triplestore tests public class LmsTripleStoreGraphInputAdapterTest { @@ -17,8 +18,8 @@ public class LmsTripleStoreGraphInputAdapterTest { public void wholeGraphtest() throws AdapterException { LmsTripleStoreGraphInputAdapter inputAdapter = new LmsTripleStoreGraphInputAdapter(); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount() + " " + graph.edgeCount()); - System.out.println(graph.getNodeName(graph.firstNode())); + System.out.println(graph.getNodeCount() + " " + graph.getEdgeCount()); + System.out.println(graph.getNodeName(graph.getNode(0))); } @Test @@ -31,9 +32,9 @@ public void testParams() throws MalformedURLException, IOException, AdapterExcep inputAdapter.setParameter(params); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount() + " " + graph.edgeCount()); - if(graph.nodeCount() != 0) { - System.out.println(graph.getNodeName(graph.firstNode())); + System.out.println(graph.getNodeCount() + " " + graph.getEdgeCount()); + if(graph.getNodeCount() != 0) { + System.out.println(graph.getNodeName(graph.getNode(0))); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapterTest.java index b75d86f2..1dce581d 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeContentEdgeListGraphInputAdapterTest.java @@ -26,7 +26,7 @@ public void testOnUrch() throws AdapterException, FileNotFoundException, Illegal new NodeContentEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.urchPostsEdgeListInputPath)); inputAdapter.setParameter(adapterParam); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount()); + System.out.println(graph.getNodeCount()); } @Ignore @@ -40,6 +40,6 @@ public void testOnOSS() throws AdapterException, FileNotFoundException, IllegalA new NodeContentEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.jmolEdgeListInputPath)); inputAdapter.setParameter(adapterParam); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount()); + System.out.println(graph.getNodeCount()); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapterTest.java index b0b3ccd7..704d9a9a 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/NodeWeightedEdgeListGraphInputAdapterTest.java @@ -9,11 +9,11 @@ import java.io.FileNotFoundException; import java.io.FileReader; +import java.util.Iterator; import org.junit.Test; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class NodeWeightedEdgeListGraphInputAdapterTest { @@ -22,13 +22,12 @@ public void test() throws AdapterException, FileNotFoundException { GraphInputAdapter inputAdapter = new NodeWeightedEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.sawmillNodeWeightedEdgeListInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(graph.nodeCount(), 36); - assertEquals(graph.edgeCount(), 62); - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); - assertEquals(graph.getNodeName(node), Integer.toString(node.index()+1)); - nodes.next(); + assertEquals(graph.getNodeCount(), 36); + assertEquals(graph.getEdgeCount(), 62); + Iterator nodesIt = graph.iterator(); + while(nodesIt.hasNext()) { + Node node = nodesIt.next(); + assertEquals(graph.getNodeName(node), Integer.toString(node.getIndex()+1)); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapterTest.java index 5e883afc..0aa627af 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/UnweightedEdgeListGraphInputAdapterTest.java @@ -19,8 +19,8 @@ public void testOnSawmill() throws AdapterException, FileNotFoundException { GraphInputAdapter inputAdapter = new UnweightedEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.sawmillUnweightedEdgeListInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(36, graph.nodeCount()); - assertEquals(62, graph.edgeCount()); + assertEquals(36, graph.getNodeCount()); + assertEquals(62, graph.getEdgeCount()); } @Test @@ -28,8 +28,8 @@ public void testOnSiam() throws AdapterException, FileNotFoundException { GraphInputAdapter inputAdapter = new UnweightedEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.siamDmUnweightedEdgeListInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(1219, graph.nodeCount()); - assertEquals(3777, graph.edgeCount()); + assertEquals(1219, graph.getNodeCount()); + assertEquals(3777, graph.getEdgeCount()); } @Test @@ -43,8 +43,8 @@ public void testWithStringReader() throws AdapterException { Reader reader = new StringReader(graphStr); inputAdapter.setReader(reader); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(4, graph.nodeCount()); - assertEquals(3, graph.edgeCount()); + assertEquals(4, graph.getNodeCount()); + assertEquals(3, graph.getEdgeCount()); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapterTest.java index 4b1a913a..9637d645 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/WeightedEdgeListGraphInputAdapterTest.java @@ -19,8 +19,8 @@ public void test() throws AdapterException, FileNotFoundException { GraphInputAdapter inputAdapter = new WeightedEdgeListGraphInputAdapter(new FileReader(OcdTestConstants.sawmillWeightedEdgeListInputPath)); CustomGraph graph = inputAdapter.readGraph(); - assertEquals(36, graph.nodeCount()); - assertEquals(62, graph.edgeCount()); + assertEquals(36, graph.getNodeCount()); + assertEquals(62, graph.getEdgeCount()); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapterTest.java index 80aac3be..2af427ba 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XGMMLGraphInputAdapterTest.java @@ -21,6 +21,6 @@ public void test() throws AdapterException, FileNotFoundException, IllegalArgume XGMMLGraphInputAdapter inputAdapter = new XGMMLGraphInputAdapter(); inputAdapter.setParameter(adapterParam); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount()); + System.out.println(graph.getNodeCount()); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapterTest.java index 8b60835d..e5dd2a33 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphInput/XMLGraphInputAdapterTest.java @@ -23,6 +23,6 @@ public void test() throws AdapterException, FileNotFoundException, IllegalArgume new XMLGraphInputAdapter(); inputAdapter.setParameter(adapterParam); CustomGraph graph = inputAdapter.readGraph(); - System.out.println(graph.nodeCount()); + System.out.println(graph.getNodeCount()); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapterTest.java index b9b5802b..eb2b4937 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/graphOutput/GraphMlGraphOutputAdapterTest.java @@ -10,6 +10,7 @@ import java.io.FileWriter; import java.io.IOException; +import org.graphstream.graph.Edge; import org.junit.Test; public class GraphMlGraphOutputAdapterTest { @@ -17,7 +18,7 @@ public class GraphMlGraphOutputAdapterTest { @Test public void test() throws AdapterException, IOException { CustomGraph graph = OcdTestGraphFactory.getSawmillGraph(); - graph.setEdgeWeight(graph.getEdgeArray()[0], 2); + graph.setEdgeWeight(graph.edges().toArray(Edge[]::new)[0], 2); GraphOutputAdapter adapter = new GraphMlGraphOutputAdapter(); adapter.setWriter(new FileWriter(OcdTestConstants.sawmillGraphMlOutputPath)); adapter.writeGraph(graph); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapterTest.java new file mode 100644 index 00000000..fc72320c --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCentralityMetaOutputAdapterTest.java @@ -0,0 +1,50 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; +import i5.las2peer.services.ocd.centrality.data.CentralityCreationType; +import i5.las2peer.services.ocd.centrality.data.CentralityMeasureType; +import i5.las2peer.services.ocd.centrality.data.CentralityMeta; +import i5.las2peer.services.ocd.graphs.GraphType; +import i5.las2peer.services.ocd.testsUtils.OcdTestConstants; +import i5.las2peer.services.ocd.utils.ExecutionStatus; +import org.junit.Test; + +import java.io.FileWriter; +import java.util.HashMap; +import java.util.HashSet; + +public class MetaXmlCentralityMetaOutputAdapterTest { + + @Test + public void writeCentralityMap() { + + String centralityKey = "centralityTestKey"; + String centralityName = "testCentrality"; + String graphKey = "graphTestKey"; + String graphName = "testGraph"; + HashSet compatibleGraphTypes = new HashSet(); + Long executionTime = Long.valueOf(20); + compatibleGraphTypes.add(GraphType.WEIGHTED); + CentralityCreationLog centralityCreationLog = new CentralityCreationLog(CentralityMeasureType.DEGREE_CENTRALITY, CentralityCreationType.CENTRALITY_MEASURE, new HashMap(),compatibleGraphTypes ); + centralityCreationLog.setExecutionTime(1); + centralityCreationLog.setStatus(ExecutionStatus.COMPLETED); + + CentralityMeta centralityMeta = new CentralityMeta( + centralityKey, + centralityName, + graphKey, + graphName, + centralityCreationLog.getCreationType().getId(), + centralityCreationLog.getStatus().getId(), + executionTime + ); + + try { + MetaXmlCentralityMetaOutputAdapter adapter = new MetaXmlCentralityMetaOutputAdapter(); + adapter.setWriter(new FileWriter(OcdTestConstants.testMetaXmlMetricMetaOutputPath)); + adapter.writeCentralityMap(centralityMeta); + }catch(Exception e){ + e.printStackTrace(); + } + } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapterTest.java new file mode 100644 index 00000000..626123c9 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlCoverMetaOutputAdapterTest.java @@ -0,0 +1,57 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.graphs.*; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import i5.las2peer.services.ocd.testsUtils.OcdTestConstants; +import i5.las2peer.services.ocd.utils.ExecutionStatus; +import org.junit.Test; + +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +public class MetaXmlCoverMetaOutputAdapterTest { + + @Test + public void writeCover() { + + String key = "coverTestKey"; + String username = "Alice"; + String name = "testCover"; + Integer numberOfCommunities = 7; + String graphKey = "graphTestKey"; + String graphName = "testGraph"; + ArrayList graphTypes = new ArrayList(); + graphTypes.add(0); + graphTypes.add(1); + HashSet compatibleGraphTypes = new HashSet(); + compatibleGraphTypes.add(GraphType.DIRECTED); + compatibleGraphTypes.add(GraphType.WEIGHTED); + + HashMap parameters = new HashMap<>(); + parameters.put("testParameter1", "0.5"); + parameters.put("testparameter2", "0.85"); + CoverCreationLog coverCreationLog = new CoverCreationLog(CoverCreationType.GROUND_TRUTH, parameters,compatibleGraphTypes); + coverCreationLog.setStatus(ExecutionStatus.COMPLETED); + + + CoverMeta coverMeta = new CoverMeta( + key, + name, + numberOfCommunities, + graphKey, + graphName, + coverCreationLog.getType().getId(), + coverCreationLog.getStatus().getId()); + + try { + MetaXmlCoverMetaOutputAdapter adapter = new MetaXmlCoverMetaOutputAdapter(); + adapter.setWriter(new FileWriter(OcdTestConstants.testMetaXmlCoverMetaOutputPath)); + adapter.writeCover(coverMeta); + }catch(Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapterTest.java new file mode 100644 index 00000000..61bea779 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/metaOutput/MetaXmlGraphMetaOutputAdapterTest.java @@ -0,0 +1,51 @@ +package i5.las2peer.services.ocd.adapters.metaOutput; + +import i5.las2peer.services.ocd.graphs.CustomGraphMeta; +import i5.las2peer.services.ocd.graphs.GraphCreationLog; +import i5.las2peer.services.ocd.graphs.GraphCreationType; +import i5.las2peer.services.ocd.testsUtils.OcdTestConstants; +import i5.las2peer.services.ocd.utils.ExecutionStatus; +import org.junit.Test; + +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; + +public class MetaXmlGraphMetaOutputAdapterTest { + + @Test + public void writeGraph() { + + + String key = "testKey"; + String username = "Alice"; + String name = "testGraph"; + Long nodeCount = Long.valueOf(5); + Long edgeCount = Long.valueOf(10); + ArrayList graphTypes = new ArrayList(); + graphTypes.add(0); + graphTypes.add(1); + GraphCreationLog graphCreationLog = new GraphCreationLog(GraphCreationType.REAL_WORLD, new HashMap()); + graphCreationLog.setStatus(ExecutionStatus.COMPLETED); + + CustomGraphMeta graphMeta = new CustomGraphMeta( + key, + username, + name, + nodeCount, + edgeCount, + graphTypes, + graphCreationLog.getType().getId(), + graphCreationLog.getStatus().getId() + ); + + try { + MetaXmlGraphMetaOutputAdapter adapter = new MetaXmlGraphMetaOutputAdapter(); + adapter.setWriter(new FileWriter(OcdTestConstants.testMetaXmlGraphMetaOutputPath)); + adapter.writeGraph(graphMeta); + }catch(Exception e){ + e.printStackTrace(); + } + + } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapterTest.java index 96fde755..29f206e1 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/JsonVisualOutputAdapterTest.java @@ -19,7 +19,7 @@ public class JsonVisualOutputAdapterTest { @Test - public void testOnTinyCircleGraph() throws IOException, AdapterException, InstantiationException, IllegalAccessException { + public void testOnTinyCircleGraph() throws IOException, AdapterException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getTinyCircleGraph(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(graph, GraphLayoutType.ORGANIC, true, false, 20, 45); @@ -29,7 +29,7 @@ public void testOnTinyCircleGraph() throws IOException, AdapterException, Instan } @Test - public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getTwoCommunitiesGraph(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(graph, GraphLayoutType.ORGANIC, true, false, 20, 45); @@ -39,7 +39,7 @@ public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, In } @Test - public void testSvgOnSawmillGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testSvgOnSawmillGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getSawmillGraph(); JsonVisualOutputAdapter adapter = new JsonVisualOutputAdapter(); LayoutHandler handler = new LayoutHandler(); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualGraphOutputAdapterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualGraphOutputAdapterTest.java index 5662aa26..d9251f89 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualGraphOutputAdapterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/adapters/visualOutput/SvgVisualGraphOutputAdapterTest.java @@ -16,7 +16,7 @@ public class SvgVisualGraphOutputAdapterTest { @Test - public void testOnTinyCircleGraph() throws IOException, AdapterException, InstantiationException, IllegalAccessException { + public void testOnTinyCircleGraph() throws IOException, AdapterException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getTinyCircleGraph(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(graph, GraphLayoutType.ORGANIC, true, false, 20, 45); @@ -26,7 +26,7 @@ public void testOnTinyCircleGraph() throws IOException, AdapterException, Instan } @Test - public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getTwoCommunitiesGraph(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(graph, GraphLayoutType.ORGANIC, true, false, 20, 45); @@ -36,7 +36,7 @@ public void testOnTwoCommunitiesGraph() throws AdapterException, IOException, In } @Test - public void testSvgOnSawmillGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testSvgOnSawmillGraph() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { CustomGraph graph = ViewerTestGraphFactory.getSawmillGraph(); SvgVisualOutputAdapter adapter = new SvgVisualOutputAdapter(); LayoutHandler handler = new LayoutHandler(); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AlgorithmsBoundaryTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AlgorithmsBoundaryTest.java index 303efb3c..d8a970a3 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AlgorithmsBoundaryTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AlgorithmsBoundaryTest.java @@ -17,11 +17,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import org.junit.Test; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; public class AlgorithmsBoundaryTest { @@ -40,12 +41,12 @@ public void testAlgorithmsBoundaries() throws OcdAlgorithmException, Interrupted CustomGraph graph = new CustomGraph(); graphs.add(graph); graph = new CustomGraph(); - graph.createNode(); + graph.addNode("firstNode"); graphs.add(graph); graph = new CustomGraph(); - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - Edge edge = graph.createEdge(node0, node1); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + Edge edge = graph.addEdge(UUID.randomUUID().toString(), node0, node1); graph.setEdgeWeight(edge, 2); graph.addType(GraphType.DIRECTED); graphs.add(graph); @@ -54,7 +55,7 @@ public void testAlgorithmsBoundaries() throws OcdAlgorithmException, Interrupted for(CustomGraph currentGraph : graphs) { Cover cover = executor.execute(currentGraph, currentAlgo, 0); System.out.println("Algo: " + currentAlgo.getAlgorithmType().name() - + ", Node Count: " + currentGraph.nodeCount()); + + ", Node Count: " + currentGraph.getNodeCount()); System.out.println(cover + "\n"); } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationTest.java index 7aea44cf..b3147017 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/AntColonyOptimizationTest.java @@ -23,7 +23,9 @@ import i5.las2peer.services.ocd.metrics.ModularityMetric; import i5.las2peer.services.ocd.metrics.OcdMetricException; import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; -import y.base.Node; +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class AntColonyOptimizationTest { @@ -34,7 +36,7 @@ public class AntColonyOptimizationTest { public void testCDDistanceTest() throws OcdAlgorithmException, InterruptedException, AdapterException, FileNotFoundException, IllegalArgumentException, ParseException { CustomGraph graph = OcdTestGraphFactory.getMaximalCliqueGraph() ; - Node[] nmap = graph.getNodeArray(); + Node[] nmap = graph.nodes().toArray(Node[]::new); Node v1 = nmap[1]; Node v2 = nmap[7]; AntColonyOptimizationAlgorithm ACO = new AntColonyOptimizationAlgorithm(); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithmTest.java index 55dccc1f..24531b7e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/BinarySearchRandomWalkLabelPropagationAlgorithmTest.java @@ -17,7 +17,7 @@ import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.vector.Vector; -import y.base.Node; +import org.graphstream.graph.Node; /* LDAV=ones(1,num_vertices(SparseGraph)); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithmTest.java index 20023775..44600732 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/ClizzAlgorithmTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.la4j.matrix.Matrix; -import y.base.Node; +import org.graphstream.graph.Node; public class ClizzAlgorithmTest { @@ -100,7 +100,7 @@ public void testOnAperiodicTwoCommunities() throws OcdAlgorithmException, Adapte Cover cover = new Cover(graph, memberships); cover.setCreationMethod(new CoverCreationLog(algo.getAlgorithmType(), algo.getParameters(), algo.compatibleGraphTypes())); assertEquals(2, cover.communityCount()); - for(int i=0; i edges = graph.edges().iterator(); Edge edge; System.out.println("Graph:"); - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edges.next(); System.out.println(edge + " " + graph.getEdgeWeight(edge)); - edges.next(); } algo.writeNetworkFile(graph); } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithmTest.java new file mode 100644 index 00000000..453de80a --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LOCAlgorithmTest.java @@ -0,0 +1,196 @@ +package i5.las2peer.services.ocd.algorithms; + +import java.io.FileNotFoundException; + +import java.awt.Color; +import java.util.*; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; +import org.junit.Test; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.algorithms.utils.OcdAlgorithmException; +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.Community; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.metrics.OcdMetricException; + + +public class LOCAlgorithmTest { + private static CustomGraph graph; + private static Node n[]; + + @Test + public void testgraphs() throws OcdAlgorithmException, InterruptedException, FileNotFoundException, AdapterException, OcdMetricException { + System.out.println("Test 1"); + graph = getGraph1(); + test4(graph); + System.out.println("Test 2"); + graph = getGraph2(); + test4(graph); + System.out.println("Test 3"); + graph = getGraph3(); + test4(graph); + System.out.println("Test 4"); + graph = getGraph4(); + test4(graph); + + } + + private void test(CustomGraph graph) throws InterruptedException{ + LOCAlgorithm loca = new LOCAlgorithm(); + System.out.println("Graph statistics :"); + System.out.println("Nodes " + graph.getNodeCount() + " Edges " + graph.getEdgeCount()); + + System.out.println("Test Local Density:"); + HashMap map = loca.getLocalDensityMap(graph); + Node bestnode = loca.getMaxValueNode(map); + Set cluster = new HashSet(); + System.out.println("Node : " + cluster.toString()); + cluster.add(bestnode); + Node[] nodes = graph.nodes().toArray(Node[]::new); + for(Node node : nodes) { + double nodefitness = loca.getNodeFitness(node, cluster, graph); + System.out.println(node.toString()+ "has fitness value " + nodefitness); + } + + } + + private void test2(CustomGraph graph) { + + } + private void test3(CustomGraph graph) { + + + } + private void test4(CustomGraph graph) { + LOCAlgorithm loca = new LOCAlgorithm(); + try { + Cover cover = loca.detectOverlappingCommunities(graph); + } catch ( Exception e) { + e.printStackTrace(); + } + } + + // Creates graph1 from Paper + private CustomGraph getGraph1() { + CustomGraph graph = new CustomGraph(); + + // Creates nodes + Node n[] = new Node[7]; + for (int i = 0; i < 7; i++) { + n[i] = graph.addNode(String.valueOf(i)); + } + + // first community (nodes: 0, 1, 2, 3) + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (i != j ) { + graph.addEdge(UUID.randomUUID().toString(),n[i], n[j]); + } + } + } + + // second community (nodes: 3, 4, 5, 6) + for(int i = 3; i < 7; i++) { + for (int j = 3; j < 7; j++) { + if(i!=j ) { + graph.addEdge(UUID.randomUUID().toString(),n[i], n[j]); + } + } + } + return graph; + } + + // Creates graph2 from Paper + private CustomGraph getGraph2() { + + graph = new CustomGraph(); + + // Creates nodes + n = new Node[8]; + for (int i = 0; i < 8; i++) { + n[i] = graph.addNode(String.valueOf(i)); + } + // first community (nodes: 0, 1, 2, 3) + e(0,1); + e(0,3); + e(1,3); + e(1,2); + e(2,3); + // second community (nodes: 4, 5, 6, 7) + for(int i = 4; i < 8; i++) { + for (int j = 4; j < 8; j++) { + if(i!=j ) { + graph.addEdge(UUID.randomUUID().toString(),n[i], n[j]); + } + } + } + + e(0,4); + e(2,4); + return graph; + } + + // Creates a graph of 0-1-2-3-4 + private CustomGraph getGraph3() { + graph = new CustomGraph(); + + // Creates nodes + n = new Node[7]; + for (int i = 0; i < 7; i++) { + n[i] = graph.addNode(String.valueOf(i)); + } + e(0,1); + e(1,2); + e(2,3); + e(3,4); + e(4,5); + e(5,6); + return graph; + } + + private CustomGraph getGraph4() { + graph = new CustomGraph(); + + // Creates nodes + n = new Node[20]; + for (int i = 0; i < 20; i++) { + n[i] = graph.addNode(String.valueOf(i)); + } + e(0,1); + e(1,2); + e(2,3); + e(3,4); + e(6,7); + e(6,8); + e(6,9); + e(7,8); + e(7,9); + e(7,17); + e(8,9); + e(8,10); + e(9,11); + e(9,12); + e(9,10); + e(10,13); + e(13,14); + e(13,15); + e(13,16); + e(14,15); + e(15,16); + e(15,18); + e(18,19); + return graph; + } + + private void e(int a, int b) { + graph.addEdge(UUID.randomUUID().toString(),n[a], n[b]); + graph.addEdge(UUID.randomUUID().toString(),n[b], n[a]); + } + + private void p(String s) { + System.out.println(s); + } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithmTest.java index 1e8365fa..c93efc9e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/LocalSpectralClusteringAlgorithmTest.java @@ -18,8 +18,6 @@ import org.la4j.matrix.Matrix; import org.la4j.matrix.dense.*; -import y.base.Node; - public class LocalSpectralClusteringAlgorithmTest { /* diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MemeticLinkClusteringAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MemeticLinkClusteringAlgorithmTest.java new file mode 100644 index 00000000..d22fd308 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MemeticLinkClusteringAlgorithmTest.java @@ -0,0 +1,41 @@ +package i5.las2peer.services.ocd.algorithms; + +import org.graphstream.graph.Node; +import org.junit.Test; + +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.graphs.Cover; + +import java.util.UUID; + + +public class MemeticLinkClusteringAlgorithmTest { + + @Test + + public void CustomGraphTest(){ + + try { + CustomGraph graph = new CustomGraph(); + Node n1 = graph.addNode(Integer.toString(0)); + Node n2 = graph.addNode(Integer.toString(1)); + Node n3 = graph.addNode(Integer.toString(2)); + Node n4 = graph.addNode(Integer.toString(3)); + Node n5 = graph.addNode(Integer.toString(4)); + Node n6 = graph.addNode(Integer.toString(5)); + + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n1); + graph.addEdge(UUID.randomUUID().toString(), n4, n5); + graph.addEdge(UUID.randomUUID().toString(), n5, n6); + graph.addEdge(UUID.randomUUID().toString(), n6, n4); + + + OcdAlgorithm algo = new MemeticLinkClusteringAlgorithm(); + Cover cover = algo.detectOverlappingCommunities(graph); + System.out.println(cover.toString()); + + }catch(Exception e){e.printStackTrace();} + } +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesTest.java index c4ce8fec..32e84574 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/MergingOfOverlappingCommunitiesTest.java @@ -14,11 +14,12 @@ import java.io.FileNotFoundException; import java.util.HashSet; +import java.util.UUID; import org.junit.Ignore; import org.junit.Test; -import y.base.Node; +import org.graphstream.graph.Node; public class MergingOfOverlappingCommunitiesTest { @@ -42,18 +43,18 @@ public void testOnSawmill() throws OcdAlgorithmException, AdapterException, File @Test public void testOnKnowResultGraph() throws OcdAlgorithmException, InterruptedException, OcdMetricException { CustomGraph graph = new CustomGraph(); - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - Node node2 = graph.createNode(); - Node node3 = graph.createNode(); - Node node4 = graph.createNode(); - Node node5 = graph.createNode(); - graph.createEdge(node0, node1); - graph.createEdge(node0, node2); - graph.createEdge(node0, node3); - graph.createEdge(node1, node2); - graph.createEdge(node3, node4); - graph.createEdge(node3, node5); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + Node node2 = graph.addNode("2"); + Node node3 = graph.addNode("3"); + Node node4 = graph.addNode("4"); + Node node5 = graph.addNode("5"); + graph.addEdge(UUID.randomUUID().toString(), node0, node1); + graph.addEdge(UUID.randomUUID().toString(), node0, node2); + graph.addEdge(UUID.randomUUID().toString(), node0, node3); + graph.addEdge(UUID.randomUUID().toString(), node1, node2); + graph.addEdge(UUID.randomUUID().toString(), node3, node4); + graph.addEdge(UUID.randomUUID().toString(), node3, node5); GraphProcessor processor = new GraphProcessor(); graph.addType(GraphType.DIRECTED); processor.makeCompatible(graph, new HashSet()); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/NISEAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/NISEAlgorithmTest.java index 7e70e823..1fe4e6e4 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/NISEAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/NISEAlgorithmTest.java @@ -13,6 +13,7 @@ import org.junit.Test; +//TODO: GRAPHSTREAM UPGRADE: Check with further graphs, the tests here give every node the same belonging to every community. This is intended but not exhaustive enough public class NISEAlgorithmTest { @Test diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/RandomWalkLabelPropagationAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/RandomWalkLabelPropagationAlgorithmTest.java index a0340aaf..4da70cef 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/RandomWalkLabelPropagationAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/RandomWalkLabelPropagationAlgorithmTest.java @@ -21,7 +21,7 @@ import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.vector.Vector; -import y.base.Node; +import org.graphstream.graph.Node; /* LDAV=ones(1,num_vertices(SparseGraph)); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SSKAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SSKAlgorithmTest.java index 250e9eda..d023bb81 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SSKAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SSKAlgorithmTest.java @@ -21,7 +21,7 @@ import org.la4j.vector.Vector; import org.la4j.vector.Vectors; -import y.base.Node; +import org.graphstream.graph.Node; public class SSKAlgorithmTest { @@ -89,7 +89,7 @@ public void testDetermineGlobalLeadersOnAperiodicTwoCommunities() throws Interru Matrix transitionMatrix = algo.calculateTransitionMatrix(graph); Vector totalInfluences = algo.executeRandomWalk(transitionMatrix); Map globalLeaders = algo.determineGlobalLeaders(graph, transitionMatrix, totalInfluences); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); assertEquals(1, globalLeaders.size()); assertTrue(globalLeaders.keySet().contains(nodes[0])); System.out.println("Global Leaders:"); @@ -108,7 +108,7 @@ public void testDetermineGlobalLeadersOnSawmill() throws AdapterException, FileN Map globalLeaders = algo.determineGlobalLeaders(graph, transitionMatrix, totalInfluences); assertEquals(3, globalLeaders.size()); assertEquals(3, globalLeaders.values().size()); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); assertTrue(globalLeaders.keySet().contains(nodes[11])); assertTrue(globalLeaders.keySet().contains(nodes[26])); assertTrue(globalLeaders.keySet().contains(nodes[30])); @@ -128,7 +128,7 @@ public void testDetermineGlobalLeadersOnDirectedAperiodicTwoCommunities() throws Vector totalInfluences = algo.executeRandomWalk(transitionMatrix); Map globalLeaders = algo.determineGlobalLeaders(graph, transitionMatrix, totalInfluences); assertEquals(7, globalLeaders.size()); - Node[] nodes = graph.getNodeArray(); + Node[] nodes = graph.nodes().toArray(Node[]::new); assertTrue(globalLeaders.keySet().contains(nodes[0])); assertTrue(globalLeaders.keySet().contains(nodes[5])); assertTrue(globalLeaders.keySet().contains(nodes[6])); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithmTest.java index 53c98b9e..662e085c 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedDMIDAlgorithmTest.java @@ -19,13 +19,16 @@ import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; -import y.base.Node; + +import org.graphstream.graph.Graph; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class SignedDMIDAlgorithmTest { @Test public void testGetLeadershipVector() throws FileNotFoundException, AdapterException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSignedLfrSixNodesGraph(); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Vector leadershipVector = algo.getLeadershipVector(graph); Vector expectedVector = new BasicVector(nodeCount); @@ -50,7 +53,7 @@ public void testGetLeadershipVector() throws FileNotFoundException, AdapterExcep @Test public void testGetLocalLeader() throws FileNotFoundException, AdapterException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Vector leadershipVector = new BasicVector(nodeCount); leadershipVector.set(0, 0.465116279); @@ -73,10 +76,10 @@ public void testGetLocalLeader() throws FileNotFoundException, AdapterException, System.out.println("Result: " + followerMap.toString()); assertEquals(expectedMap.entrySet().size(), followerMap.entrySet().size()); - assertTrue(followerMap.keySet().contains(graph.getNodeArray()[3])); - assertTrue(followerMap.keySet().contains(graph.getNodeArray()[11])); - assertEquals(5, (int) followerMap.get(graph.getNodeArray()[3])); - assertEquals(3, (int) followerMap.get(graph.getNodeArray()[11])); + assertTrue(followerMap.keySet().contains(graph.nodes().toArray(Node[]::new)[3])); + assertTrue(followerMap.keySet().contains(graph.nodes().toArray(Node[]::new)[11])); + assertEquals(5, (int) followerMap.get(graph.nodes().toArray(Node[]::new)[3])); + assertEquals(3, (int) followerMap.get(graph.nodes().toArray(Node[]::new)[11])); } @Test @@ -85,7 +88,7 @@ public void testGetGlobalLeader() throws FileNotFoundException, AdapterException Map LeadershipMap = new HashMap(); Node n[] = new Node[5]; for (int i = 0; i < 5; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); LeadershipMap.put(n[i], i + 1); } SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); @@ -95,9 +98,9 @@ public void testGetGlobalLeader() throws FileNotFoundException, AdapterException * number of global leaders=3 */ assertEquals(3, leaderCount); - assertTrue(globalLeader.contains(graph.getNodeArray()[2])); - assertTrue(globalLeader.contains(graph.getNodeArray()[3])); - assertTrue(globalLeader.contains(graph.getNodeArray()[4])); + assertTrue(globalLeader.contains(graph.nodes().toArray(Node[]::new)[2])); + assertTrue(globalLeader.contains(graph.nodes().toArray(Node[]::new)[3])); + assertTrue(globalLeader.contains(graph.nodes().toArray(Node[]::new)[4])); // assertEquals(expectedLeader,globalLeader); } @@ -105,7 +108,7 @@ public void testGetGlobalLeader() throws FileNotFoundException, AdapterException public void testExecuteLabelPropagation() throws FileNotFoundException, AdapterException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); - Vector leadershipVector = new BasicVector(graph.nodeCount()); + Vector leadershipVector = new BasicVector(graph.getNodeCount()); leadershipVector.set(0, 0.465116279); leadershipVector.set(1, 0.480769231); leadershipVector.set(2, 0.166666667); @@ -118,30 +121,30 @@ public void testExecuteLabelPropagation() throws FileNotFoundException, AdapterE leadershipVector.set(9, 0.441176471); leadershipVector.set(10, 0.471698113); leadershipVector.set(11, 0.486486486); - Map map = algo.executeLabelPropagation(graph, graph.getNodeArray()[3], leadershipVector); + Map map = algo.executeLabelPropagation(graph, graph.nodes().toArray(Node[]::new)[3], leadershipVector); Map expectedMap = new HashMap(); - // expectedMap.put(graph.getNodeArray()[3], 0); - // expectedMap.put(graph.getNodeArray()[0], 1); - // expectedMap.put(graph.getNodeArray()[1], 1); - // expectedMap.put(graph.getNodeArray()[2], 1); - // expectedMap.put(graph.getNodeArray()[9], 1); - // expectedMap.put(graph.getNodeArray()[10], 1); - // expectedMap.put(graph.getNodeArray()[4], 2); - // expectedMap.put(graph.getNodeArray()[5], 2); - // expectedMap.put(graph.getNodeArray()[8], 2); - // expectedMap.put(graph.getNodeArray()[7], 2); - // expectedMap.put(graph.getNodeArray()[11], 3); - expectedMap.put(graph.getNodeArray()[3], 1); - expectedMap.put(graph.getNodeArray()[0], 2); - expectedMap.put(graph.getNodeArray()[1], 2); - expectedMap.put(graph.getNodeArray()[2], 2); - expectedMap.put(graph.getNodeArray()[9], 2); - expectedMap.put(graph.getNodeArray()[10], 2); - expectedMap.put(graph.getNodeArray()[4], 3); - expectedMap.put(graph.getNodeArray()[5], 3); - expectedMap.put(graph.getNodeArray()[8], 3); - expectedMap.put(graph.getNodeArray()[7], 3); - expectedMap.put(graph.getNodeArray()[11], 4); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[3], 0); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[0], 1); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[1], 1); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[2], 1); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[9], 1); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[10], 1); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[4], 2); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[5], 2); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[8], 2); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[7], 2); + // expectedMap.put(graph.nodes().toArray(Node[]::new)[11], 3); + expectedMap.put(graph.nodes().toArray(Node[]::new)[3], 1); + expectedMap.put(graph.nodes().toArray(Node[]::new)[0], 2); + expectedMap.put(graph.nodes().toArray(Node[]::new)[1], 2); + expectedMap.put(graph.nodes().toArray(Node[]::new)[2], 2); + expectedMap.put(graph.nodes().toArray(Node[]::new)[9], 2); + expectedMap.put(graph.nodes().toArray(Node[]::new)[10], 2); + expectedMap.put(graph.nodes().toArray(Node[]::new)[4], 3); + expectedMap.put(graph.nodes().toArray(Node[]::new)[5], 3); + expectedMap.put(graph.nodes().toArray(Node[]::new)[8], 3); + expectedMap.put(graph.nodes().toArray(Node[]::new)[7], 3); + expectedMap.put(graph.nodes().toArray(Node[]::new)[11], 4); System.out.println(map.toString()); assertEquals(expectedMap, map); } @@ -149,31 +152,31 @@ public void testExecuteLabelPropagation() throws FileNotFoundException, AdapterE @Test public void testGetMembershipDegrees() throws FileNotFoundException, AdapterException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Map> communities = new HashMap>(); Map community = new HashMap(); - community.put(graph.getNodeArray()[0], 2); - community.put(graph.getNodeArray()[1], 2); - community.put(graph.getNodeArray()[2], 2); - community.put(graph.getNodeArray()[9], 2); - community.put(graph.getNodeArray()[10], 2); - community.put(graph.getNodeArray()[4], 3); - community.put(graph.getNodeArray()[5], 3); - community.put(graph.getNodeArray()[8], 3); - community.put(graph.getNodeArray()[7], 3); - community.put(graph.getNodeArray()[11], 4); - communities.put(graph.getNodeArray()[3], community); + community.put(graph.nodes().toArray(Node[]::new)[0], 2); + community.put(graph.nodes().toArray(Node[]::new)[1], 2); + community.put(graph.nodes().toArray(Node[]::new)[2], 2); + community.put(graph.nodes().toArray(Node[]::new)[9], 2); + community.put(graph.nodes().toArray(Node[]::new)[10], 2); + community.put(graph.nodes().toArray(Node[]::new)[4], 3); + community.put(graph.nodes().toArray(Node[]::new)[5], 3); + community.put(graph.nodes().toArray(Node[]::new)[8], 3); + community.put(graph.nodes().toArray(Node[]::new)[7], 3); + community.put(graph.nodes().toArray(Node[]::new)[11], 4); + communities.put(graph.nodes().toArray(Node[]::new)[3], community); Map communityTwo = new HashMap(); - communityTwo.put(graph.getNodeArray()[5], 2); - communityTwo.put(graph.getNodeArray()[6], 2); - communityTwo.put(graph.getNodeArray()[8], 2); - communityTwo.put(graph.getNodeArray()[9], 3); - communityTwo.put(graph.getNodeArray()[7], 3); - communityTwo.put(graph.getNodeArray()[1], 3); - communityTwo.put(graph.getNodeArray()[0], 4); - communityTwo.put(graph.getNodeArray()[3], 4); - communities.put(graph.getNodeArray()[11], communityTwo); + communityTwo.put(graph.nodes().toArray(Node[]::new)[5], 2); + communityTwo.put(graph.nodes().toArray(Node[]::new)[6], 2); + communityTwo.put(graph.nodes().toArray(Node[]::new)[8], 2); + communityTwo.put(graph.nodes().toArray(Node[]::new)[9], 3); + communityTwo.put(graph.nodes().toArray(Node[]::new)[7], 3); + communityTwo.put(graph.nodes().toArray(Node[]::new)[1], 3); + communityTwo.put(graph.nodes().toArray(Node[]::new)[0], 4); + communityTwo.put(graph.nodes().toArray(Node[]::new)[3], 4); + communities.put(graph.nodes().toArray(Node[]::new)[11], communityTwo); Cover cover = algo.getMembershipDegrees(graph, communities); Matrix matrix = cover.getMemberships(); System.out.println(matrix.toString()); @@ -213,7 +216,7 @@ public void testGetMembershipDegrees() throws FileNotFoundException, AdapterExce public void testDetectOverlappingCommunities() throws FileNotFoundException, AdapterException, OcdAlgorithmException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Cover cover = algo.detectOverlappingCommunities(graph); Matrix matrix = cover.getMemberships(); @@ -255,11 +258,11 @@ public void testGetPosNodesWithNewLabel() throws FileNotFoundException, AdapterE CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Set nodesWithNewBehavior = new HashSet(); - nodesWithNewBehavior.add(graph.getNodeArray()[5]); - nodesWithNewBehavior.add(graph.getNodeArray()[6]); - nodesWithNewBehavior.add(graph.getNodeArray()[8]); - nodesWithNewBehavior.add(graph.getNodeArray()[11]); - int posNeihboursWithNewBehavior = algo.getPosNodesWithNewLabel(graph, graph.getNodeArray()[7], + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[5]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[6]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[8]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[11]); + int posNeihboursWithNewBehavior = algo.getPosNodesWithNewLabel(graph, graph.nodes().toArray(Node[]::new)[7], nodesWithNewBehavior); assertEquals(3, posNeihboursWithNewBehavior); } @@ -269,11 +272,11 @@ public void testGetNegNodesWithNewLabel() throws FileNotFoundException, AdapterE CustomGraph graph = OcdTestGraphFactory.getSignedLfrGraph(); SignedDMIDAlgorithm algo = new SignedDMIDAlgorithm(); Set nodesWithNewBehavior = new HashSet(); - nodesWithNewBehavior.add(graph.getNodeArray()[5]); - nodesWithNewBehavior.add(graph.getNodeArray()[6]); - nodesWithNewBehavior.add(graph.getNodeArray()[8]); - nodesWithNewBehavior.add(graph.getNodeArray()[11]); - int negNeihboursWithNewBehavior = algo.getNegNodesWithNewLabel(graph, graph.getNodeArray()[4], + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[5]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[6]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[8]); + nodesWithNewBehavior.add(graph.nodes().toArray(Node[]::new)[11]); + int negNeihboursWithNewBehavior = algo.getNegNodesWithNewLabel(graph, graph.nodes().toArray(Node[]::new)[4], nodesWithNewBehavior); assertEquals(2, negNeihboursWithNewBehavior); } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithmTest.java index fddde4b9..80377f9e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SignedProbabilisticMixtureAlgorithmTest.java @@ -17,7 +17,7 @@ import i5.las2peer.services.ocd.graphs.GraphProcessor; import i5.las2peer.services.ocd.testsUtils.OcdTestConstants; import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; -import y.base.Node; +import org.graphstream.graph.Node; public class SignedProbabilisticMixtureAlgorithmTest { @Test diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationHelpers/PopularityListenerRuleTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationHelpers/PopularityListenerRuleTest.java index e7270116..7091d683 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationHelpers/PopularityListenerRuleTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/SpeakerListenerLabelPropagationHelpers/PopularityListenerRuleTest.java @@ -11,25 +11,21 @@ import org.junit.Test; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class PopularityListenerRuleTest { @Test - public void test() { + public void test() throws InterruptedException { CustomGraph graph = OcdTestGraphFactory.getTwoCommunitiesGraph(); - Node listener = graph.getNodeArray()[0]; - NodeCursor successors = listener.successors(); + Node listener = graph.nodes().toArray(Node[]::new)[0]; + Node[] successors = graph.getSuccessorNeighbours(listener).toArray(new Node[0]); Map receivedLabels = new HashMap(); - while(successors.ok()) { - receivedLabels.put(successors.node(), 0); - successors.next(); + for (Node successor : successors) { + receivedLabels.put(successor, 0); } - successors.toFirst(); - receivedLabels.put(successors.node(), 1); - successors.toLast(); - receivedLabels.put(successors.node(), 1); + receivedLabels.put(successors[0], 1); + receivedLabels.put(successors[successors.length == 0 ? 0 : successors.length-1], 1); System.out.println("Labels:"); System.out.println(receivedLabels); SlpaListenerRuleCommand listenerRule = new SlpaPopularityListenerRule(); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithmTest.java index 03faa88f..6b3c3d75 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeakCliquePercolationMethodAlgorithmTest.java @@ -10,12 +10,13 @@ import i5.las2peer.services.ocd.algorithms.utils.WeakClique; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.metrics.OcdMetricException; -import y.base.Node; import static org.junit.Assert.assertEquals; import java.io.FileNotFoundException; import java.util.HashSet; import java.util.Iterator; +import java.util.UUID; +import org.graphstream.graph.Node; public class WeakCliquePercolationMethodAlgorithmTest { @@ -35,7 +36,7 @@ public void testOnSimpleGraph() throws OcdAlgorithmException, AdapterException, for (int i = 0; i < size; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); } @@ -43,7 +44,7 @@ public void testOnSimpleGraph() throws OcdAlgorithmException, AdapterException, for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (i != j ) { - graph.createEdge(n[i], n[j]); + graph.addEdge(UUID.randomUUID().toString(), n[i], n[j]); } } } @@ -52,7 +53,7 @@ public void testOnSimpleGraph() throws OcdAlgorithmException, AdapterException, for(int i = 5; i < 10; i++) { for (int j = 5; j < 10; j++) { if(i!=j ) { - graph.createEdge(n[i], n[j]); + graph.addEdge(UUID.randomUUID().toString(), n[i], n[j]); } } } @@ -60,10 +61,10 @@ public void testOnSimpleGraph() throws OcdAlgorithmException, AdapterException, /* * Connect above two communities, which creates another small community of size 3 (nodes 0, 5, 10) */ - graph.createEdge(n[5], n[10]); - graph.createEdge(n[10], n[5]); - graph.createEdge(n[0], n[10]); - graph.createEdge(n[10], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[0]); // instantiate the algorithm WeakCliquePercolationMethodAlgorithm wcpm = new WeakCliquePercolationMethodAlgorithm(); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithmTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithmTest.java index 6cddd942..409201bb 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithmTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/algorithms/WeightedLinkCommunitiesAlgorithmTest.java @@ -10,8 +10,9 @@ import org.junit.Test; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Edge; + +import java.util.Iterator; public class WeightedLinkCommunitiesAlgorithmTest { @@ -30,15 +31,14 @@ public void testOnAperiodicTwoCommunities() throws OcdAlgorithmException, Interr @Test public void testOnLinkCommunitiesTestGraph() throws OcdAlgorithmException, InterruptedException, OcdMetricException { CustomGraph graph = OcdTestGraphFactory.getLinkCommunitiesTestGraph(); - EdgeCursor edges = graph.edges(); - while (edges.ok()) { - Edge edge = edges.edge(); - Edge reverseEdge = edge.target().getEdgeTo(edge.source()); - if (reverseEdge == null || edge.index() < reverseEdge.index()) { - System.out.println("Edge " + edge.index() + ": " - + edge.source() + " -> " + edge.target()); + Iterator edges = graph.edges().iterator(); + while (edges.hasNext()) { + Edge edge = edges.next(); + Edge reverseEdge = edge.getTargetNode().getEdgeToward(edge.getSourceNode()); + if (reverseEdge == null || edge.getIndex() < reverseEdge.getIndex()) { + System.out.println("Edge " + edge.getIndex() + ": " + + edge.getSourceNode() + " -> " + edge.getTargetNode()); } - edges.next(); } OcdAlgorithm algo = new WeightedLinkCommunitiesAlgorithm(); Cover cover = algo.detectOverlappingCommunities(graph); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/LfrBenchmarkTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/LfrBenchmarkTest.java index 52bd256e..dfea3f5e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/LfrBenchmarkTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/LfrBenchmarkTest.java @@ -6,8 +6,9 @@ import org.junit.Test; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; + +import java.util.Iterator; public class LfrBenchmarkTest { @@ -16,7 +17,7 @@ public void test() throws OcdBenchmarkException, InterruptedException { LfrBenchmark model = new LfrBenchmark(12, 0.1, 0.5); Cover cover = model.createGroundTruthCover(); CustomGraph graph = cover.getGraph(); - assertEquals(1000, graph.nodeCount()); + assertEquals(1000, graph.getNodeCount()); System.out.println(cover.toString()); } @@ -25,7 +26,7 @@ public void testLowerBound() throws OcdBenchmarkException, InterruptedException LfrBenchmark model = new LfrBenchmark(24, 0.3, 0); Cover cover = model.createGroundTruthCover(); CustomGraph graph = cover.getGraph(); - assertEquals(1000, graph.nodeCount()); + assertEquals(1000, graph.getNodeCount()); System.out.println(cover.toString()); } @@ -34,7 +35,7 @@ public void testUpperBound() throws OcdBenchmarkException, InterruptedException LfrBenchmark model = new LfrBenchmark(24, 0.3, 1); Cover cover = model.createGroundTruthCover(); CustomGraph graph = cover.getGraph(); - assertEquals(1000, graph.nodeCount()); + assertEquals(1000, graph.getNodeCount()); System.out.println(cover.toString()); } @@ -43,13 +44,13 @@ public void testMembershipCounts() throws OcdBenchmarkException, InterruptedExce LfrBenchmark model = new LfrBenchmark(24, 0.3, 0.5); Cover cover = model.createGroundTruthCover(); CustomGraph graph = cover.getGraph(); - assertEquals(1000, graph.nodeCount()); - NodeCursor nodes = graph.nodes(); - Node node = nodes.node(); + assertEquals(1000, graph.getNodeCount()); + Iterator nodes = graph.iterator(); + Node node; int oneMembershipCount = 0; int twoMembershipsCount = 0; - while(nodes.ok()) { - node = nodes.node(); + while(nodes.hasNext()) { + node = nodes.next(); int memberships = cover.getCommunityIndices(node).size(); if(memberships == 1) { oneMembershipCount++; @@ -57,7 +58,6 @@ public void testMembershipCounts() throws OcdBenchmarkException, InterruptedExce else if(memberships == 2) { twoMembershipsCount ++; } - nodes.next(); } System.out.println("One memberships: " + oneMembershipCount); System.out.println("Two memberships: " + twoMembershipsCount); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmarkTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmarkTest.java index 2610b1ba..038c0e31 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmarkTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/NewmanBenchmarkTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.*; +import java.util.Iterator; import java.util.List; import i5.las2peer.services.ocd.benchmarks.NewmanBenchmark; @@ -10,8 +11,7 @@ import org.junit.Test; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; public class NewmanBenchmarkTest { @@ -23,11 +23,11 @@ public void testCreateGroundTruthCover() throws InterruptedException { assertNotNull(cover); CustomGraph graph = cover.getGraph(); assertNotNull(graph); - assertEquals(128, graph.nodeCount()); + assertEquals(128, graph.getNodeCount()); assertEquals(4, cover.communityCount()); - NodeCursor nodes = graph.nodes(); - while(nodes.ok()) { - Node node = nodes.node(); + Iterator nodes = graph.iterator(); + while(nodes.hasNext()) { + Node node = nodes.next(); List communityIndices = cover.getCommunityIndices(node); assertNotNull(communityIndices); assertEquals(1, communityIndices.size()); @@ -35,10 +35,10 @@ public void testCreateGroundTruthCover() throws InterruptedException { assertEquals(1, cover.getBelongingFactor(node, communityIndex), 0); int internalEdges = 0; int externalEdges = 0; - NodeCursor successors = node.successors(); - while(successors.ok()) { - Node successor = successors.node(); - assertTrue(graph.containsEdge(successor, node)); + Iterator successors = graph.getSuccessorNeighbours(node).iterator(); + while(successors.hasNext()) { + Node successor = successors.next(); + assertTrue(successor.hasEdgeToward(node)); double successorCommunityMembership = cover.getBelongingFactor(successor, communityIndex); if(successorCommunityMembership == 1) { internalEdges++; @@ -49,11 +49,9 @@ else if (successorCommunityMembership == 0) { else { fail("Invalid membership degree (neither 0 nor 1)"); } - successors.next(); } assertEquals(i, externalEdges); assertEquals(16 - i, internalEdges); - nodes.next(); } } } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmarkTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmarkTest.java index f4789102..c1b930ce 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmarkTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/benchmarks/SignedLfrBenchmarkTest.java @@ -9,8 +9,10 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.testsUtils.OcdTestCoverFactory; -import y.base.Edge; -import y.base.EdgeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + +import java.util.Iterator; /* * @author YLi @@ -21,9 +23,9 @@ public void testCreateGroundTruth() throws OcdBenchmarkException, InterruptedExc SignedLfrBenchmark model = new SignedLfrBenchmark(100, 3, 6, 0.1, -2.0, -1.0, 10, 40, 5, 2, 0.1, 0.1); Cover cover = model.createGroundTruthCover(); CustomGraph graph = cover.getGraph(); - assertEquals(100, graph.nodeCount()); + assertEquals(100, graph.getNodeCount()); System.out.println(cover.toString()); - int nodeCount = graph.nodeCount(); + int nodeCount = graph.getNodeCount(); int overlappingNodeCount = 0; int communityCount = cover.communityCount(); Matrix membership = cover.getMemberships(); @@ -51,19 +53,19 @@ public void testSetWeightSign() throws Exception { System.out.println(cover.toString()); System.out.println(signedCover.toString()); int communityCount = membership.columns(); - EdgeCursor edges = graph.edges(); + Iterator edges = graph.edges().iterator(); Edge edge; int negIntraEdgeCount = 0; int posInterEdgeCount = 0; - while (edges.ok()) { + while (edges.hasNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } - edge = edges.edge(); + edge = edges.next(); double weight = graph.getEdgeWeight(edge); if (weight < 0) { for (int i = 0; i < communityCount; i++) { - if (membership.get(edge.source().index(), i) * membership.get(edge.target().index(), i) != 0) { + if (membership.get(edge.getSourceNode().getIndex(), i) * membership.get(edge.getTargetNode().getIndex(), i) != 0) { negIntraEdgeCount++; break; } @@ -71,14 +73,13 @@ public void testSetWeightSign() throws Exception { } else if (weight > 0) { double sum = 0; for (int i = 0; i < communityCount; i++) { - sum = sum + membership.get(edge.source().index(), i) * membership.get(edge.target().index(), i); + sum = sum + membership.get(edge.getSourceNode().getIndex(), i) * membership.get(edge.getTargetNode().getIndex(), i); } if (sum == 0) { posInterEdgeCount++; } } - edges.next(); } System.out.println("neg. intra-edges count: " + negIntraEdgeCount); System.out.println("pos. inter-edges count: " + posInterEdgeCount); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweennessTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweennessTest.java index 882ea8fd..23371b2e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweennessTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/FlowBetweennessTest.java @@ -1,5 +1,6 @@ package i5.las2peer.services.ocd.centrality.measures; +import org.graphstream.graph.Node; import org.junit.Test; import i5.las2peer.services.ocd.centrality.data.CentralityMap; @@ -8,6 +9,7 @@ import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; +//TODO: Have further tests with more complex graph to compare to original yFiles behaviour public class FlowBetweennessTest { @Test public void testUndirectedUnweighted() throws InterruptedException, CentralityAlgorithmException { diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/IntegrationTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/IntegrationTest.java index e7af6c8d..45c41aa1 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/IntegrationTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/centrality/measures/IntegrationTest.java @@ -12,6 +12,7 @@ public class IntegrationTest { @Test public void testUndirectedUnweighted() throws InterruptedException, CentralityAlgorithmException { CustomGraph graph = OcdTestGraphFactory.getSimpleGraphUndirectedUnweighted(); + Integration algorithm = new Integration(); CentralityAlgorithmExecutor executor = new CentralityAlgorithmExecutor(); CentralityMap result = executor.execute(graph, algorithm); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandlerTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandlerTest.java deleted file mode 100644 index ca96ebf4..00000000 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationEntityHandlerTest.java +++ /dev/null @@ -1,466 +0,0 @@ -package i5.las2peer.services.ocd.cooperation.data; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; -import javax.persistence.Query; - -import org.eclipse.persistence.config.PersistenceUnitProperties; -import org.junit.After; -import org.junit.Test; - -import i5.las2peer.services.ocd.cooperation.data.simulation.AgentData; -import i5.las2peer.services.ocd.cooperation.data.simulation.Evaluation; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationDataset; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeries; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeriesGroup; -import i5.las2peer.services.ocd.cooperation.data.simulation.SimulationSeriesParameters; -import i5.las2peer.services.ocd.graphs.CustomGraph; - -public class SimulationEntityHandlerTest { - - private static final String PERSISTENCE_UNIT_NAME = "ocd"; - private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, - Collections.singletonMap(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/testing/persistence.xml")); - private SimulationEntityHandler entityHandler = new SimulationEntityHandler(); - - @After - public void clearDatabase() { - - EntityManager em = factory.createEntityManager(); - EntityTransaction etx = em.getTransaction(); - etx.begin(); - Query query; - query = em.createQuery("DELETE FROM CustomEdge", CustomGraph.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM Community", CustomGraph.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM CustomNode", CustomGraph.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM Cover", CustomGraph.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM CustomGraph", CustomGraph.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM AgentData", AgentData.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM SimulationDataset", SimulationDataset.class); - query.executeUpdate(); - query = em.createQuery("DELETE FROM SimulationSeries", SimulationSeries.class); - query.executeUpdate(); - etx.commit(); - } - - /////////////////////// Simulation Series ////////////////////////// - - @Test - public void storeSimulationSeries() { - - SimulationSeries series = new SimulationSeries(); - series.setCooperationEvaluation(new Evaluation(new double[]{1.0,2.0,3.0})); - long userId = 7; - series.setUserId(Long.toString(userId)); - - long seriesId = 0; - try { - seriesId = entityHandler.store(series, Long.toString(userId)); - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = factory.createEntityManager(); - SimulationSeries resultSeries; - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - resultSeries = em.find(SimulationSeries.class, seriesId); - tx.commit(); - } catch (RuntimeException e) { - tx.rollback(); - throw e; - } - em.close(); - - assertNotNull(resultSeries); - assertEquals(Long.toString(userId), resultSeries.getUserId()); - assertEquals(seriesId, resultSeries.getId()); - } - - @Test - public void storeSimulationSeriesWithDatasets() { - - SimulationSeries series = new SimulationSeries(); - SimulationDataset d1 = new SimulationDataset(); - d1.setName("da1"); - SimulationDataset d2 = new SimulationDataset(); - d2.setName("da2"); - List list = new ArrayList<>(); - list.add(d1); - list.add(d2); - series.setSimulationDatasets(list); - long userId = 7; - series.setUserId(Long.toString(userId)); - - long seriesId = 0; - try { - seriesId = entityHandler.store(series, Long.toString(userId)); - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = factory.createEntityManager(); - SimulationSeries resultSeries; - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - resultSeries = em.find(SimulationSeries.class, seriesId); - tx.commit(); - } catch (RuntimeException e) { - tx.rollback(); - throw e; - } - em.close(); - - assertNotNull(resultSeries); - assertNotNull(resultSeries.getSimulationDatasets()); - assertEquals(2, resultSeries.size()); - assertEquals("da1", resultSeries.getSimulationDatasets().get(0).getName()); - } - - @Test - public void getSimulationSeries() { - - SimulationSeries series = new SimulationSeries(); - long userId = 7; - series.setUserId(Integer.toString(7)); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.flush(); - em.getTransaction().commit(); - long seriesId = series.getId(); - em.close(); - - SimulationSeries resultSeries = null; - try { - resultSeries = entityHandler.getSimulationSeries(seriesId); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultSeries); - assertEquals(Long.toString(userId), resultSeries.getUserId()); - assertEquals(seriesId, resultSeries.getId()); - - } - - @Test - public void getSimulationSeriesWithDatasets() { - - SimulationSeries series = new SimulationSeries(); - long userId = 7; - series.setUserId(Integer.toString(7)); - - SimulationDataset d1 = new SimulationDataset(); - d1.setName("da1"); - SimulationDataset d2 = new SimulationDataset(); - d2.setName("da2"); - List list = new ArrayList<>(); - list.add(d1); - list.add(d2); - - series.setSimulationDatasets(list); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.flush(); - em.getTransaction().commit(); - long seriesId = series.getId(); - em.close(); - - SimulationSeries resultSeries = null; - try { - resultSeries = entityHandler.getSimulationSeries(seriesId); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultSeries); - assertNotNull(resultSeries.getSimulationDatasets()); - assertEquals(2, resultSeries.size()); - assertEquals("da1", resultSeries.getSimulationDatasets().get(0).getName()); - - } - - @Test - public void getSimulationSeriesByGraphId() { - - SimulationSeries series = new SimulationSeries(); - long userId = 7; - series.setUserId(Integer.toString(7)); - - SimulationSeriesParameters parameters = new SimulationSeriesParameters(); - parameters.setGraphId(23); - parameters.setGraphName("testGraphName123"); - series.setParameters(parameters); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.flush(); - em.getTransaction().commit(); - long seriesId = series.getId(); - em.close(); - - List resultSeries = null; - try { - resultSeries = entityHandler.getSimulationSeriesByUser(Integer.toString(7), 23, 0, 10); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultSeries); - assertEquals(resultSeries.size(), 1); - assertNotNull(resultSeries.get(0).getParameters()); - assertEquals(23, resultSeries.get(0).getParameters().getGraphId()); - - } - - @Test - public void getSimulationSeriesWithGraph() { - - SimulationSeries series = new SimulationSeries(); - CustomGraph graph = new CustomGraph(); - graph.setName("testGraphName"); - long userId = 7; - series.setUserId(Integer.toString(7)); - series.setNetwork(graph); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.flush(); - em.getTransaction().commit(); - long seriesId = series.getId(); - long graphId = graph.getId(); - em.close(); - - SimulationSeries resultSeries = null; - try { - resultSeries = entityHandler.getSimulationSeries(seriesId); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultSeries); - assertEquals(Long.toString(userId), resultSeries.getUserId()); - assertEquals(seriesId, resultSeries.getId()); - assertNotNull(resultSeries.getNetwork()); - assertEquals("testGraphName", resultSeries.getNetwork().getName()); - assertEquals(graphId, resultSeries.getNetwork().getId()); - } - - @Test - public void deleteSimulationSeries() { - - SimulationSeries series = new SimulationSeries(); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series); - em.flush(); - em.getTransaction().commit(); - long seriesId = series.getId(); - - - try { - entityHandler.delete(series); - } catch (Exception e) { - e.printStackTrace(); - } - - SimulationSeries resultSeries = null; - em.getTransaction().begin(); - resultSeries = em.find(SimulationSeries.class, seriesId); - em.getTransaction().commit(); - em.close(); - - assertNotNull(resultSeries); - assertEquals(seriesId, resultSeries.getId()); - } - - - @Test - public void getSimulationSeriesByUser() { - - long userId = 23; - - SimulationSeries series1 = new SimulationSeries(); - series1.setUserId(Long.toString(userId)); - - SimulationSeries series2 = new SimulationSeries(); - series2.setUserId(Long.toString(userId)); - - SimulationSeries series3 = new SimulationSeries(); - series3.setUserId(Integer.toString(22)); - - SimulationSeries series4 = new SimulationSeries(); - series4.setUserId(Long.toString(userId)); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(series1); - em.persist(series2); - em.persist(series3); - em.persist(series4); - em.flush(); - em.getTransaction().commit(); - em.close(); - - List resultSeries = null; - try { - resultSeries = entityHandler.getSimulationSeriesByUser(Long.toString(userId)); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultSeries); - assertEquals(3, resultSeries.size()); - - } - - -/////////////////////// Simulation Series Group ////////////////////////// - - @Test - public void storeSimulationSeriesGroup() { - - SimulationSeriesGroup simulation = new SimulationSeriesGroup(); - long Id = 0; - try { - Id = entityHandler.store(simulation, Long.toString(Id)); - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = factory.createEntityManager(); - SimulationSeriesGroup result; - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - result = em.find(SimulationSeriesGroup.class, Id); - tx.commit(); - } catch (RuntimeException e) { - tx.rollback(); - throw e; - } - em.close(); - - assertNotNull(result); - assertEquals(Id, result.getId()); - } - - @Test - public void getSimulationSeriesGroup() { - - SimulationSeriesGroup simulation = new SimulationSeriesGroup(); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(simulation); - em.flush(); - em.getTransaction().commit(); - long Id = simulation.getId(); - em.close(); - - SimulationSeriesGroup result = null; - try { - result = entityHandler.getSimulationSeriesGroup(Id); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(result); - assertEquals(Id, result.getId()); - - } - - @Test - public void deleteSimulationSeriesGroup() { - - SimulationSeriesGroup simulation = new SimulationSeriesGroup(); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(simulation); - em.flush(); - em.getTransaction().commit(); - long Id = simulation.getId(); - - - try { - entityHandler.delete(simulation); - } catch (Exception e) { - e.printStackTrace(); - } - - SimulationSeriesGroup result = null; - em.getTransaction().begin(); - result = em.find(SimulationSeriesGroup.class, Id); - em.getTransaction().commit(); - em.close(); - - assertNotNull(result); - assertEquals(Id, result.getId()); - - } - - @Test - public void getSimulationSeriesGroupByUser() { - - long userId = 25; - - SimulationSeriesGroup s1 = new SimulationSeriesGroup(); - s1.setUserId(Long.toString(userId)); - - SimulationSeriesGroup s2 = new SimulationSeriesGroup(); - s2.setUserId(Integer.toString(12)); - - SimulationSeriesGroup s3 = new SimulationSeriesGroup(); - s3.setUserId(Long.toString(userId)); - - SimulationSeriesGroup s4 = new SimulationSeriesGroup(); - s4.setUserId(Integer.toString(15)); - - EntityManager em = factory.createEntityManager(); - em.getTransaction().begin(); - em.persist(s1); - em.persist(s2); - em.persist(s3); - em.persist(s4); - em.flush(); - em.getTransaction().commit(); - em.close(); - - List resultList = null; - try { - resultList = entityHandler.getSimulationSeriesGroups(Long.toString(userId)); - } catch (Exception e) { - e.printStackTrace(); - } - - assertNotNull(resultList); - assertEquals(2, resultList.size()); - - } - -} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationPersistenceTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationPersistenceTest.java new file mode 100644 index 00000000..2980f15f --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/SimulationPersistenceTest.java @@ -0,0 +1,314 @@ +package i5.las2peer.services.ocd.cooperation.data; + +import i5.las2peer.services.ocd.cooperation.data.simulation.*; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.utils.Database; +import i5.las2peer.services.ocd.utils.DatabaseConfig; +import org.graphstream.graph.Node; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class SimulationPersistenceTest { + private static CustomGraph graph; + private static Node n[]; + private static Database database; + private String map = "MAP 11111"; + + + @BeforeClass + public static void clearDatabase() { + database = new Database(true); + } + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + + /////////////////////// Simulation Series ////////////////////////// + + @Test + public void storeSimulationSeries() { + System.out.println("store sim series"); + SimulationSeries series = new SimulationSeries(); + series.setCooperationEvaluation(new Evaluation(new double[]{1.0,2.0,3.0})); + long userId = 7; + series.setUserId(Long.toString(userId)); + + String seriesKey = ""; + try { + seriesKey = database.storeSimulationSeries(series, Long.toString(userId)); + } catch (Exception e) { + e.printStackTrace(); + } + + SimulationSeries resultSeries; + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertEquals(Long.toString(userId), resultSeries.getUserId()); + assertEquals(seriesKey, resultSeries.getKey()); + + } + + + @Test + public void storeSimulationSeriesWithDatasets() { + + SimulationSeries series = new SimulationSeries(); + SimulationDataset d1 = new SimulationDataset(); + d1.setName("da1"); + + SimulationDataset d2 = new SimulationDataset(); + d2.setName("da2"); + List list = new ArrayList<>(); + list.add(d1); // add key of SimulationDataset returned when it is stored in db + list.add(d2); + series.setSimulationDatasets(list); + long userId = 7; + series.setUserId(Long.toString(userId)); + + String seriesKey = ""; + try { + seriesKey = database.storeSimulationSeries(series, Long.toString(userId)); + } catch (Exception e) { + e.printStackTrace(); + } + + + SimulationSeries resultSeries; + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertNotNull(resultSeries.getSimulationDatasets()); + assertEquals(2, resultSeries.size()); + assertEquals("da1", resultSeries.getSimulationDatasets().get(0).getName()); + + } + + @Test + public void getSimulationSeries() { + + SimulationSeries series = new SimulationSeries(); + long userId = 7; + series.setUserId(Integer.toString(7)); + String seriesKey = database.storeSimulationSeries(series); + SimulationSeries resultSeries = null; + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertEquals(Long.toString(userId), resultSeries.getUserId()); + assertEquals(seriesKey, resultSeries.getKey()); + + } + + @Test + public void getSimulationSeriesWithDatasets() { + + SimulationSeries series = new SimulationSeries(); + long userId = 7; + series.setUserId(Integer.toString(7)); + + SimulationDataset d1 = new SimulationDataset(); + d1.setName("da1"); + SimulationDataset d2 = new SimulationDataset(); + d2.setName("da2"); + List list = new ArrayList<>(); + list.add(d1); + list.add(d2); + + series.setSimulationDatasets(list); + + + String seriesKey = database.storeSimulationSeries(series); + SimulationSeries resultSeries = null; + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertNotNull(resultSeries.getSimulationDatasets()); + assertEquals(2, resultSeries.size()); + assertEquals("da1", resultSeries.getSimulationDatasets().get(0).getName()); + + } + + @Test + public void getSimulationSeriesByGraphId() { + + SimulationSeries series = new SimulationSeries(); + long userId = 7; + series.setUserId(Integer.toString(7)); + + SimulationSeriesParameters parameters = new SimulationSeriesParameters(); + parameters.setGraphKey("23"); + parameters.setGraphName("testGraphName123"); + series.setSimulationSeriesParameters(parameters); + + String seriesKey = database.storeSimulationSeries(series); + List resultSeries = null; + + resultSeries = database.getSimulationSeriesByUser(Integer.toString(7), "23", 0, 10); + System.out.println("size of resultSeries is " + resultSeries.size()); + assertNotNull(resultSeries); + assertEquals(1, resultSeries.size() ); + assertNotNull(resultSeries.get(0).getSimulationSeriesParameters()); + assertEquals("23", resultSeries.get(0).getSimulationSeriesParameters().getGraphKey()); + + } + + @Test + public void getSimulationSeriesWithGraph() { + + SimulationSeries series = new SimulationSeries(); + CustomGraph graph = new CustomGraph(); + graph.setName("testGraphName"); + long userId = 7; + database.storeGraph(graph); + series.setUserId(Integer.toString(7)); + series.setNetwork(graph); + + String seriesKey = database.storeSimulationSeries(series); + System.out.println("seriesKey is "+ seriesKey); + + SimulationSeries resultSeries = null; + + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertEquals(Long.toString(userId), resultSeries.getUserId()); + assertEquals(seriesKey, resultSeries.getKey()); + assertNotNull(resultSeries.getNetwork()); + assertEquals("testGraphName", resultSeries.getNetwork().getName()); + assertEquals(graph.getKey(), resultSeries.getNetwork().getKey()); + } + + @Test + public void deleteSimulationSeries() { + + SimulationSeries series = new SimulationSeries(); + String seriesKey = database.storeSimulationSeries(series); + database.deleteSimulationSeries(seriesKey); + SimulationSeries resultSeries = null; + resultSeries = database.getSimulationSeries(seriesKey); + + assertNotNull(resultSeries); + assertEquals(null, resultSeries.getKey()); + + } + + @Test + public void getSimulationSeriesByUser() { + + long userId = 23; + + SimulationSeries series1 = new SimulationSeries(); + series1.setUserId(Long.toString(userId)); + + SimulationSeries series2 = new SimulationSeries(); + series2.setUserId(Long.toString(userId)); + + SimulationSeries series3 = new SimulationSeries(); + series3.setUserId(Integer.toString(22)); + + SimulationSeries series4 = new SimulationSeries(); + series4.setUserId(Long.toString(userId)); + + + database.storeSimulationSeries(series1); + database.storeSimulationSeries(series2); + database.storeSimulationSeries(series3); + database.storeSimulationSeries(series4); + + List resultSeries = null; + resultSeries = database.getSimulationSeriesByUser(Long.toString(userId)); + + + assertNotNull(resultSeries); + assertEquals(3, resultSeries.size()); + + } + + /////////////////////// Simulation Series Group ////////////////////////// + + @Test + public void storeSimulationSeriesGroup() { + + SimulationSeriesGroup simulation = new SimulationSeriesGroup(); + String userId = "testUser"; + simulation.setUserId(userId); + String ssgKey = database.storeSimulationSeriesGroup(simulation); + + SimulationSeriesGroup result = database.getSimulationSeriesGroup(ssgKey); + + assertNotNull(result); + assertEquals(ssgKey, result.getKey()); + } + + @Test + public void getSimulationSeriesGroup() { + + SimulationSeriesGroup simulation = new SimulationSeriesGroup(); + String ssgKey = database.storeSimulationSeriesGroup(simulation); + SimulationSeriesGroup result = database.getSimulationSeriesGroup(ssgKey); + assertNotNull(result); + assertEquals(ssgKey, result.getKey()); + + } + + @Test + public void deleteSimulationSeriesGroup() { + + SimulationSeriesGroup simulation = new SimulationSeriesGroup(); + String ssgKey = database.storeSimulationSeriesGroup(simulation); + database.deleteSimulationSeriesGroup(ssgKey); + SimulationSeriesGroup result = database.getSimulationSeriesGroup(ssgKey); + assertNotNull(result); + assertEquals(null, result.getKey()); + + } + + @Test + public void getSimulationSeriesGroupByUser() { + + String userId = "25"; + + SimulationSeriesGroup s1 = new SimulationSeriesGroup(); + s1.setUserId(userId); + + SimulationSeriesGroup s2 = new SimulationSeriesGroup(); + s2.setUserId("12"); + + SimulationSeriesGroup s3 = new SimulationSeriesGroup(); + s3.setUserId(userId); + + SimulationSeriesGroup s4 = new SimulationSeriesGroup(); + s4.setUserId("15"); + + + database.storeSimulationSeriesGroup(s1); + database.storeSimulationSeriesGroup(s2); + database.storeSimulationSeriesGroup(s3); + database.storeSimulationSeriesGroup(s4); + + List resultList = database.getSimulationSeriesGroups(userId); + + for (SimulationSeriesGroup ssg : resultList){ + System.out.println(ssg.getKey()); + } + + assertNotNull(resultList); + assertEquals(2, resultList.size()); + + } + + + +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/EvaluationTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/EvaluationTest.java index b512a38e..cac2d0b6 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/EvaluationTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/EvaluationTest.java @@ -4,8 +4,6 @@ import org.junit.Test; -import i5.las2peer.services.ocd.cooperation.data.simulation.Evaluation; - public class EvaluationTest { double[] values; @@ -77,17 +75,17 @@ public void minTest() { values = new double[]{1.4, 4.8, 0.7, 2.2}; evaluation = new Evaluation(values); - result = evaluation.getMin(); + result = evaluation.getMinimum(); assertEquals(0.7, result, 0.0001); values = new double[]{800.0, 1200.0, 400.0}; evaluation = new Evaluation(values); - result = evaluation.getMin(); + result = evaluation.getMinimum(); assertEquals(400, result, 0.0001); values = new double[]{0.0, 0.0, 0.0}; evaluation = new Evaluation(values); - result = evaluation.getMin(); + result = evaluation.getMinimum(); assertEquals(0, result, 0.0001); } @@ -96,17 +94,17 @@ public void maxTest() { values = new double[]{1.4, 4.8, 0.7, 2.2}; evaluation = new Evaluation(values); - result = evaluation.getMax(); + result = evaluation.getMaximum(); assertEquals(4.8, result, 0.0001); values = new double[]{800.0, 1200.0, 400.0}; evaluation = new Evaluation(values); - result = evaluation.getMax(); + result = evaluation.getMaximum(); assertEquals(1200, result, 0.0001); values = new double[]{0.0, 0.0, 0.0}; evaluation = new Evaluation(values); - result = evaluation.getMax(); + result = evaluation.getMaximum(); assertEquals(0, result, 0.0001); } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesTest.java index 6a28d8bb..b49b78b6 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/data/simulation/SimulationSeriesTest.java @@ -286,12 +286,8 @@ public void averageCooperationValue() { Mockito.doReturn(cooperation).when(simulation).getFinalCooperationValues(); double result = simulation.averageCooperationValue(); - - //TODO: @MaxKissgen It is a bit unclear to me what this method is intended to do. - //The averageCooperationValue of a Simulation is initialised with zero. If nothing is done to it, then of course the original assert below will fail. - //assertEquals(0.4, result, 0.00000001); - - assertEquals(0.0, result, 0.00000001); + + assertEquals(0.4, result, 0.00000001); } @Test @@ -302,12 +298,8 @@ public void averagePayoffValue() { Mockito.doReturn(values).when(simulation).getFinalPayoffValues(); double result = simulation.averagePayoffValue(); - - //TODO: @MaxKissgen As above, it is unclear to me what this method is intended to do. - //The averagePayoffValue of a Simulation is initialised with zero. If nothing is done to it, then of course the original assert below will fail. - //assertEquals(0.48, result, 0.00000001); - assertEquals(0.0, result, 0.00000001); + assertEquals(0.48, result, 0.00000001); } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/AgentTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/AgentTest.java index 11f46b21..7273ee12 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/AgentTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/AgentTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.la4j.matrix.dense.Basic2DMatrix; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; @@ -16,6 +17,10 @@ import sim.field.network.Network; import sim.util.Bag; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.UUID; + @RunWith(MockitoJUnitRunner.class) public class AgentTest { @@ -148,7 +153,6 @@ public void getNeighbourhoodTest() { resultBag = agent.calculateNeighbourhood(network); assertNotNull(resultBag); assertEquals(0, resultBag.size()); - network.addEdge(agent, agent1, true); resultBag = agent.calculateNeighbourhood(network); assertNotNull(resultBag); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilderTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilderTest.java index a31ee0a4..143f2429 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilderTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/cooperation/simulation/SimulationBuilderTest.java @@ -16,7 +16,10 @@ import i5.las2peer.services.ocd.graphs.GraphType; import sim.field.network.Network; import sim.util.Bag; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; + +import java.util.UUID; public class SimulationBuilderTest { @@ -98,16 +101,16 @@ public void buildNetworkTest() { SimulationBuilder simulationBuilder = new SimulationBuilder(); CustomGraph graph = new CustomGraph(); - Node n0 = graph.createNode(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - - graph.createEdge(n0, n1); - graph.createEdge(n1, n2); - graph.createEdge(n3, n2); - graph.createEdge(n4, n1); + Node n0 = graph.addNode("n0"); + Node n1 = graph.addNode("n1"); + Node n2 = graph.addNode("n2"); + Node n3 = graph.addNode("n3"); + Node n4 = graph.addNode("n4"); + + graph.addEdge(UUID.randomUUID().toString(), n0, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); + graph.addEdge(UUID.randomUUID().toString(), n4, n1); Network network = simulationBuilder.buildNetwork(graph); assertNotNull(network); @@ -143,14 +146,14 @@ public void buildNetworkSelfLoops() { //@MaxKissgen Previously, SELF_LOOPS was only added to the Set returned from getTypes(). //This set is not the internal list of types of a graph, and SELF_LOOPS would therefore not have been added to it and the SimulationBuilderTest would have failed. graph.addType(GraphType.SELF_LOOPS); - - Node n0 = graph.createNode(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - - graph.createEdge(n0, n1); - graph.createEdge(n1, n1); - graph.createEdge(n0, n2); + + Node n0 = graph.addNode("n0"); + Node n1 = graph.addNode("n1"); + Node n2 = graph.addNode("n2"); + + graph.addEdge(UUID.randomUUID().toString(), n0, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n1); + graph.addEdge(UUID.randomUUID().toString(), n0, n2); simulationBuilder.buildNetwork(graph); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CommunityTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CommunityTest.java index f94f751b..79a13a39 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CommunityTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CommunityTest.java @@ -11,7 +11,7 @@ import static org.mockito.Mockito.*; import org.mockito.runners.MockitoJUnitRunner; -import y.base.Node; +import org.graphstream.graph.Node; @RunWith(MockitoJUnitRunner.class) public class CommunityTest { diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverDatabaseTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverDatabaseTest.java new file mode 100644 index 00000000..bee31588 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverDatabaseTest.java @@ -0,0 +1,127 @@ +package i5.las2peer.services.ocd.graphs; + +import static org.junit.Assert.assertEquals; +import i5.las2peer.services.ocd.benchmarks.OcdBenchmarkException; +import i5.las2peer.services.ocd.benchmarks.GroundTruthBenchmark; +import i5.las2peer.services.ocd.benchmarks.OcdBenchmarkExecutor; +import i5.las2peer.services.ocd.benchmarks.OcdBenchmarkFactory; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import i5.las2peer.services.ocd.metrics.OcdMetricType; +import i5.las2peer.services.ocd.utils.Database; +import i5.las2peer.services.ocd.utils.DatabaseConfig; +import i5.las2peer.services.ocd.utils.ThreadHandler; + +import java.awt.Color; +import java.util.*; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; +import org.junit.Test; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; + +import org.la4j.matrix.Matrix; +import org.la4j.matrix.sparse.CCSMatrix; + + +//@Ignore +public class CoverDatabaseTest { + + private static final String userName = "coverPersistenceUser"; + private static final String graphName = "coverPersistenceGraph"; + private static final String coverName = "coverPersistenceCover"; + private static final String invalidCoverName = "invalidCoverName"; + private static Database database; + + @BeforeClass + public static void clearDatabase() { + database = new Database(true); + } + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + @Test + public void testPersist() { + CustomGraph graph = new CustomGraph(); + graph.setUserName(userName); + graph.setName(graphName); + Node nodeA = graph.addNode("nodeA"); + Node nodeB = graph.addNode("nodeB"); + Node nodeC = graph.addNode("nodeC"); + graph.setNodeName(nodeA, "A"); + graph.setNodeName(nodeB, "B"); + graph.setNodeName(nodeC, "C"); + Edge edgeAB = graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); + graph.setEdgeWeight(edgeAB, 5); + Edge edgeBC = graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeC); + graph.setEdgeWeight(edgeBC, 2.5); + + String Gkey = database.storeGraph(graph); + System.out.println("graph key: " + graph.getKey()); + + Matrix memberships = new CCSMatrix(3, 2); + memberships.set(0, 0, 1); + memberships.set(1, 0, 0.5); + memberships.set(1, 1, 0.5); + memberships.set(2, 1, 1); + HashMap params = new HashMap(); + params.put("param1", "val1"); + params.put("param2", "val2"); + CoverCreationLog algo = new CoverCreationLog(CoverCreationType.UNDEFINED, params, new HashSet()); + Cover cover = new Cover(graph, memberships); + cover.setCreationMethod(algo); + cover.setName(coverName); + cover.setCommunityColor(1, Color.BLUE); + cover.setCommunityName(1, "Community1"); + OcdMetricLog metric = new OcdMetricLog(OcdMetricType.EXECUTION_TIME, 3.55, params, cover); + cover.addMetric(metric); + + database.storeCover(cover); + + List queryResults = database.getCoversByName(coverName, cover.getGraph()); + assertEquals(1, queryResults.size()); + Cover persistedCover = queryResults.get(0); + persistedCover.toString(); + System.out.println("Name: " + persistedCover.getName()); + System.out.println("Community Count: " + persistedCover.communityCount()); + System.out.println("Algo: " + persistedCover.getCreationMethod().getType().toString()); + System.out.println("Metrics Count: " + persistedCover.getMetrics().size()); + for(int i=0; i params = new HashMap(); - params.put("param1", "val1"); - params.put("param2", "val2"); - CoverCreationLog algo = new CoverCreationLog(CoverCreationType.UNDEFINED, params, new HashSet()); - Cover cover = new Cover(graph, memberships); - cover.setCreationMethod(algo); - cover.setName(coverName); - cover.setCommunityColor(1, Color.BLUE); - cover.setCommunityName(1, "Community1"); - OcdMetricLog metric = new OcdMetricLog(OcdMetricType.EXECUTION_TIME, 3.55, params, cover); - cover.addMetric(metric); - tx = em.getTransaction(); - try { - tx.begin(); - em.persist(cover); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - CoverId cId = new CoverId(cover.getId(), gId); - em = emf.createEntityManager(); - TypedQuery query = em.createQuery("Select c from Cover c where c.name = :name", Cover.class); - query.setParameter("name", coverName); - List queryResults = query.getResultList(); - em.close(); - //assertEquals(1, queryResults.size()); - Cover persistedCover = queryResults.get(0); - System.out.println("Name: " + persistedCover.getName()); - System.out.println("Community Count: " + persistedCover.communityCount()); - System.out.println("Algo: " + persistedCover.getCreationMethod().getType().toString()); - System.out.println("Metrics Count: " + persistedCover.getMetrics().size()); - for(int i=0; i parameters = new HashMap(); - CustomGraph graph = new CustomGraph(); - OcdBenchmarkFactory benchmarkFactory = new OcdBenchmarkFactory(); - GroundTruthBenchmark benchmark = (GroundTruthBenchmark)benchmarkFactory.getInstance(benchmarkType, parameters); - GraphCreationLog log = new GraphCreationLog(benchmarkType, parameters); - graph.setCreationMethod(log); - graph.setName(graphNameStr); - Cover cover = new Cover(graph, new CCSMatrix()); - cover.setName(coverNameStr); - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - em.persist(cover); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - System.out.println("CID: " + cover.getId()); - System.out.println("GID: " + graph.getId()); - OcdBenchmarkExecutor executor = new OcdBenchmarkExecutor(); - Cover calculatedCover = executor.calculateGroundTruthBenchmark(benchmark); - CustomGraph calculatedGraph = calculatedCover.getGraph(); - CustomGraphId gId = new CustomGraphId(graph.getId(), graph.getUserName()); - CoverId cId = new CoverId(cover.getId(), gId); - - em = emf.createEntityManager(); - tx = em.getTransaction(); - try { - tx.begin(); - System.out.println("PrePersistG"); - Cover pCover = em.find(Cover.class, cId); - pCover.getGraph().setStructureFrom(calculatedGraph); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - em = emf.createEntityManager(); - tx = em.getTransaction(); - try { - tx.begin(); - System.out.println("PrePersistC"); - Cover pCover = em.find(Cover.class, cId); - pCover.setMemberships(calculatedCover.getMemberships()); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - - em = emf.createEntityManager(); - tx = em.getTransaction(); - Cover coverRead; - try { - tx.begin(); - coverRead = em.find(Cover.class, cId); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - - assertEquals(4, coverRead.communityCount()); - System.out.println("RPCID: " + coverRead.getId()); - System.out.println("RPGID: " + coverRead.getGraph().getId()); - System.out.println("Nodes: " + coverRead.getGraph().nodeCount()); - System.out.println(coverRead); - - } - -} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverTest.java index 3f438fc0..a32f489a 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CoverTest.java @@ -20,7 +20,7 @@ import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; +import org.graphstream.graph.Node; public class CoverTest { @@ -32,7 +32,7 @@ public class CoverTest { @Before public void sawmillCoverSetUp() throws AdapterException, FileNotFoundException { CustomGraph graph = OcdTestGraphFactory.getSawmillGraph(); - Matrix memberships = new Basic2DMatrix(graph.nodeCount(), 5); + Matrix memberships = new Basic2DMatrix(graph.getNodeCount(), 5); for(int i=0; i indices = cover.getCommunityIndices(nodes[0]); assertEquals(1, indices.size()); assertEquals(5, (int)indices.get(0)); @@ -140,7 +140,7 @@ public void testSetEntriesBelowThresholdToZero() { memberships.set(0, 3, 3); memberships.set(0, 4, 3); CustomGraph graph = new CustomGraph(); - graph.createNode(); + graph.addNode("1"); Cover cover = new Cover(graph, memberships); System.out.println(cover); cover.setRowEntriesBelowThresholdToZero(memberships, 0, 0.3); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphDatabaseTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphDatabaseTest.java new file mode 100644 index 00000000..29d52548 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphDatabaseTest.java @@ -0,0 +1,116 @@ +package i5.las2peer.services.ocd.graphs; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.utils.Database; +import i5.las2peer.services.ocd.utils.DatabaseConfig; +import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; + +import java.io.FileNotFoundException; +import java.util.*; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.Persistence; +import javax.persistence.TypedQuery; + +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +//@Ignore +public class CustomGraphDatabaseTest { + + private static final String userName1 = "testUser1"; + private static final String graphName1 = "persistenceTestGraph1"; + private static final String invalidGraphName = "invalidGraphName"; + private static Database database; + + @BeforeClass + public static void clearDatabase() { + database = new Database(true); + } + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + @Test + public void testPersist() { + CustomGraph graph = new CustomGraph(); + graph.setUserName(userName1); + graph.setName(graphName1); + Node nodeA = graph.addNode("A"); + Node nodeB = graph.addNode("B"); + Node nodeC = graph.addNode("C"); + graph.setNodeName(nodeA, "A"); + graph.setNodeName(nodeB, "B"); + graph.setNodeName(nodeC, "C"); + Edge edgeAB = graph.addEdge(UUID.randomUUID().toString(), nodeA, nodeB); + graph.setEdgeWeight(edgeAB, 5); + Edge edgeBC = graph.addEdge(UUID.randomUUID().toString(), nodeB, nodeC); + graph.setEdgeWeight(edgeBC, 2.5); + graph.addType(GraphType.DIRECTED); + + database.storeGraph(graph); + + List queryResults = database.getGraphsbyName(graphName1); + + assertEquals(1, queryResults.size()); + CustomGraph persistedGraph = queryResults.get(0); + assertNotNull(persistedGraph); + System.out.println("Username: " + persistedGraph.getUserName()); + System.out.println("Graphname: " + persistedGraph.getName()); + System.out.println("Nodecount: " + persistedGraph.getNodeCount()); + System.out.println("Edgecount: " + persistedGraph.getEdgeCount()); + assertEquals(graphName1, persistedGraph.getName()); + assertEquals(userName1, persistedGraph.getUserName()); + assertEquals(3, persistedGraph.getNodeCount()); + assertEquals(2, persistedGraph.getEdgeCount()); + Set nodeNames = new HashSet(); + nodeNames.add("A"); + nodeNames.add("B"); + nodeNames.add("C"); + Node[] nodes = graph.nodes().toArray(Node[]::new); + for(int i=0; i<3; i++) { + Node node = nodes[i]; + String name = persistedGraph.getNodeName(node); + System.out.println("Node: " + node.getIndex() + ", Name: " + persistedGraph.getNodeName(node)); + assertTrue(nodeNames.contains(name)); + nodeNames.remove(name); + } + Edge[] edges = persistedGraph.edges().toArray(Edge[]::new); + for(int i=0; i<2; i++) { + Edge edge =edges[i]; + Double weight = persistedGraph.getEdgeWeight(edge); + if(weight == 5) { + assertEquals("A", persistedGraph.getNodeName(edge.getSourceNode())); + assertEquals("B", persistedGraph.getNodeName(edge.getTargetNode())); + } + else if(weight == 2.5) { + assertEquals("B", persistedGraph.getNodeName(edge.getSourceNode())); + assertEquals("C", persistedGraph.getNodeName(edge.getTargetNode())); + } + else { + throw new IllegalStateException("Invalid Node Weight"); + } + } + assertEquals(1, persistedGraph.getTypes().size()); + assertTrue(persistedGraph.getTypes().contains(GraphType.DIRECTED)); + System.out.println("Types: " + graph.getTypes()); + + queryResults = database.getGraphs(invalidGraphName); + + assertEquals(0, queryResults.size()); + } + +} \ No newline at end of file diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphPersistenceTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphPersistenceTest.java deleted file mode 100644 index 1df37f9d..00000000 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphPersistenceTest.java +++ /dev/null @@ -1,182 +0,0 @@ -package i5.las2peer.services.ocd.graphs; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import i5.las2peer.services.ocd.adapters.AdapterException; -import i5.las2peer.services.ocd.graphs.CustomGraph; -import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; - -import java.io.FileNotFoundException; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; -import javax.persistence.TypedQuery; - -import org.junit.After; -import org.junit.Ignore; -import org.junit.Test; - -import y.base.Edge; -import y.base.Node; - -public class CustomGraphPersistenceTest { - - private static final String userName1 = "testUser1"; - private static final String graphName1 = "persistenceTestGraph1"; - private static final String invalidGraphName = "invalidGraphName"; - - EntityManagerFactory emf = Persistence.createEntityManagerFactory("ocd"); - - @Test - public void testPersist() { - EntityManager em = emf.createEntityManager(); - CustomGraph graph = new CustomGraph(); - graph.setUserName(userName1); - graph.setName(graphName1); - Node nodeA = graph.createNode(); - Node nodeB = graph.createNode(); - Node nodeC = graph.createNode(); - graph.setNodeName(nodeA, "A"); - graph.setNodeName(nodeB, "B"); - graph.setNodeName(nodeC, "C"); - Edge edgeAB = graph.createEdge(nodeA, nodeB); - graph.setEdgeWeight(edgeAB, 5); - Edge edgeBC = graph.createEdge(nodeB, nodeC); - graph.setEdgeWeight(edgeBC, 2.5); - graph.addType(GraphType.DIRECTED); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - em = emf.createEntityManager(); - TypedQuery query = em.createQuery("Select g from CustomGraph g where g.name = :name", CustomGraph.class); - query.setParameter("name", graphName1); - List queryResults = query.getResultList(); - assertEquals(1, queryResults.size()); - CustomGraph persistedGraph = queryResults.get(0); - assertNotNull(persistedGraph); - System.out.println("Username: " + persistedGraph.getUserName()); - System.out.println("Graphname: " + persistedGraph.getName()); - System.out.println("Nodecount: " + persistedGraph.nodeCount()); - System.out.println("Edgecount: " + persistedGraph.edgeCount()); - assertEquals(graphName1, persistedGraph.getName()); - assertEquals(userName1, persistedGraph.getUserName()); - assertEquals(3, persistedGraph.nodeCount()); - assertEquals(2, persistedGraph.edgeCount()); - Set nodeNames = new HashSet(); - nodeNames.add("A"); - nodeNames.add("B"); - nodeNames.add("C"); - for(int i=0; i<3; i++) { - Node node = persistedGraph.getNodeArray()[i]; - String name = persistedGraph.getNodeName(node); - System.out.println("Node: " + node.index() + ", Name: " + persistedGraph.getNodeName(node)); - assertTrue(nodeNames.contains(name)); - nodeNames.remove(name); - } - for(int i=0; i<2; i++) { - Edge edge = persistedGraph.getEdgeArray()[i]; - Double weight = persistedGraph.getEdgeWeight(edge); - if(weight == 5) { - assertEquals("A", persistedGraph.getNodeName(edge.source())); - assertEquals("B", persistedGraph.getNodeName(edge.target())); - } - else if(weight == 2.5) { - assertEquals("B", persistedGraph.getNodeName(edge.source())); - assertEquals("C", persistedGraph.getNodeName(edge.target())); - } - else { - throw new IllegalStateException("Invalid Node Weight"); - } - } - assertEquals(1, persistedGraph.getTypes().size()); - assertTrue(persistedGraph.getTypes().contains(GraphType.DIRECTED)); - System.out.println("Types: " + graph.getTypes()); - query = em.createQuery("Select graph from CustomGraph graph where graph.name = :name", CustomGraph.class); - query.setParameter("name", invalidGraphName); - queryResults = query.getResultList(); - assertEquals(0, queryResults.size()); - } - - /* - * Tests whether two instances of the same object obtained by a single entity manager - * are indeed identical (i.e. the comparison == results in TRUE). - */ - @Ignore - @Test - public void testIdentity() { - EntityManager em = emf.createEntityManager(); - CustomGraph graph = new CustomGraph(); - graph.setUserName(userName1); - graph.setName(graphName1); - Node nodeA = graph.createNode(); - Node nodeB = graph.createNode(); - Node nodeC = graph.createNode(); - graph.setNodeName(nodeA, "A"); - graph.setNodeName(nodeB, "B"); - graph.setNodeName(nodeC, "C"); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - tx.commit(); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - em = emf.createEntityManager(); - TypedQuery query = em.createQuery("Select g from CustomGraph g where g.name = :name", CustomGraph.class); - query.setParameter("name", graphName1); - List queryResults1 = query.getResultList(); - assertEquals(1, queryResults1.size()); - CustomGraph persistedGraph1 = queryResults1.get(0); - List queryResults2 = query.getResultList(); - assertEquals(1, queryResults2.size()); - CustomGraph persistedGraph2 = queryResults2.get(0); - assertTrue(persistedGraph1 == persistedGraph2); - Node node = persistedGraph1.getNodeArray()[0]; - String name1 = persistedGraph1.getNodeName(node); - String name2 = persistedGraph2.getNodeName(node); - System.out.println("name1: " + name1); - System.out.println("name2: " + name2); - assertEquals(name1, name2); - } - - @Ignore - @Test - public void testEfficiency() throws AdapterException, FileNotFoundException { - CustomGraph graph = OcdTestGraphFactory.getSiamDmGraph(); - EntityManager em = emf.createEntityManager(); - EntityTransaction tx = em.getTransaction(); - try { - tx.begin(); - em.persist(graph); - System.out.println("Commit graph"); - tx.commit(); - System.out.println("Commited graph"); - } catch( RuntimeException ex ) { - if( tx != null && tx.isActive() ) tx.rollback(); - throw ex; - } - em.close(); - } - - @After - public void after() { - emf.close(); - } - -} \ No newline at end of file diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphTest.java index 18c8f389..f273d715 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/CustomGraphTest.java @@ -4,73 +4,74 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.properties.GraphProperty; import org.junit.Test; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class CustomGraphTest { @Test public void testCopyConstructor() { CustomGraph graph = new CustomGraph(); - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - graph.createEdge(node0, node1); - graph.createEdge(node1, node0); - graph.createEdge(node0, node0); - Node node2 = graph.createNode(); - graph.createEdge(node0, node2); - graph.createEdge(node1, node2); - Edge edge5 = graph.createEdge(node2, node1); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + graph.addEdge(UUID.randomUUID().toString(), node0, node1); + graph.addEdge(UUID.randomUUID().toString(), node1, node0); + graph.addEdge(UUID.randomUUID().toString(), node0, node0); + Node node2 = graph.addNode("2"); + graph.addEdge(UUID.randomUUID().toString(), node0, node2); + graph.addEdge(UUID.randomUUID().toString(), node1, node2); + Edge edge5 = graph.addEdge(UUID.randomUUID().toString(), node2, node1); graph.setEdgeWeight(edge5, 5); CustomGraph copy = new CustomGraph(graph); - assertEquals(graph.nodeCount(), copy.nodeCount()); - assertEquals(graph.edgeCount(), copy.edgeCount()); - Edge copyEdge5 = copy.getEdgeArray()[5]; + assertEquals(graph.getNodeCount(), copy.getNodeCount()); + assertEquals(graph.getEdgeCount(), copy.getEdgeCount()); + Edge copyEdge5 = copy.getEdge(5); assertEquals(5, copy.getEdgeWeight(copyEdge5), 0); graph.setEdgeWeight(edge5, 2); assertEquals(5, copy.getEdgeWeight(copyEdge5), 0); copy.removeEdge(copyEdge5); - assertEquals(graph.edgeCount() - 1, copy.edgeCount()); + assertEquals(graph.getEdgeCount() - 1, copy.getEdgeCount()); } @Test(expected = NullPointerException.class) public void testEdgeRemoval() { CustomGraph graph = new CustomGraph(); - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - graph.createEdge(node0, node1); - graph.createEdge(node1, node0); - graph.createEdge(node0, node0); - Node node2 = graph.createNode(); - graph.createEdge(node0, node2); - graph.createEdge(node1, node2); - Edge edge5 = graph.createEdge(node2, node1); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + graph.addEdge(UUID.randomUUID().toString(), node0, node1); + graph.addEdge(UUID.randomUUID().toString(), node1, node0); + graph.addEdge(UUID.randomUUID().toString(), node0, node0); + Node node2 = graph.addNode("2"); + graph.addEdge(UUID.randomUUID().toString(), node0, node2); + graph.addEdge(UUID.randomUUID().toString(), node1, node2); + Edge edge5 = graph.addEdge(UUID.randomUUID().toString(), node2, node1); graph.setEdgeWeight(edge5, 5); - assertEquals(6, graph.edgeCount()); + assertEquals(6, graph.getEdgeCount()); graph.removeEdge(edge5); - assertEquals(5, graph.edgeCount()); + assertEquals(5, graph.getEdgeCount()); graph.getEdgeWeight(edge5); } @Test - public void getProperties() { + public void getProperties() throws InterruptedException { CustomGraph graph = new CustomGraph(); graph.addType(GraphType.DIRECTED); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); + Node n1 = graph.addNode("1"); + Node n2 = graph.addNode("2"); + Node n3 = graph.addNode("3"); + Node n4 = graph.addNode("4"); - graph.createEdge(n1, n2); - graph.createEdge(n2, n3); - graph.createEdge(n2, n4); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n2, n4); graph.initProperties(); List list = graph.getProperties(); @@ -89,32 +90,32 @@ public void getSubGraph() { CustomGraph graph = new CustomGraph(); CustomGraph result; - Node n0 = graph.createNode(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - - graph.createEdge(n0, n1); - graph.createEdge(n0, n2); - graph.createEdge(n3, n0); - graph.createEdge(n3, n2); + Node n0 = graph.addNode("0"); + Node n1 = graph.addNode("1"); + Node n2 = graph.addNode("2"); + Node n3 = graph.addNode("3"); + + graph.addEdge(UUID.randomUUID().toString(), n0, n1); + graph.addEdge(UUID.randomUUID().toString(), n0, n2); + graph.addEdge(UUID.randomUUID().toString(), n3, n0); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); List nodeIds = new ArrayList<>(); nodeIds.add(0); result = graph.getSubGraph(nodeIds); - assertEquals(1, result.nodeCount()); - assertEquals(0, result.edgeCount()); + assertEquals(1, result.getNodeCount()); + assertEquals(0, result.getEdgeCount()); nodeIds.add(3); result = graph.getSubGraph(nodeIds); - assertEquals(2, result.nodeCount()); - assertEquals(1, result.edgeCount()); + assertEquals(2, result.getNodeCount()); + assertEquals(1, result.getEdgeCount()); nodeIds.add(2); result = graph.getSubGraph(nodeIds); - assertEquals(3, result.nodeCount()); - assertEquals(3, result.edgeCount()); + assertEquals(3, result.getNodeCount()); + assertEquals(3, result.getEdgeCount()); } diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/GraphProcessorTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/GraphProcessorTest.java index 366d090c..3fff955e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/GraphProcessorTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/GraphProcessorTest.java @@ -16,17 +16,12 @@ import i5.las2peer.services.ocd.utils.Pair; import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.junit.Test; -import y.base.Edge; -import y.base.Node; -import y.base.NodeCursor; +import org.graphstream.graph.Node; +import org.graphstream.graph.Edge; public class GraphProcessorTest { @@ -35,71 +30,68 @@ public class GraphProcessorTest { * and edge weight setting, on sawmill. */ @Test - public void testMakeUndirected() throws AdapterException, FileNotFoundException { + public void testMakeUndirected() throws AdapterException, FileNotFoundException, InterruptedException { /* * Note that getSawmillGraph makes use of makeUndirected. */ CustomGraph undirectedGraph = OcdTestGraphFactory.getSawmillGraph(); CustomGraph directedGraph = OcdTestGraphFactory.getDirectedSawmillGraph(); - assertEquals(undirectedGraph.nodeCount(), directedGraph.nodeCount()); + assertEquals(undirectedGraph.getNodeCount(), directedGraph.getNodeCount()); /* * Assures that the undirected graph has precisely twice as many edges */ - assertEquals(undirectedGraph.edgeCount(), 2 * directedGraph.edgeCount()); - System.out.println("Edge Count Directed Graph: " + directedGraph.edgeCount()); - System.out.println("Edge Count Undirected Graph: " + undirectedGraph.edgeCount()); + assertEquals(undirectedGraph.getEdgeCount(), 2 * directedGraph.getEdgeCount()); + System.out.println("Edge Count Directed Graph: " + directedGraph.getEdgeCount()); + System.out.println("Edge Count Undirected Graph: " + undirectedGraph.getEdgeCount()); /* * Assures that the undirected graph includes all the original and the reverse edges * and possesses correct edge weights. */ - NodeCursor directedNodes = directedGraph.nodes(); - Node[] undirectedNodes = undirectedGraph.getNodeArray(); - while(directedNodes.ok()) { - Node directedNode = directedNodes.node(); - Node undirectedNode = undirectedNodes[directedNode.index()]; - NodeCursor directedSuccessors = directedNode.successors(); - while(directedSuccessors.ok()) { - Node directedSuccessor = directedSuccessors.node(); - Node undirectedSuccessor = undirectedNodes[directedSuccessor.index()]; - Edge edge = directedNode.getEdge(directedSuccessor); + Node[] directedNodes = directedGraph.nodes().toArray(Node[]::new); + Node[] undirectedNodes = undirectedGraph.nodes().toArray(Node[]::new); + for (Node directedNode : directedNodes) { + Node undirectedNode = undirectedNodes[directedNode.getIndex()]; + Iterator directedSuccessors = directedGraph.getSuccessorNeighbours(directedNode).iterator(); + while(directedSuccessors.hasNext()) { + Node directedSuccessor = directedSuccessors.next(); + Node undirectedSuccessor = undirectedNodes[directedSuccessor.getIndex()]; + Edge edge = directedNode.getEdgeToward(directedSuccessor); double weight = directedGraph.getEdgeWeight(edge); - Edge toEdge = undirectedNode.getEdgeTo(undirectedSuccessor); + Edge toEdge = undirectedNode.getEdgeToward(undirectedSuccessor); Edge fromEdge = undirectedNode.getEdgeFrom(undirectedSuccessor); assertNotNull(toEdge); assertNotNull(fromEdge); assertEquals(weight, undirectedGraph.getEdgeWeight(toEdge), 0); assertEquals(weight, undirectedGraph.getEdgeWeight(fromEdge), 0); - directedSuccessors.next(); } - directedNodes.next(); } } - + /* * Tests removing multi edges from a graph. */ @Test public void testRemoveMultiEdges() { CustomGraph graph = new CustomGraph(); - Node node1 = graph.createNode(); - Node node2 = graph.createNode(); - Edge edge1 = graph.createEdge(node1, node2); + Node node1 = graph.addNode("1"); + Node node2 = graph.addNode("2"); + Edge edge1 = graph.addEdge(UUID.randomUUID().toString(), node1, node2); graph.setEdgeWeight(edge1, 2d); - graph.createEdge(node1, node2); + graph.addEdge(UUID.randomUUID().toString(),node1, node2); System.out.println("Multi Edge Graph"); - System.out.println("Edge Count: " + graph.edgeCount() + "\nEdge Weights:"); - for(Edge edge : graph.getEdgeArray()) { + System.out.println("Edge Count: " + graph.getEdgeCount() + "\nEdge Weights:"); + for(Edge edge : graph.edges().toArray(Edge[]::new)) { System.out.println(graph.getEdgeWeight(edge)); } GraphProcessor processor = new GraphProcessor(); processor.removeMultiEdges(graph); System.out.println("Single Edge Graph"); - System.out.println("Edge Count: " + graph.edgeCount() + "\nEdge Weights:"); - for(Edge edge : graph.getEdgeArray()) { + System.out.println("Edge Count: " + graph.getEdgeCount() + "\nEdge Weights:"); + for(Edge edge : graph.edges().toArray(Edge[]::new)) { System.out.println(graph.getEdgeWeight(edge)); } - assertEquals(1, graph.edgeCount()); - assertEquals(3d, graph.getEdgeWeight(graph.getEdgeArray()[0]), 0.00001); + assertEquals(1, graph.getEdgeCount()); + assertEquals(3d, graph.getEdgeWeight(graph.getEdge(0)), 0.00001); } /* @@ -137,9 +129,9 @@ public void testDetermineGraphTypes() { /* * One directed edge. */ - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - graph.createEdge(node0, node1); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + graph.addEdge(UUID.randomUUID().toString(), node0, node1); processor.determineGraphTypes(graph); System.out.println("One directed edge."); System.out.println(graph.getTypes()); @@ -148,7 +140,7 @@ public void testDetermineGraphTypes() { /* * One undirected edge. */ - graph.createEdge(node1, node0); + graph.addEdge(UUID.randomUUID().toString(), node1, node0); processor.determineGraphTypes(graph); System.out.println("One undirected edge."); System.out.println(graph.getTypes()); @@ -156,7 +148,7 @@ public void testDetermineGraphTypes() { /* * Undirected edge and self loop. */ - Edge edge2 = graph.createEdge(node0, node0); + Edge edge2 = graph.addEdge(UUID.randomUUID().toString(), node0, node0); processor.determineGraphTypes(graph); System.out.println("Undirected edge and self loop."); System.out.println(graph.getTypes()); @@ -186,8 +178,8 @@ public void testDetermineGraphTypes() { /* * Undirected edge, 0 weight self loop and directed negative edge. */ - Node node2 = graph.createNode(); - Edge edge3 = graph.createEdge(node0, node2); + Node node2 = graph.addNode("2"); + Edge edge3 = graph.addEdge(UUID.randomUUID().toString(), node0, node2); graph.setEdgeWeight(edge3, -1); processor.determineGraphTypes(graph); System.out.println("Undirected edge, 0 weight self loop and directed negative edge."); @@ -237,17 +229,17 @@ public void testMakeCompatible() { compatibleTypes.add(GraphType.WEIGHTED); compatibleTypes.add(GraphType.DIRECTED); compatibleTypes.add(GraphType.SELF_LOOPS); - Node node0 = graph.createNode(); - Node node1 = graph.createNode(); - Node node2 = graph.createNode(); - Node node3 = graph.createNode(); - graph.createEdge(node0, node1); - graph.createEdge(node1, node0); - graph.createEdge(node0, node0); - Edge edge3 = graph.createEdge(node0, node2); - Edge edge4 = graph.createEdge(node1, node2); - Edge edge5 = graph.createEdge(node2, node1); - Edge edge6 = graph.createEdge(node2, node3); + Node node0 = graph.addNode("0"); + Node node1 = graph.addNode("1"); + Node node2 = graph.addNode("2"); + Node node3 = graph.addNode("3"); + graph.addEdge(UUID.randomUUID().toString(), node0, node1); + graph.addEdge(UUID.randomUUID().toString(), node1, node0); + graph.addEdge(UUID.randomUUID().toString(), node0, node0); + Edge edge3 = graph.addEdge(UUID.randomUUID().toString(), node0, node2); + Edge edge4 = graph.addEdge(UUID.randomUUID().toString(), node1, node2); + Edge edge5 = graph.addEdge(UUID.randomUUID().toString(), node2, node1); + Edge edge6 = graph.addEdge(UUID.randomUUID().toString(), node2, node3); graph.setEdgeWeight(edge3, 3); graph.setEdgeWeight(edge4, -1); graph.setEdgeWeight(edge5, 0); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/AverageDegreeTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/AverageDegreeTest.java index 0a93ab7c..ab07adca 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/AverageDegreeTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/AverageDegreeTest.java @@ -56,8 +56,8 @@ public void calculateInvalid() { @Test public void initialize() { - Mockito.when(graph.nodeCount()).thenReturn(4); - Mockito.when(graph.edgeCount()).thenReturn(8); + Mockito.when(graph.getNodeCount()).thenReturn(4); + Mockito.when(graph.getEdgeCount()).thenReturn(8); property.calculate(graph); Mockito.verify(property, Mockito.times(1)).calculate(4, 8); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficientTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficientTest.java index 091d8b95..728c512e 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficientTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/ClusteringCoefficientTest.java @@ -7,9 +7,10 @@ import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.runners.MockitoJUnitRunner; +import java.util.UUID; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; +import org.graphstream.graph.Node; @RunWith(MockitoJUnitRunner.class) public class ClusteringCoefficientTest { @@ -73,31 +74,31 @@ public void localDirected() { } @Test - public void calculateNodeLocalUndirected() { + public void calculateNodeLocalUndirected() throws InterruptedException { CustomGraph graph = new CustomGraph(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - Node n5 = graph.createNode(); - Node n6 = graph.createNode(); - - graph.createEdge(n1, n2); - graph.createEdge(n2, n1); - graph.createEdge(n1, n3); - graph.createEdge(n3, n1); - graph.createEdge(n1, n4); - graph.createEdge(n4, n1); - graph.createEdge(n1, n5); - graph.createEdge(n5, n1); - graph.createEdge(n1, n6); - graph.createEdge(n6, n1); - - graph.createEdge(n2, n3); - graph.createEdge(n3, n2); - graph.createEdge(n5, n4); - graph.createEdge(n4, n5); + Node n1 = graph.addNode(Integer.toString(1)); + Node n2 = graph.addNode(Integer.toString(2)); + Node n3 = graph.addNode(Integer.toString(3)); + Node n4 = graph.addNode(Integer.toString(4)); + Node n5 = graph.addNode(Integer.toString(5)); + Node n6 = graph.addNode(Integer.toString(6)); + + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n5); + graph.addEdge(UUID.randomUUID().toString(), n5, n1); + graph.addEdge(UUID.randomUUID().toString(), n1, n6); + graph.addEdge(UUID.randomUUID().toString(), n6, n1); + + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); + graph.addEdge(UUID.randomUUID().toString(), n5, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n5); property.calculateLocal(n1, graph); Mockito.verify(property, Mockito.times(1)).localUndirected(2, 5); @@ -105,27 +106,27 @@ public void calculateNodeLocalUndirected() { } @Test - public void calculateNodeLocal() { + public void calculateNodeLocal() throws InterruptedException { CustomGraph graph = new CustomGraph(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - graph.createEdge(n1, n2); - graph.createEdge(n2, n1); - - graph.createEdge(n1, n3); - graph.createEdge(n3, n1); - - graph.createEdge(n1, n4); - graph.createEdge(n4, n1); - - graph.createEdge(n2, n3); - graph.createEdge(n3, n2); - - graph.createEdge(n3, n4); - graph.createEdge(n4, n3); + Node n1 = graph.addNode(Integer.toString(1)); + Node n2 = graph.addNode(Integer.toString(2)); + Node n3 = graph.addNode(Integer.toString(3)); + Node n4 = graph.addNode(Integer.toString(4)); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n1); + + graph.addEdge(UUID.randomUUID().toString(), n1, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n1); + + graph.addEdge(UUID.randomUUID().toString(), n1, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n1); + + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); + + graph.addEdge(UUID.randomUUID().toString(), n3, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n3); property.calculateLocal(n1, graph); Mockito.verify(property, Mockito.times(1)).localUndirected(2, 3); @@ -133,25 +134,25 @@ public void calculateNodeLocal() { } @Test - public void initialize() { + public void initialize() throws InterruptedException { CustomGraph graph = new CustomGraph(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - graph.createEdge(n1, n2); - graph.createEdge(n2, n1); - - graph.createEdge(n1, n3); - graph.createEdge(n3, n1); - - graph.createEdge(n2, n3); - graph.createEdge(n3, n2); - - graph.createEdge(n3, n4); - graph.createEdge(n4, n3); - + Node n1 = graph.addNode(Integer.toString(1)); + Node n2 = graph.addNode(Integer.toString(2)); + Node n3 = graph.addNode(Integer.toString(3)); + Node n4 = graph.addNode(Integer.toString(4)); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n1); + + graph.addEdge(UUID.randomUUID().toString(), n1, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n1); + + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); + + graph.addEdge(UUID.randomUUID().toString(), n3, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n3); + property.calculate(graph); Mockito.verify(property, Mockito.times(2)).localUndirected(1, 2); Mockito.verify(property, Mockito.times(1)).localUndirected(1, 3); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviationTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviationTest.java index ae89c4f8..adcac4be 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviationTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DegreeDeviationTest.java @@ -8,10 +8,11 @@ import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.runners.MockitoJUnitRunner; +import java.util.UUID; import i5.las2peer.services.ocd.graphs.CustomGraph; import i5.las2peer.services.ocd.graphs.GraphType; -import y.base.Node; +import org.graphstream.graph.Node; @RunWith(MockitoJUnitRunner.class) public class DegreeDeviationTest { @@ -37,16 +38,16 @@ public void calculate() { public void initializeUndirected() { CustomGraph graph = new CustomGraph(); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - graph.createEdge(n1, n2); - graph.createEdge(n2, n1); - graph.createEdge(n2, n3); - graph.createEdge(n3, n2); - graph.createEdge(n3, n4); - graph.createEdge(n4, n3); + Node n1 = graph.addNode(Integer.toString(1)); + Node n2 = graph.addNode(Integer.toString(2)); + Node n3 = graph.addNode(Integer.toString(3)); + Node n4 = graph.addNode(Integer.toString(4)); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n1); + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n2); + graph.addEdge(UUID.randomUUID().toString(), n3, n4); + graph.addEdge(UUID.randomUUID().toString(), n4, n3); double result; result = property.calculate(graph); @@ -60,13 +61,13 @@ public void initializeDirected() { CustomGraph graph = new CustomGraph(); graph.addType(GraphType.DIRECTED); - Node n1 = graph.createNode(); - Node n2 = graph.createNode(); - Node n3 = graph.createNode(); - Node n4 = graph.createNode(); - graph.createEdge(n1, n2); - graph.createEdge(n2, n3); - graph.createEdge(n3, n4); + Node n1 = graph.addNode(Integer.toString(1)); + Node n2 = graph.addNode(Integer.toString(2)); + Node n3 = graph.addNode(Integer.toString(3)); + Node n4 = graph.addNode(Integer.toString(4)); + graph.addEdge(UUID.randomUUID().toString(), n1, n2); + graph.addEdge(UUID.randomUUID().toString(), n2, n3); + graph.addEdge(UUID.randomUUID().toString(), n3, n4); double result; result = property.calculate(graph); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DensityTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DensityTest.java index 0bd405e6..96907e51 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DensityTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/graphs/properties/DensityTest.java @@ -56,8 +56,8 @@ public void calculateInvalid() { @Test public void initialize() { - Mockito.when(graph.nodeCount()).thenReturn(4); - Mockito.when(graph.edgeCount()).thenReturn(7); + Mockito.when(graph.getNodeCount()).thenReturn(4); + Mockito.when(graph.getEdgeCount()).thenReturn(7); property.calculate(graph); Mockito.verify(property, Mockito.times(1)).calculate(4, 7); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricTest.java index f2b70e16..1a9ff4c6 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/metrics/ExtendedModularityMetricTest.java @@ -13,6 +13,7 @@ import java.io.FileNotFoundException; import java.util.HashSet; +import java.util.UUID; import org.junit.Ignore; import org.junit.Test; @@ -20,7 +21,7 @@ import org.la4j.matrix.dense.Basic2DMatrix; import org.la4j.matrix.sparse.CCSMatrix; -import y.base.Node; +import org.graphstream.graph.Node; public class ExtendedModularityMetricTest { /* @@ -29,7 +30,7 @@ public class ExtendedModularityMetricTest { @Test public void testExtendedModularityWithOneCommunity() throws AdapterException, FileNotFoundException, InterruptedException { CustomGraph graph = OcdTestGraphFactory.getSawmillGraph(); - Matrix memberships = new Basic2DMatrix(graph.nodeCount(), 1); + Matrix memberships = new Basic2DMatrix(graph.getNodeCount(), 1); for(int i=0; i edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); @@ -81,30 +77,29 @@ public static CustomGraph getAperiodicTwoCommunitiesGraph() { // Creates nodes Node n[] = new Node[11]; for (int i = 0; i < 11; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[0], n[3]); - graph.createEdge(n[0], n[4]); - graph.createEdge(n[0], n[10]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[5], n[8]); - graph.createEdge(n[5], n[9]); - graph.createEdge(n[5], n[10]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[1], n[10]); - graph.createEdge(n[4], n[10]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[9]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[10]); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } GraphProcessor processor = new GraphProcessor(); graph.addType(GraphType.DIRECTED); @@ -122,30 +117,29 @@ public static CustomGraph getDirectedAperiodicTwoCommunitiesGraph() { // Creates nodes Node n[] = new Node[11]; for (int i = 0; i < 11; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Creates edges - graph.createEdge(n[1], n[0]); - graph.createEdge(n[2], n[0]); - graph.createEdge(n[3], n[0]); - graph.createEdge(n[4], n[0]); - graph.createEdge(n[10], n[0]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[5], n[8]); - graph.createEdge(n[5], n[9]); - graph.createEdge(n[5], n[10]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[1], n[10]); - graph.createEdge(n[4], n[10]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[9]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[10]); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } graph.addType(GraphType.DIRECTED); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); @@ -161,28 +155,27 @@ public static CustomGraph getSimpleTwoComponentsGraph() { // Creates nodes Node n[] = new Node[11]; for (int i = 0; i < 11; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); } // Creates edges - graph.createEdge(n[1], n[0]); - graph.createEdge(n[2], n[0]); - graph.createEdge(n[3], n[0]); - graph.createEdge(n[4], n[0]); - graph.createEdge(n[10], n[0]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[5], n[8]); - graph.createEdge(n[5], n[9]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[1], n[10]); - graph.createEdge(n[4], n[10]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[9]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[10]); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } graph.addType(GraphType.DIRECTED); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); @@ -202,28 +195,27 @@ public static CustomGraph getLinkCommunitiesTestGraph() { graph.setName(OcdTestConstants.linkCommunitiesTestName); // Creates nodes for (int i = 0; i < 9; i++) { - graph.createNode(); + graph.addNode(Integer.toString(i)); } // Creates edges - Node n[] = graph.getNodeArray(); - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[0], n[3]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[3]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[3], n[6]); - graph.createEdge(n[4], n[5]); - graph.createEdge(n[6], n[7]); - graph.createEdge(n[6], n[8]); - graph.createEdge(n[7], n[8]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + Node n[] = graph.nodes().toArray(Node[]::new); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[8]); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } GraphProcessor processor = new GraphProcessor(); graph.addType(GraphType.DIRECTED); @@ -315,14 +307,14 @@ public static CustomGraph getMiniServiceTestGraph() { // Creates nodes Node n[] = new Node[5]; for (int i = 0; i < 5; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[0], n[3]); - graph.createEdge(n[0], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[4]); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); graph.setCreationMethod(log); @@ -369,7 +361,7 @@ public static CustomGraph getDocaTestGraph() throws FileNotFoundException, Adapt Node n[] = new Node[5]; for (int i = 0; i < 5; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(); graph.setNodeName(n[i], Integer.toString(i)); } @@ -612,24 +604,24 @@ public static CustomGraph getFiveNodesGraph() { // Creates nodes Node n[] = new Node[5]; for (int i = 0; i < 5; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[1]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[4], n[2]); - graph.createEdge(n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); // Set edge weight - graph.setEdgeWeight(graph.getEdgeArray()[0], 1); - graph.setEdgeWeight(graph.getEdgeArray()[1], -1); - graph.setEdgeWeight(graph.getEdgeArray()[2], 1); - graph.setEdgeWeight(graph.getEdgeArray()[3], -1); - graph.setEdgeWeight(graph.getEdgeArray()[4], 1); - graph.setEdgeWeight(graph.getEdgeArray()[5], 1); - graph.setEdgeWeight(graph.getEdgeArray()[6], 1); + graph.setEdgeWeight(graph.getEdge(0), 1); + graph.setEdgeWeight(graph.getEdge(1), -1); + graph.setEdgeWeight(graph.getEdge(2), 1); + graph.setEdgeWeight(graph.getEdge(3), -1); + graph.setEdgeWeight(graph.getEdge(4), 1); + graph.setEdgeWeight(graph.getEdge(5), 1); + graph.setEdgeWeight(graph.getEdge(6), 1); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); graph.setCreationMethod(log); @@ -643,24 +635,24 @@ public static CustomGraph getSimpleGraphUndirectedUnweighted() { // Create nodes Node n[] = new Node[7]; for (int i = 0; i < 7; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Create edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[3]); - graph.createEdge(n[2], n[1]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[1]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[4], n[3]); - graph.createEdge(n[4], n[6]); - graph.createEdge(n[5], n[3]); - graph.createEdge(n[6], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[4]); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); @@ -670,106 +662,110 @@ public static CustomGraph getSimpleGraphUndirectedUnweighted() { public static CustomGraph getSimpleGraphUndirectedWeighted() { CustomGraph graph = new CustomGraph(); - graph.setName("Simple Test Graph Undirected Unweighted"); + graph.setName("Simple Test Graph Undirected Weighted"); // Create nodes Node n[] = new Node[7]; for (int i = 0; i < 7; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Create edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[3]); - graph.createEdge(n[2], n[1]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[1]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[4], n[3]); - graph.createEdge(n[4], n[6]); - graph.createEdge(n[5], n[3]); - graph.createEdge(n[6], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[4]); // Set edge weights - graph.setEdgeWeight(n[0].getEdgeTo(n[1]), 3.0); - graph.setEdgeWeight(n[1].getEdgeTo(n[0]), 3.0); - graph.setEdgeWeight(n[1].getEdgeTo(n[2]), 2.0); - graph.setEdgeWeight(n[2].getEdgeTo(n[1]), 2.0); - graph.setEdgeWeight(n[1].getEdgeTo(n[3]), 2.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[1]), 2.0); - graph.setEdgeWeight(n[2].getEdgeTo(n[3]), 1.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[2]), 1.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[4]), 1.0); - graph.setEdgeWeight(n[4].getEdgeTo(n[3]), 1.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[5]), 1.0); - graph.setEdgeWeight(n[5].getEdgeTo(n[3]), 1.0); - graph.setEdgeWeight(n[4].getEdgeTo(n[6]), 4.0); - graph.setEdgeWeight(n[6].getEdgeTo(n[4]), 4.0); + graph.setEdgeWeight(n[0].getEdgeToward(n[1]), 3.0); + graph.setEdgeWeight(n[1].getEdgeToward(n[0]), 3.0); + graph.setEdgeWeight(n[1].getEdgeToward(n[2]), 2.0); + graph.setEdgeWeight(n[2].getEdgeToward(n[1]), 2.0); + graph.setEdgeWeight(n[1].getEdgeToward(n[3]), 2.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[1]), 2.0); + graph.setEdgeWeight(n[2].getEdgeToward(n[3]), 1.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[2]), 1.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[4]), 1.0); + graph.setEdgeWeight(n[4].getEdgeToward(n[3]), 1.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[5]), 1.0); + graph.setEdgeWeight(n[5].getEdgeToward(n[3]), 1.0); + graph.setEdgeWeight(n[4].getEdgeToward(n[6]), 4.0); + graph.setEdgeWeight(n[6].getEdgeToward(n[4]), 4.0); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); graph.setCreationMethod(log); + graph.addType(GraphType.WEIGHTED); return graph; } public static CustomGraph getSimpleGraphDirectedUnweighted() { CustomGraph graph = new CustomGraph(); - graph.setName("Simple Test Graph Undirected Unweighted"); + graph.setName("Simple Test Graph Directed Unweighted"); // Create nodes Node n[] = new Node[7]; for (int i = 0; i < 7; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Create edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[3]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[4], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[6]); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); graph.setCreationMethod(log); + graph.addType(GraphType.DIRECTED); return graph; } public static CustomGraph getSimpleGraphDirectedWeighted() { CustomGraph graph = new CustomGraph(); - graph.setName("Simple Test Graph Undirected Unweighted"); + graph.setName("Simple Test Graph Directed Weighted"); // Create nodes Node n[] = new Node[7]; for (int i = 0; i < 7; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Create edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[3]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[4], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[6]); // Set edge weights - graph.setEdgeWeight(n[0].getEdgeTo(n[1]), 3.0); - graph.setEdgeWeight(n[1].getEdgeTo(n[2]), 2.0); - graph.setEdgeWeight(n[1].getEdgeTo(n[3]), 2.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[2]), 1.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[4]), 1.0); - graph.setEdgeWeight(n[3].getEdgeTo(n[5]), 1.0); - graph.setEdgeWeight(n[4].getEdgeTo(n[6]), 4.0); + graph.setEdgeWeight(n[0].getEdgeToward(n[1]), 3.0); + graph.setEdgeWeight(n[1].getEdgeToward(n[2]), 2.0); + graph.setEdgeWeight(n[1].getEdgeToward(n[3]), 2.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[2]), 1.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[4]), 1.0); + graph.setEdgeWeight(n[3].getEdgeToward(n[5]), 1.0); + graph.setEdgeWeight(n[4].getEdgeToward(n[6]), 4.0); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); graph.setCreationMethod(log); + graph.addType(GraphType.DIRECTED); + graph.addType(GraphType.WEIGHTED); return graph; } @@ -784,40 +780,40 @@ public static CustomGraph getMaximalCliqueGraph() { // Create nodes Node n[] = new Node[9]; for (int i = 0; i < 9; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Create edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[8]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[1], n[8]); - graph.createEdge(n[2], n[1]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[2], n[7]); - graph.createEdge(n[2], n[8]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[3], n[6]); - graph.createEdge(n[3], n[7]); - graph.createEdge(n[4], n[3]); - graph.createEdge(n[4], n[5]); - graph.createEdge(n[5], n[3]); - graph.createEdge(n[5], n[4]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[6], n[3]); - graph.createEdge(n[6], n[5]); - graph.createEdge(n[6], n[7]); - graph.createEdge(n[7], n[2]); - graph.createEdge(n[7], n[3]); - graph.createEdge(n[7], n[5]); - graph.createEdge(n[7], n[6]); - graph.createEdge(n[8], n[0]); - graph.createEdge(n[8], n[1]); - graph.createEdge(n[8], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[8], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[8], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[8], n[2]); GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); @@ -832,39 +828,38 @@ public static CustomGraph getLinkgraph() { // Creates nodes Node n[] = new Node[8]; for (int i = 0; i < 8; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[3]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[2], n[0]); - graph.createEdge(n[2], n[1]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[2]); - graph.createEdge(n[3], n[4]); - graph.createEdge(n[3], n[5]); - graph.createEdge(n[3], n[6]); - graph.createEdge(n[4], n[3]); - graph.createEdge(n[4], n[5]); - graph.createEdge(n[4], n[6]); - graph.createEdge(n[5], n[3]); - graph.createEdge(n[5], n[4]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[6], n[3]); - graph.createEdge(n[6], n[4]); - graph.createEdge(n[6], n[5]); - graph.createEdge(n[6], n[7]); - graph.createEdge(n[7], n[5]); - graph.createEdge(n[7], n[6]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[6]); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); @@ -879,24 +874,23 @@ public static CustomGraph getModularityTestGraph() { // Creates nodes Node n[] = new Node[4]; for (int i = 0; i < 4; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[1], n[2]); - graph.createEdge(n[2], n[0]); - graph.createEdge(n[2], n[1]); - graph.createEdge(n[2], n[3]); - graph.createEdge(n[3], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[2]); - EdgeCursor edges = graph.edges(); - while(edges.ok()) { - Edge edge = edges.edge(); + Iterator edges = graph.edges().iterator(); + while(edges.hasNext()) { + Edge edge = edges.next(); graph.setEdgeWeight(edge, 1); - edges.next(); } GraphCreationLog log = new GraphCreationLog(GraphCreationType.UNDEFINED, new HashMap()); log.setStatus(ExecutionStatus.COMPLETED); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseConfigTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseConfigTest.java new file mode 100644 index 00000000..c7ee0573 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseConfigTest.java @@ -0,0 +1,38 @@ +package i5.las2peer.services.ocd.utils; + +import static org.junit.Assert.*; +import java.util.Properties; + +import org.junit.Ignore; +import org.junit.Test; + +public class DatabaseConfigTest { + private static DatabaseConfig dc = new DatabaseConfig(); + + + + @Test + public void getPropertiesTest() { + Properties props = dc.getConfigProperties(); + System.out.println("HOST:"+props.getProperty("HOST")); + assertEquals("127.0.0.1", props.getProperty("HOST")); + + System.out.println("PORT:"+props.getProperty("PORT")); + assertEquals("8529", props.getProperty("PORT")); + +// System.out.println("USER:"+props.getProperty("USER")); +// assertEquals("root", props.getProperty("USER")); + +// System.out.println("PASSWORD:"+props.getProperty("PASSWORD")); +// assertEquals("password", props.getProperty("PASSWORD")); + + System.out.println("DATABASENAME:"+props.getProperty("DATABASENAME")); + String dbName = props.getProperty("DATABASENAME"); + assertEquals("ocdDB",dbName ); + + System.out.println("TESTDATABASENAME:"+props.getProperty("TESTDATABASENAME")); + assertEquals("testDB", props.getProperty("TESTDATABASENAME")); + + } + +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseMethodTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseMethodTest.java new file mode 100644 index 00000000..356f99a2 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseMethodTest.java @@ -0,0 +1,213 @@ +package i5.las2peer.services.ocd.utils; + +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; +import java.util.Collections; +import java.util.List; + +import i5.las2peer.services.ocd.utils.Database; +import i5.las2peer.services.ocd.utils.DatabaseConfig; +import org.eclipse.persistence.config.PersistenceUnitProperties; +import org.junit.BeforeClass; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import i5.las2peer.services.ocd.adapters.AdapterException; +import i5.las2peer.services.ocd.graphs.Cover; +import i5.las2peer.services.ocd.graphs.CustomGraph; +import i5.las2peer.services.ocd.graphs.CustomGraphId; +import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; + + +public class DatabaseMethodTest { + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + private static Database database; + + @BeforeClass + public static void setupTestDatabase() { + database = new Database(true); + + } + @Before + public void clearDatabase() { + database.deleteDatabase(); + database.init(); + } + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + public CustomGraph getTestGraph() { + CustomGraph graph = null; + try { + graph = OcdTestGraphFactory.getDolphinsGraph(); + } catch (FileNotFoundException | AdapterException e) { + e.printStackTrace(); + } + return graph; + } + + @Test + public void getGraph() { + try { + CustomGraph graph = OcdTestGraphFactory.getDolphinsGraph(); + graph.setUserName("eve"); + database.storeGraph(graph); + String graphKey = graph.getKey(); + + CustomGraph resultGraph = database.getGraph("eve", graphKey); + assertNotNull(resultGraph); + assertEquals(graphKey, resultGraph.getKey()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void getGraphNotFound() { + CustomGraph graph = database.getGraph("eve", "0"); + if(graph == null) { + System.out.println("graph is null in getGraphNotFound"); + } + else {System.out.println(graph.String());} + assertNull(graph); + } + + @Test + public void storeGraph() { + + CustomGraph graph = getTestGraph(); + graph.setUserName("testUser231"); + graph.setName("testGraphName231"); + + database.storeGraph(graph); + String graphKey = graph.getKey(); + CustomGraph resultGraph = database.getGraph("testUser231", graphKey); + assertEquals(graph.getName(), resultGraph.getName()); + assertEquals(graph.getUserName(), resultGraph.getUserName()); + assertEquals(graph.getNodeCount(), resultGraph.getNodeCount()); + assertEquals(graph.getEdgeCount(), resultGraph.getEdgeCount()); + } + + @Test + public void deleteGraph() { + CustomGraph graph1 = null; + CustomGraph graph2 = null; + Cover cover = null; + try { + graph1 = OcdTestGraphFactory.getSawmillGraph(); + graph1.setUserName("eve"); + graph2 = getTestGraph(); + graph2.setUserName("eve"); + cover = new Cover(graph1); + + } catch (Exception e) { + e.printStackTrace(); + } + + database.storeGraph(graph1); + database.storeGraph(graph2); + database.storeCover(cover); + + String graphKey = graph1.getKey(); + try { + database.deleteGraph("eve", graphKey, new ThreadHandler()); + } catch (Exception e) { + e.printStackTrace(); + } + + List queryResults = database.getGraphs("eve"); + assertEquals(1, queryResults.size()); + } + + @Test + public void getCover() { + + try { + CustomGraph graph = null; + Cover cover = null; + try { + graph = OcdTestGraphFactory.getSawmillGraph(); + graph.setUserName("eve"); + cover = new Cover(graph); + } catch (Exception e) { + e.printStackTrace(); + } + database.storeGraph(graph); + database.storeCover(cover); + String graphKey = graph.getKey(); + String coverKey = cover.getKey(); + + Cover resultCover; + resultCover = database.getCover("eve", graphKey, coverKey); + assertNotNull(resultCover); + assertEquals(coverKey, resultCover.getKey()); + assertEquals(graphKey, resultCover.getGraph().getKey()); + + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("getcover success"); + } + + @Test + public void getCoverNotFound() { + Cover cover = database.getCover("eve", "2", "2"); + assertNull(cover); + System.out.println("getcovernotfound success"); + } + + @Test + public void deleteCover() { + + Cover cover1 = null; + Cover cover2 = null; + Cover cover3 = null; + CustomGraph graph = null; + try { + graph = getTestGraph(); + graph.setUserName("eve"); + cover1 = new Cover(graph); + cover2 = new Cover(graph); + cover3 = new Cover(graph); + } catch (Exception e) { + e.printStackTrace(); + } + + database.storeGraph(graph); + database.storeCover(cover1); + database.storeCover(cover2); + database.storeCover(cover3); + + String graphKey = graph.getKey(); + String cover2Key = cover2.getKey(); + + try { + database.deleteCover("eve", graphKey, cover2Key, new ThreadHandler()); + } catch (Exception e) { + e.printStackTrace(); + } + + List covers = database.getAllCoverKeys(); + assertEquals(2, covers.size()); + } + + @Test + public void deleteCoverNotFound() throws Exception { + + exception.expect(IllegalArgumentException.class); + exception.expectMessage("Cover not found"); + + database.deleteCover("eve", "3", "1", new ThreadHandler()); + } + +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseTest.java new file mode 100644 index 00000000..00024aa8 --- /dev/null +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/DatabaseTest.java @@ -0,0 +1,366 @@ +package i5.las2peer.services.ocd.utils; + +import static org.junit.Assert.*; + +import org.graphstream.graph.Node; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.*; +import java.awt.Color; + +import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory;//graphen schnell erstellen +import i5.las2peer.services.ocd.testsUtils.OcdTestCoverFactory;//cover schnell erstellen + +import i5.las2peer.services.ocd.algorithms.LOCAlgorithm; +import i5.las2peer.services.ocd.algorithms.SpeakerListenerLabelPropagationAlgorithm; +import i5.las2peer.services.ocd.algorithms.RandomWalkLabelPropagationAlgorithm; + +import i5.las2peer.services.ocd.metrics.*; +import i5.las2peer.services.ocd.metrics.OcdMetricLog; +import i5.las2peer.services.ocd.metrics.OcdMetricExecutor; +import i5.las2peer.services.ocd.metrics.StatisticalMeasure; +import i5.las2peer.services.ocd.metrics.ExtendedModularityMetric; +import i5.las2peer.services.ocd.graphs.*; + +import i5.las2peer.services.ocd.centrality.data.CentralityMap; +import i5.las2peer.services.ocd.centrality.data.CentralityCreationLog; +import i5.las2peer.services.ocd.centrality.measures.OutDegree; +import i5.las2peer.services.ocd.centrality.utils.CentralityAlgorithmExecutor; +import i5.las2peer.services.ocd.centrality.utils.CentralityAlgorithm; +import i5.las2peer.services.ocd.centrality.measures.AlphaCentrality; +import i5.las2peer.services.ocd.centrality.measures.BridgingCentrality; +import i5.las2peer.services.ocd.centrality.measures.DegreeCentrality; +import i5.las2peer.services.ocd.centrality.measures.PageRank; +import i5.las2peer.services.ocd.centrality.measures.EigenvectorCentrality; + + + +public class DatabaseTest { + private static CustomGraph graph; + private static Node n[]; + private static Database database; + private String map = "MAP 11111"; + + @BeforeClass + public static void clearDatabase() { + database = new Database(true); + } + + @AfterClass + public static void deleteDatabase() { + database.deleteDatabase(); + } + + @Test + public void test() { + Database db = new Database(true); + db.init(); + List i = new ArrayList(); + i.add(1);i.add(2); + try { + for(CustomGraph g : db.getGraphs("marcel", 0, 4, i)) { + } + }catch(Exception e) { + e.printStackTrace(); + } + + + + } + + //TODO: is this test needed? + @Test + public void persistFactoryGraph() { + Database db = new Database(true); + db.init(); + try { + + }catch(Exception e) { + } + } + + @Test + public void persistGraphs() { + Database db = new Database(true); + db.deleteDatabase(); + db.init(); + CustomGraph g1 = getGraph1(); + CustomGraph g2 = getGraph2(); + CustomGraph g3 = getGraph3(); + CustomGraph g4 = getGraph4(); + System.out.println("start"); + this.persistExampleGraphCoverCMap(g1); + this.persistExampleGraphCoverCMap(g2); + this.persistExampleGraphCoverCMap(g4); + } + + public void persistExampleGraphCoverCMap(CustomGraph g) { + Database db = new Database(true); + db.init(); + + Cover c1 = getLOCCover(g); + Cover c2 = getSLLPCover(g); + g.setNodeNames(); + g.setName("Test Graph 4 "); + g.setPath("der index pfad 4"); + g.setUserName("marcel"); + c1.setName("Test LOCCover 4"); + c1.setSimCosts(34.1); + c1.setName("Test RWLPCover 4"); + c1.setSimCosts(12.2); + + CoverCreationLog ccl = getCoverCreationLog("loc"); + CoverCreationLog ccl2 = getCoverCreationLog("sllp"); + + c1.setCreationMethod(ccl); + c2.setCreationMethod(ccl2); + + setOcdMetricLog(c1, "em"); + setOcdMetricLog(c1, "nm"); + try { + c1.setCommunityColor(0, Color.blue); + c1.setCommunityColor(1, Color.red); + }catch(Exception e) { + // there aren't enough communities + e.printStackTrace(); + } + + + + db.storeGraph(g); + CentralityMap cm = this.getCentralityMap(g, 3); + CentralityMap cm2 = this.getCentralityMap(g, 2); + + cm.setName("PageRank centrality map name"); + cm2.setName("Degree centrality map name"); + + db.storeCover(c1); + db.storeCover(c2); + + db.storeCentralityMap(cm); + db.storeCentralityMap(cm2); + } + + + private Cover getLOCCover(CustomGraph g) { + LOCAlgorithm loca = new LOCAlgorithm(); + Cover cover = new Cover(g); + try { + cover = loca.detectOverlappingCommunities(g); + } catch ( Exception e) { + e.printStackTrace(); + } + return cover; + } + private Cover getSLLPCover(CustomGraph g) { + SpeakerListenerLabelPropagationAlgorithm sllp = new SpeakerListenerLabelPropagationAlgorithm(); + Cover cover = new Cover(g); + try { + cover = sllp.detectOverlappingCommunities(g); + } catch ( Exception e) { + e.printStackTrace(); + } + return cover; + } + private CoverCreationLog getCoverCreationLog(String typ) { + int i = 0; + if(typ == "loc") {i = 26;} + else if(typ == "sllp") {i = 3;} + CoverCreationType cct = CoverCreationType.lookupType(i); + Set graphTypes = this.getSomeGraphTypes(); + Map param = this.getSomeParam(); + return new CoverCreationLog(cct, param, graphTypes); + } + + private OcdMetricLog setOcdMetricLog(Cover c, String a) { + StatisticalMeasure sm =new ExtendedModularityMetricCoMembership(); + OcdMetricType omt = OcdMetricType.lookupType(0); + OcdMetricLog oml= new OcdMetricLog(omt, 0.5, this.getSomeParam(), c); + if(a == "em") { + sm = new ExtendedModularityMetric(); + omt = OcdMetricType.lookupType(2); + } + else if(a == "nm"){ + sm = new ModularityMetric(); + omt = OcdMetricType.lookupType(7); + } + OcdMetricExecutor ome = new OcdMetricExecutor(); + try { + oml = ome.executeStatisticalMeasure(c, sm); + } catch ( Exception e) { + e.printStackTrace(); + } + return oml; + } + private Set getSomeGraphTypes() { + GraphType gt1 = GraphType.lookupType(2); + GraphType gt2 = GraphType.lookupType(5); + Set graphTypes = new HashSet(); + graphTypes.add(gt1); + graphTypes.add(gt2); + return graphTypes; + } + private Map getSomeParam(){ + Map param = new HashMap(); + param.put("par1", "val1"); + param.put("par2", "val2"); + param.put("par3", "val3"); + return param; + } + private CentralityMap getCentralityMap(CustomGraph g, int i) { + CentralityMap cm = new CentralityMap(g); + CentralityAlgorithm ca = getCentralityAlgorithm(i); + try { + CentralityAlgorithmExecutor cae = new CentralityAlgorithmExecutor(); + cm = cae.execute(g, ca); + } catch (Exception e) { + e.printStackTrace(); + } + return cm; + + } + + private CentralityAlgorithm getCentralityAlgorithm(int i) { + CentralityAlgorithm ca = new OutDegree(); + switch(i){ + case 0: + ca = new AlphaCentrality(); + break; + case 1: + ca = new BridgingCentrality(); + break; + case 2: + ca = new DegreeCentrality(); + break; + case 3: + ca = new PageRank(); + break; + default: + ca = new EigenvectorCentrality(); + break; + } + return ca; + } + + + + // Creates graph1 from Paper + private CustomGraph getGraph1() { + CustomGraph graph = new CustomGraph(); + + // Creates nodes + Node n[] = new Node[7]; + for (int i = 0; i < 7; i++) { + n[i] = graph.addNode("A_"+i); + } + + // first community (nodes: 0, 1, 2, 3) + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (i != j ) { + graph.addEdge(UUID.randomUUID().toString(), n[i], n[j]); + } + } + } + + // second community (nodes: 3, 4, 5, 6) + for(int i = 3; i < 7; i++) { + for (int j = 3; j < 7; j++) { + if(i!=j ) { + graph.addEdge(UUID.randomUUID().toString(), n[i], n[j]); + } + } + } + return graph; + } + + // Creates graph2 from Paper + private CustomGraph getGraph2() { + + graph = new CustomGraph(); + + // Creates nodes + n = new Node[8]; + for (int i = 0; i < 8; i++) { + n[i] = graph.addNode("B_" + i); + } + // first community (nodes: 0, 1, 2, 3) + e(0,1); + e(0,3); + e(1,3); + e(1,2); + e(2,3); + // second community (nodes: 4, 5, 6, 7) + for(int i = 4; i < 8; i++) { + for (int j = 4; j < 8; j++) { + if(i!=j ) { + graph.addEdge(UUID.randomUUID().toString(), n[i], n[j]); + } + } + } + + e(0,4); + e(2,4); + return graph; + } + + // Creates a graph of 0-1-2-3-4 + private CustomGraph getGraph3() { + graph = new CustomGraph(); + + // Creates nodes + n = new Node[7]; + for (int i = 0; i < 7; i++) { + n[i] = graph.addNode("C_"+i); + } + e(0,1); + e(1,2); + e(2,3); + e(3,4); + e(4,5); + e(5,6); + return graph; + } + + private CustomGraph getGraph4() { + graph = new CustomGraph(); + + // Creates nodes + n = new Node[20]; + for (int i = 0; i < 20; i++) { + n[i] = graph.addNode("D_"+i); + } + e(0,1); + e(1,2); + e(2,3); + e(3,4); + e(6,7); + e(6,8); + e(6,9); + e(7,8); + e(7,9); + e(7,17); + e(8,9); + e(8,10); + e(9,11); + e(9,12); + e(9,10); + e(10,13); + e(13,14); + e(13,15); + e(13,16); + e(14,15); + e(15,16); + e(15,18); + e(18,19); + return graph; + } + + private void e(int a, int b) { + graph.addEdge(UUID.randomUUID().toString(), n[a], n[b]); + graph.addEdge(UUID.randomUUID().toString(),n[b], n[a]); + } + +} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/EntityHandlerTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/EntityHandlerTest.java deleted file mode 100644 index 6d311ae1..00000000 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/EntityHandlerTest.java +++ /dev/null @@ -1,268 +0,0 @@ -package i5.las2peer.services.ocd.utils; - -import static org.junit.Assert.*; - -import java.io.FileNotFoundException; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.List; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.persistence.Persistence; -import javax.persistence.Query; -import javax.persistence.TypedQuery; - -import org.eclipse.persistence.config.PersistenceUnitProperties; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import i5.las2peer.services.ocd.adapters.AdapterException; -import i5.las2peer.services.ocd.graphs.Cover; -import i5.las2peer.services.ocd.graphs.CustomGraph; -import i5.las2peer.services.ocd.graphs.CustomGraphId; -import i5.las2peer.services.ocd.testsUtils.OcdTestGraphFactory; - -public class EntityHandlerTest { - - @Rule - public final ExpectedException exception = ExpectedException.none(); - - private static final String PERSISTENCE_UNIT_NAME = "ocd"; - private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, - Collections.singletonMap(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/testing/persistence.xml")); - private EntityHandler entityHandler = new EntityHandler(); - - @Before - public void clearDatabase() { - - EntityManager em = factory.createEntityManager(); - EntityTransaction etx = em.getTransaction(); - etx.begin(); - Query EdgeQuery = em.createQuery("DELETE FROM CustomEdge", CustomGraph.class); - EdgeQuery.executeUpdate(); - Query memberQuery = em.createQuery("DELETE FROM Community", CustomGraph.class); - memberQuery.executeUpdate(); - Query NodeQuery = em.createQuery("DELETE FROM CustomNode", CustomGraph.class); - NodeQuery.executeUpdate(); - Query CoverQuery = em.createQuery("DELETE FROM Cover", CustomGraph.class); - CoverQuery.executeUpdate(); - Query GraphQuery = em.createQuery("DELETE FROM CustomGraph", CustomGraph.class); - GraphQuery.executeUpdate(); - etx.commit(); - } - - public CustomGraph getTestGraph() { - - CustomGraph graph = null; - try { - graph = OcdTestGraphFactory.getDolphinsGraph(); - } catch (FileNotFoundException | AdapterException e) { - e.printStackTrace(); - } - return graph; - } - - @Test - public void getGraph() { - - try { - CustomGraph graph = OcdTestGraphFactory.getDolphinsGraph(); - graph.setUserName("eve"); - - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - em.persist(graph); - em.flush(); - tx.commit(); - long graphId = graph.getId(); - em.close(); - - CustomGraph resultGraph; - resultGraph = entityHandler.getGraph("eve", graphId); - assertNotNull(resultGraph); - assertEquals(graphId, resultGraph.getId()); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Test - public void getGraphNotFound() { - - CustomGraph graph = entityHandler.getGraph("eve", 2); - assertNull(graph); - } - - @Test - public void storeGraph() { - - CustomGraph graph = getTestGraph(); - graph.setUserName("testUser231"); - graph.setName("testGraphName231"); - - entityHandler.storeGraph(graph); - long graphId = graph.getId(); - - CustomGraphId id = new CustomGraphId(graphId, "testUser231"); - CustomGraph resultGraph = null; - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - - try { - tx.begin(); - resultGraph = em.find(CustomGraph.class, id); - tx.commit(); - } catch (RuntimeException e) { - tx.rollback(); - throw e; - } - em.close(); - - assertEquals(graph.getName(), resultGraph.getName()); - assertEquals(graph.getUserName(), resultGraph.getUserName()); - assertEquals(graph.nodeCount(), resultGraph.nodeCount()); - assertEquals(graph.edgeCount(), resultGraph.edgeCount()); - } - - @Test - public void deleteGraph() { - - CustomGraph graph1 = null; - CustomGraph graph2 = null; - Cover cover = null; - try { - graph1 = OcdTestGraphFactory.getSawmillGraph(); - graph1.setUserName("eve"); - graph2 = getTestGraph(); - graph2.setUserName("eve"); - cover = new Cover(graph1); - - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - - em.persist(graph1); - em.persist(graph2); - em.persist(cover); - - tx.commit(); - - long graphId = graph1.getId(); - try { - entityHandler.deleteGraph("eve", graphId, new ThreadHandler()); - } catch (Exception e) { - e.printStackTrace(); - } - - List queryResults; - String queryStr = "SELECT g FROM CustomGraph g WHERE g." + CustomGraph.USER_NAME_FIELD_NAME + " = :username"; - TypedQuery query = em.createQuery(queryStr, CustomGraph.class); - query.setParameter("username", "eve"); - queryResults = query.getResultList(); - em.close(); - assertEquals(1, queryResults.size()); - } - - @Test - public void getCover() { - - try { - CustomGraph graph = null; - Cover cover = null; - try { - graph = OcdTestGraphFactory.getSawmillGraph(); - graph.setUserName("eve"); - cover = new Cover(graph); - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - em.persist(graph); - em.persist(cover); - tx.commit(); - long graphId = graph.getId(); - long coverId = cover.getId(); - - Cover resultCover; - resultCover = entityHandler.getCover("eve", graphId, coverId); - assertNotNull(resultCover); - assertEquals(coverId, resultCover.getId()); - assertEquals(graphId, resultCover.getGraph().getId()); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Test - public void getCoverNotFound() { - - Cover cover = entityHandler.getCover("eve", 2, 2); - assertNull(cover); - } - - @Test - public void deleteCover() { - - Cover cover1 = null; - Cover cover2 = null; - Cover cover3 = null; - CustomGraph graph = null; - try { - graph = getTestGraph(); - graph.setUserName("eve"); - cover1 = new Cover(graph); - cover2 = new Cover(graph); - cover3 = new Cover(graph); - } catch (Exception e) { - e.printStackTrace(); - } - - EntityManager em = entityHandler.getEntityManager(); - EntityTransaction tx = em.getTransaction(); - tx.begin(); - em.persist(graph); - em.persist(cover1); - em.persist(cover2); - em.persist(cover3); - tx.commit(); - - long graphId = graph.getId(); - long cover2Id = cover2.getId(); - try { - entityHandler.deleteCover("eve", graphId, cover2Id, new ThreadHandler()); - } catch (Exception e) { - e.printStackTrace(); - } - - List queryResults; - String queryStr = "SELECT c FROM Cover c"; - TypedQuery query = em.createQuery(queryStr, Cover.class); - queryResults = query.getResultList(); - em.close(); - assertEquals(2, queryResults.size()); - } - - @Test - public void deleteCoverNotFound() throws Exception { - - exception.expect(IllegalArgumentException.class); - exception.expectMessage("Cover not found"); - - entityHandler.deleteCover("eve", 3, 1, new ThreadHandler()); - } - -} diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/InvocationHandlerTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/InvocationHandlerTest.java index 6d79a0b0..ab42d064 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/InvocationHandlerTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/utils/InvocationHandlerTest.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.UUID; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; @@ -14,12 +15,12 @@ import i5.las2peer.services.ocd.graphs.Cover; import i5.las2peer.services.ocd.graphs.CustomGraph; -import y.base.Node; +import org.graphstream.graph.Node; public class InvocationHandlerTest { - private static final String PERSISTENCE_UNIT_NAME = "ocd"; - private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); + //private static final String PERSISTENCE_UNIT_NAME = "ocd"; + //private static final EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); String username; String graphName; @@ -45,14 +46,14 @@ public void setUp() { nodes = new ArrayList<>(4); for (int i = 0; i < 4; i++) { - nodes.add(i, graph.createNode()); + nodes.add(i, graph.addNode(Integer.toString(i))); graph.setNodeName(nodes.get(i), String.valueOf(i + 1)); } - graph.createEdge(nodes.get(0), nodes.get(1)); - graph.createEdge(nodes.get(1), nodes.get(2)); - graph.createEdge(nodes.get(1), nodes.get(3)); - graph.createEdge(nodes.get(3), nodes.get(2)); + graph.addEdge(UUID.randomUUID().toString(), nodes.get(0), nodes.get(1)); + graph.addEdge(UUID.randomUUID().toString(), nodes.get(1), nodes.get(2)); + graph.addEdge(UUID.randomUUID().toString(), nodes.get(1), nodes.get(3)); + graph.addEdge(UUID.randomUUID().toString(), nodes.get(3), nodes.get(2)); cover = new Cover(graph); @@ -91,7 +92,7 @@ public void getAdjListTest() { @Test public void getMemberListTest() { - Matrix memberships = new Basic2DMatrix(graph.nodeCount(), 3); + Matrix memberships = new Basic2DMatrix(graph.getNodeCount(), 3); memberships.set(0, 0, 0.7); memberships.set(0, 1, 0.0); memberships.set(0, 2, 0.0); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/PredefinedColorsCoverPainterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/PredefinedColorsCoverPainterTest.java index 0e612551..4b844c82 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/PredefinedColorsCoverPainterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/PredefinedColorsCoverPainterTest.java @@ -16,7 +16,7 @@ public class PredefinedColorsCoverPainterTest { @Test - public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { Cover cover = ViewerTestGraphFactory.getSlpaSawmillCover(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS); @@ -26,7 +26,7 @@ public void testOnSawmill() throws AdapterException, IOException, InstantiationE } @Test - public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { Cover cover = ViewerTestGraphFactory.getSlpaDolphinsCover(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/RandomColorPainterTest.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/RandomColorPainterTest.java index a6627d4b..4e562f2b 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/RandomColorPainterTest.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/painters/RandomColorPainterTest.java @@ -16,7 +16,7 @@ public class RandomColorPainterTest { @Test - public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { Cover cover = ViewerTestGraphFactory.getSlpaSawmillCover(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS); @@ -26,7 +26,7 @@ public void testOnSawmill() throws AdapterException, IOException, InstantiationE } @Test - public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException { + public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException { Cover cover = ViewerTestGraphFactory.getSlpaDolphinsCover(); LayoutHandler handler = new LayoutHandler(); handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS); diff --git a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/testsUtil/ViewerTestGraphFactory.java b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/testsUtil/ViewerTestGraphFactory.java index a94ce67b..153aca46 100644 --- a/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/testsUtil/ViewerTestGraphFactory.java +++ b/rest_ocd_services/src/test/java/i5/las2peer/services/ocd/viewer/testsUtil/ViewerTestGraphFactory.java @@ -14,12 +14,13 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.util.HashSet; +import java.util.UUID; import org.la4j.matrix.Matrix; import org.la4j.matrix.dense.Basic2DMatrix; -import y.base.Edge; -import y.base.Node; +import org.graphstream.graph.Edge; +import org.graphstream.graph.Node; public class ViewerTestGraphFactory { @@ -30,16 +31,17 @@ public static CustomGraph getTinyCircleGraph() { // Creates 10 nodes. Node n[] = new Node[10]; for (int i = 0; i < 10; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], "id: " + i); memberships.set(i, i%2, 1); } // Creates 10 edges forming a cycle Edge e[] = new Edge[10]; for (int i = 0; i < 10; i++) { - e[i] = graph.createEdge(n[i], n[(i+1)%10]); + e[i] = graph.addEdge(UUID.randomUUID().toString(), n[i], n[(i+1)%10]); graph.setEdgeWeight(e[i], 1.0); } + graph.addType(GraphType.DIRECTED); return new CustomGraph(graph); } @@ -49,30 +51,30 @@ public static CustomGraph getTwoCommunitiesGraph() { // Creates nodes Node n[] = new Node[11]; for (int i = 0; i < 11; i++) { - n[i] = graph.createNode(); + n[i] = graph.addNode(Integer.toString(i)); graph.setNodeName(n[i], Integer.toString(i)); } // Creates edges - graph.createEdge(n[0], n[1]); - graph.createEdge(n[0], n[2]); - graph.createEdge(n[0], n[3]); - graph.createEdge(n[0], n[4]); - graph.createEdge(n[0], n[10]); - graph.createEdge(n[5], n[6]); - graph.createEdge(n[5], n[7]); - graph.createEdge(n[5], n[8]); - graph.createEdge(n[5], n[9]); - graph.createEdge(n[5], n[10]); - graph.createEdge(n[1], n[0]); - graph.createEdge(n[2], n[0]); - graph.createEdge(n[3], n[0]); - graph.createEdge(n[4], n[0]); - graph.createEdge(n[10], n[0]); - graph.createEdge(n[6], n[5]); - graph.createEdge(n[7], n[5]); - graph.createEdge(n[8], n[5]); - graph.createEdge(n[9], n[5]); - graph.createEdge(n[10], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[1]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[2]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[3]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[4]); + graph.addEdge(UUID.randomUUID().toString(), n[0], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[6]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[7]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[8]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[9]); + graph.addEdge(UUID.randomUUID().toString(), n[5], n[10]); + graph.addEdge(UUID.randomUUID().toString(), n[1], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[2], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[3], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[4], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[0]); + graph.addEdge(UUID.randomUUID().toString(), n[6], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[7], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[8], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[9], n[5]); + graph.addEdge(UUID.randomUUID().toString(), n[10], n[5]); return new CustomGraph(graph); } diff --git a/yFiles/README-yFiles.txt b/yFiles/README-yFiles.txt deleted file mode 100644 index 718c3d04..00000000 --- a/yFiles/README-yFiles.txt +++ /dev/null @@ -1 +0,0 @@ -Add your yfiles.jar and your ysvg.jar into this folder so that they can be considered for the build \ No newline at end of file