diff --git a/docs/publications-api.md b/docs/publications-api.md new file mode 100644 index 0000000000..16060bd38f --- /dev/null +++ b/docs/publications-api.md @@ -0,0 +1,104 @@ +# Publications and Model Curation + +## Overview + +Publications in VCell link scientific papers to the computational models (BioModels and MathModels) that were used or described in those papers. The publication system also drives the **curation workflow**, which controls model visibility and permanence. + +## Domain Concepts + +### Publication + +A publication record represents a scientific paper and its metadata: + +- **title**, **authors**, **year**, **citation** - bibliographic information +- **pubmedid**, **doi**, **url** - external identifiers and links +- **biomodelRefs** - array of BioModel references linked to this publication +- **mathmodelRefs** - array of MathModel references linked to this publication + +Publications are managed by curators (users with the `publicationEditors` special claim). + +### Model References (BiomodelRef / MathmodelRef) + +Model references are lightweight pointers to BioModels or MathModels that are associated with a publication. Each reference includes: + +- **key** (`bmKey` / `mmKey`) - the model's database identifier +- **name** - model name +- **ownerName** / **ownerKey** - the model owner +- **versionFlag** - the model's curation status (see below) + +### VersionFlag (Curation Status) + +`VersionFlag` represents a model's position in the curation lifecycle. It is **not** access control - that is handled separately by `GroupAccess`. + +| State | Int Value | Description | +|-------|-----------|-------------| +| **Current** | 0 | Default state. Model is in active development. Can be modified or deleted. | +| **Archived** | 1 | Model has been archived. Cannot be deleted without admin intervention. | +| **Published** | 3 | Model has been curated and published. Cannot be deleted without admin intervention. | + +**Key constraint**: Archived and Published models cannot be deleted through the normal API. This ensures the permanence of curated scientific models. + +### GroupAccess (Access Control) + +`GroupAccess` controls who can view a model. It is independent of `VersionFlag`. + +| Type | GroupID | Description | +|------|---------|-------------| +| **GroupAccessAll** | 0 | Public - visible to everyone | +| **GroupAccessNone** | 1 | Private - visible only to the owner | +| **GroupAccessSome** | (hash) | Shared with a specific group of users | + +## Curation Workflow + +When a curator publishes models linked to a publication, two things happen atomically for each model: + +1. **Access is set to public**: `GroupAccess` is changed to `GroupAccessAll` (groupid = 0) +2. **Status is set to published**: `VersionFlag` is changed to `Published` (value = 3) + +This is performed by `PublicationService.publishDirectly()`, which delegates to `DbDriver.publishDirectly()` to update the `vc_biomodel` and `vc_mathmodel` database tables. + +### Selective Publishing + +Curators can publish all models linked to a publication at once, or selectively choose which models to publish by providing specific model keys in the `PublishModelsRequest`. + +## REST API + +Base path: `/api/v1/publications` + +| Method | Path | Operation | Auth | Description | +|--------|------|-----------|------|-------------| +| GET | `/` | getPublications | Public | List all publications | +| GET | `/{id}` | getPublicationById | Public | Get a single publication | +| POST | `/` | createPublication | Curator | Create a new publication | +| PUT | `/` | updatePublication | Curator | Update publication metadata and model links | +| DELETE | `/{id}` | deletePublication | Curator | Delete a publication | +| PUT | `/{id}/publish` | publishBioModels | Curator | Publish models linked to a publication | + +### Publish Endpoint + +`PUT /api/v1/publications/{id}/publish` + +Request body (`PublishModelsRequest`, optional): +```json +{ + "biomodelKeys": [12345, 67890], + "mathmodelKeys": [11111] +} +``` + +- If the request body is null or keys arrays are empty, **all** models linked to the publication are published. +- If specific keys are provided, only those models are published. + +## Key Source Files + +| File | Purpose | +|------|---------| +| `handlers/PublicationResource.java` | REST endpoint definitions | +| `services/PublicationService.java` | Business logic for publication CRUD and publishing | +| `models/Publication.java` | Publication REST model | +| `models/BiomodelRef.java` | BioModel reference REST model | +| `models/MathmodelRef.java` | MathModel reference REST model | +| `models/PublishModelsRequest.java` | Request body for selective publishing | +| `vcell-core/.../VersionFlag.java` | Curation status enum | +| `vcell-core/.../GroupAccess.java` | Access control base class | +| `vcell-server/.../DbDriver.java` | Database-level publish logic | diff --git a/docs/publications.md b/docs/publications.md new file mode 100644 index 0000000000..7d181beed3 --- /dev/null +++ b/docs/publications.md @@ -0,0 +1,124 @@ +# VCell Publications and Model Curation + +## What is a Publication in VCell? + +A VCell publication links a scientific paper to the computational models (BioModels and MathModels) that support it. Publications serve two purposes: + +1. **Discovery** - Users can browse publications to find curated, peer-reviewed models relevant to their research. +2. **Curation** - Publications drive the process of reviewing, approving, and permanently preserving models in the VCell database. + +## How Users Find Published Models + +In the VCell desktop client, the **Database** panel (lower left of any document window) organizes public models into three folders: + +- **Published** - Models created by users and linked to a scientific publication. Grouped by publication citation. +- **Curated** - Models created by the VCell team or collaborators to reproduce results described in a publication. +- **Uncurated** - Public models that have not been peer-reviewed or linked to a publication. + +Published and Curated models represent the highest quality tier - they have been reviewed, are permanently preserved, and are linked to their corresponding papers. + +## How to Publish a VCell Model (Author Instructions) + +When your paper is accepted and you want to associate your VCell model with the publication, follow these steps: + +### 1. Make Your Model Public + +Change your model's permissions in the VCell Database: +- Navigate to **File > Permissions...** +- Select **Public** +- Click **OK** + +The model will initially appear in the **Uncurated** public models folder. You can also share with specific users by selecting **Grant Access to Specific Users** and adding their VCell usernames. + +### 2. Reference VCell in Your Publication + +Include your username and model name so readers can find your model: + +> "The Virtual Cell Model, *[modelname]* by user *[username]*, can be accessed within the VCell software (available at https://vcell.org)." + +### 3. Acknowledge the Funding Source + +Include this acknowledgment in your manuscript: + +> "The Virtual Cell is supported by NIH Grant R24 GM137787 from the National Institute for General Medical Sciences." + +### 4. Cite the Required VCell Papers + +All publications using VCell must cite: +- Schaff, J., C. C. Fink, B. Slepchenko, J. H. Carson, and L. M. Loew. 1997. A general computational framework for modeling cellular structure and function. Biophysical journal 73:1135-1146. PMC1181013 PMID: 9284281 DOI: 10.1016/S0006-3495(97)78146-3 +- Cowan, A. E., Moraru, II, J. C. Schaff, B. M. Slepchenko, and L. M. Loew. 2012. Spatial modeling of cell signaling networks. Methods Cell Biol 110:195-221. PMC3519356 PMID: 22482950 DOI: 10.1016/B978-0-12-388403-9.00008-4 + +Additional citations for specialized model types: +- **Rule-Based models**: + - Blinov, M. L., J. C. Schaff, D. Vasilescu, Moraru, II, J. E. Bloom, and L. M. Loew. 2017. Compartmental and Spatial Rule-Based Modeling with Virtual Cell. Biophysical journal 113:1365-1372. PMC5627391 PMID: 28978431 DOI: 10.1016/j.bpj.2017.08.022 +- **Spatial Hybrid Deterministic-Stochastic models**: + - Schaff, J. C., F. Gao, Y. Li, I. L. Novak, and B. M. Slepchenko. 2016. Numerical Approach to Spatial Deterministic-Stochastic Models Arising in Cell Biology. PLoS Comput Biol 12:e1005236. PMC5154471 PMID: 27959915 DOI: 10.1371/journal.pcbi.1005236 + +### 5. Submit Your Publication Information + +Complete the [VCell Publication Submission Form](https://vcell.org/publish-a-vcell-model) with: +- Your name, email, and VCell username +- Article title, authors, and journal citation +- Publication date +- Model type (BioModel or MathModel) and model name + +Upon approval by the VCell team, your model will be archived, listed on the VCell website, and protected from modification or deletion. + +### Archiving Without Publishing (Deprecated) + +Previously, authors could archive models independently through the VCell desktop client by right-clicking a model in the Database panel and selecting **Archive**. Archiving protected a model from deletion or alteration but did not link it to a publication. This option was removed because it caused confusion among users about the distinction between archiving and publishing. + +## Model Lifecycle + +Every model in VCell has a **curation status** (`VersionFlag`) that tracks where it is in the curation lifecycle: + +``` + Current (0) --> Archived (1) --> Published (3) + (default) (protected) (protected + public) +``` + +| Status | Who can see it | Can it be deleted? | Typical meaning | +|--------|---------------|-------------------|-----------------| +| **Current** | Depends on access settings | Yes | Work in progress or uncurated model | +| **Archived** | Depends on access settings | No (admin only) | Preserved for reference, may or may not be linked to a publication | +| **Published** | Everyone (public) | No (admin only) | Curated, peer-reviewed, linked to a publication | + +Curation status is independent from access control. A model can be publicly visible but still in "Current" status (not yet curated), or it could be archived but only visible to certain users. + +## Access Control (GroupAccess) + +Access control determines who can view a model. It is a separate concept from curation status. + +| Level | Description | +|-------|-------------| +| **Private** | Only the model owner can see it (default) | +| **Shared** | The owner and specific named users can see it | +| **Public** | Everyone can see it | + +When a model is published through the curation workflow, its access is automatically set to Public. However, a model author can independently make their model public at any time without it being "published" in the curation sense. + +## Curator Workflow + +Curators are VCell team members with the `publicationEditors` role. Curation is performed through the Angular webapp at [vcell.cam.uchc.edu](https://vcell.cam.uchc.edu). Curators are responsible for: + +- Creating and editing publication records (title, authors, DOI, PubMed ID, etc.) +- Linking the correct model versions to each publication +- Reviewing models for correctness and completeness +- **Publishing** models - the act that makes them permanently public and protected from deletion + +### What Happens When a Curator Publishes Models + +When a curator clicks "Publish Selected Models" in the webapp (or calls the publish API), two things happen atomically for each selected model: + +1. **Access becomes public** - The model's access control is set to `GroupAccessAll`, making it visible to all VCell users. +2. **Status becomes Published** - The model's `VersionFlag` is set to `Published`, protecting it from deletion. + +This is an intentionally irreversible operation through normal means. Published models are part of the scientific record and should not be casually removed. + +### Selective Publishing + +Curators can choose to publish all models linked to a publication at once, or selectively publish individual models. This is useful when a publication links to multiple models but only some are ready for curation. + +## For Developers + +See [publications-api.md](publications-api.md) for the REST API reference, data models, and source file locations. diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar new file mode 100644 index 0000000000..056ecd3a74 Binary files /dev/null and b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar differ diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.md5 b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.md5 new file mode 100644 index 0000000000..ae74507354 --- /dev/null +++ b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.md5 @@ -0,0 +1 @@ +1b0f328c9eda0992167ce503b0a5afcc diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.sha1 b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.sha1 new file mode 100644 index 0000000000..7768b1fac6 --- /dev/null +++ b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.jar.sha1 @@ -0,0 +1 @@ +34a67ba62097778e4695c951156bf189c2c8e016 diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom new file mode 100644 index 0000000000..d90dcd175a --- /dev/null +++ b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + com.sun.media + jai-codec + 1.1.3 + diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.md5 b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.md5 new file mode 100644 index 0000000000..d076dcda46 --- /dev/null +++ b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.md5 @@ -0,0 +1 @@ +0b104bf9f7e078b213bfb969621875fc diff --git a/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.sha1 b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.sha1 new file mode 100644 index 0000000000..b2325db1b3 --- /dev/null +++ b/lib/maven-repo/com/sun/media/jai-codec/1.1.3/jai-codec-1.1.3.pom.sha1 @@ -0,0 +1 @@ +ba3dbcbaed61466418f7a3b65d956c63249fc1d7 diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar new file mode 100644 index 0000000000..f46fcd3682 Binary files /dev/null and b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar differ diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.md5 b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.md5 new file mode 100644 index 0000000000..130ce76deb --- /dev/null +++ b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.md5 @@ -0,0 +1 @@ +0b57289af4bd2627b6d8c923ba29c114 diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.sha1 b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.sha1 new file mode 100644 index 0000000000..eaf51a0672 --- /dev/null +++ b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.jar.sha1 @@ -0,0 +1 @@ +a9b0be3ddf020c3aebf6498fcfc3ef007805cec0 diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom new file mode 100644 index 0000000000..75a5b2e257 --- /dev/null +++ b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom @@ -0,0 +1,208 @@ + + + 4.0.0 + + + edu.ucar + thredds-parent + 4.3.22 + + + + + netcdf + jar + NetCDF-Java Library + + The NetCDF-Java Library is a Java interface to NetCDF files, + as well as to many other types of scientific data formats. + + http://www.unidata.ucar.edu/software/netcdf-java/documentation.htm + + + + + edu.ucar + udunits + + + + + commons-httpclient + commons-httpclient + + + + org.slf4j + jcl-over-slf4j + + + + + joda-time + joda-time + + + + + org.slf4j + slf4j-api + + + + + org.jdom + jdom2 + + + + + net.jcip + jcip-annotations + + + + + com.sun.jna + jna + + + + + org.quartz-scheduler + quartz + + + + + com.google.protobuf + protobuf-java + + + + + net.sf.ehcache + ehcache-core + + + + + je + com.sleepycat + + + + org.slf4j + slf4j-jdk14 + test + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + ucar/nc2/dataset/grid/** + + ucar/nc2/util/reflect/** + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${skipTests} + true + -Dfile.encoding=UTF-8 + + + + + org.apache.maven.plugins + maven-jar-plugin + + true + + + + jar-test-classes + package + + test-jar + + + + ucar/unidata/test/** + ucar/nc2/util/** + ucar/nc2/TestLocal.* + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.1.1 + + + bundle-sources + package + + + jar-no-fork + + + + + + + + + + src/main/resources + + resources/nj22/** + resources/thredds/** + resources/wmo/** + + + + + + + src/test/resources + + + + + + + diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.md5 b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.md5 new file mode 100644 index 0000000000..e0435e2401 --- /dev/null +++ b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.md5 @@ -0,0 +1 @@ +c2bbe0215d6c6603b916b6a23f242306 diff --git a/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.sha1 b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.sha1 new file mode 100644 index 0000000000..5df1143fca --- /dev/null +++ b/lib/maven-repo/edu/ucar/netcdf/4.3.22/netcdf-4.3.22.pom.sha1 @@ -0,0 +1 @@ +5f9ad1f136eba7d64cd5cb8327d34b708ab00674 diff --git a/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom new file mode 100644 index 0000000000..fa6fa276f5 --- /dev/null +++ b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom @@ -0,0 +1,915 @@ + + + + 4.0.0 + + + + + edu.ucar + thredds-parent + pom + 4.3.22 + Parent THREDDS and CDM modules + + The Unidata THREDDS project includes the netCDF-Java library (aka CDM) and + the THREDDS Data Server (TDS). + + http://www.unidata.ucar.edu/software/netcdf-java/ + + + UCAR/Unidata + http://www.unidata.ucar.edu/ + + 1999 + + + + (MIT-style) netCDF C library license + http://www.unidata.ucar.edu/software/netcdf/copyright.html + repo + + + + + + netcdf-java + http://www.unidata.ucar.edu/support/mailinglist/mailing-list-form.html + netcdf-java@unidata.ucar.edu + + + + + https://github.com/Unidata/thredds/ + scm:git:https://github.com/Unidata/thredds/ + scm:git:git@github.com:Unidata/thredds.git + v4.3.22 + + + + + + caron + John Caron + caron@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + chastang + Julien Chastang + chastang@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + edavis + Ethan Davis + edavis@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + dmh + Dennis Heimbigner + dmh@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + emmerson + Steve Emmerson + steve@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + oxelson + Jennifer Ganter Oxelson + oxelson@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + mhermida + Marcos Hermida + mhermida@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + rkambic + Robb Kambic + rkambic@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + russ + Russel Rew + russ@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + C Developer + + + + yuanho + Ho Yuan + yuanho@unidata.ucar.edu + UCAR/UNIDATA + http://www.unidata.ucar.edu/ + + Java Developer + + + + + + + + integration-test + + it + + + + + tomcat-debug + + + org.apache.tomcat + tomcat-catalina + ${org.apache.tomcat.version} + provided + + + org.apache.tomcat + tomcat-jasper + ${org.apache.tomcat.version} + provided + + + + + + + + unidata-releases + UNIDATA Releases + https://artifacts.unidata.ucar.edu/content/repositories/unidata-releases/ + + + unidata-snapshots + UNIDATA Snapshots + https://artifacts.unidata.ucar.edu/content/repositories/unidata-snapshots/ + + + + + + unidata + THREDDS + https://artifacts.unidata.ucar.edu/content/repositories/unidata/ + + + unidata-3rdparty + https://artifacts.unidata.ucar.edu/content/repositories/unidata-3rdparty/ + + + + + + + + + + + ${project.groupId} + bufr + ${project.version} + + + ${project.groupId} + grib + ${project.version} + + + ${project.groupId} + opendap + ${project.version} + + + javax.servlet + servlet-api + + + + + ${project.groupId} + netcdf + ${project.version} + + + ${project.groupId} + tdcommon + ${project.version} + + + ${project.groupId} + udunits + ${project.version} + + + + ${project.groupId} + visadCdm + ${project.version} + + + edu.wisc.ssec + visad + + + + + + + log4j + log4j + ${log4j.version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + runtime + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + org.slf4j + slf4j-jdk14 + ${org.slf4j.version} + runtime + + + org.slf4j + slf4j-log4j12 + ${org.slf4j.version} + runtime + + + + + org.springframework + spring-core + ${org.springframework.version} + + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework + spring-beans + ${org.springframework.version} + + + org.springframework + spring-webmvc + ${org.springframework.version} + + + org.springframework + spring-test + ${org.springframework.version} + + + + + org.springframework.security + spring-security-config + ${org.springframework.security.version} + + + org.springframework.security + spring-security-core + ${org.springframework.security.version} + + + org.springframework.security + spring-security-taglibs + ${org.springframework.security.version} + + + org.springframework.security + spring-security-web + ${org.springframework.security.version} + + + + + org.springframework + spring-jdbc + ${org.springframework.version} + + + commons-dbcp + commons-dbcp + ${commons-dbcp.version} + + + taglibs + standard + ${taglibs.version} + + + org.apache.derby + derby + ${derby.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + javax.activation + activation + ${javax.activation.version} + + + cglib + cglib-nodep + ${cglib.version} + + + org.hibernate + hibernate-validator + ${org.hibernate.version} + + + + + commons-httpclient + commons-httpclient + ${commons-httpclient.version} + + + commons-logging + commons-logging + + + + + net.sf.ehcache + ehcache-core + ${net.sf.ehcache.version} + + + net.jcip + jcip-annotations + ${net.jcip.version} + + + org.jdom + jdom2 + ${org.jdom2.version} + + + org.jdom + jdom-legacy + ${org.jdom-legacy.version} + + + com.sleepycat + je + ${com.sleepycat.version} + + + com.sun.jna + jna + 3.0.9 + + + joda-time + joda-time + ${joda-time.version} + + + + org.jsoup + jsoup + ${org.jsoup.version} + + + junit + junit + ${junit.version} + test + + + com.google.protobuf + protobuf-java + ${com.google.protobuf.version} + + + org.quartz-scheduler + quartz + ${org.quartz-scheduler.version} + + + edu.wisc.ssec + visad + ${visad.version} + + + + com.lexicalscope.jewelcli + jewelcli + 0.8.5 + + + + + org.jfree + jcommon + ${org.jfree.jcommon.version} + + + org.jfree + jfreechart + ${org.jfree.jfreechart.version} + + + com.lowagie + itext + + + + + + com.jgoodies + jgoodies-forms + ${com.jgoodies.version} + + + + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + + + commons-io + commons-io + ${commons-io.version} + + + cas + casclient + ${cas.version} + + + + commons-logging + commons-logging + + + + + oro + oro + ${oro.version} + + + uk.ac.rdg.resc + ncwms + ${uk.ac.rdg.resc.version} + + + org.slf4j + slf4j-jdk14 + + + org.jfree + jcommon + + + org.jfree + jfreechart + + + + + org.geotoolkit + geotk-referencing + ${org.geotoolkit.version} + + + + + javax.servlet + servlet-api + ${javax.servlet.version} + provided + + + javax.servlet + jstl + ${javax.servlet.jstl.version} + runtime + + + + json-taglib + json-taglib + ${atg.taglib.json.version} + runtime + + + + jaxen + jaxen + ${jaxen.version} + runtime + + + maven-cobertura-plugin + maven-plugins + + + maven-findbugs-plugin + maven-plugins + + + + + + + EDS + threddsIso + ${eds.threddsIso.version} + runtime + + + + javax.servlet + javax.servlet-api + + + net.sf.saxon + saxon + + + + + + + net.sf.saxon + saxon + ${saxon.version} + + + net.sf.saxon + saxon-dom + ${saxon.version} + + + + + + + + ${project.groupId} + tds + ${project.version} + war + + + + + + ${project.groupId} + tds + ${project.version} + classes + jar + + + + + + ${project.groupId} + wmotables + ${project.version} + war + + + + ${project.groupId} + cdmvalidator + ${project.version} + war + + + + ${project.groupId} + dts + ${project.version} + war + + + + + ${project.groupId} + netcdf + test + test-jar + ${project.version} + + + + + + + + + junit + junit + test + + + + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven-assembly-plugin.version} + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.6 + 1.6 + + + + + default-testCompile + test-compile + + testCompile + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + true + + + true + true + + + ${maven.build.timestamp} + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + http://docs.oracle.com/javase/6/docs/api/ + + false + true + 1024m + 512m + + + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + v@{project.version} + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven-shade-plugin.version} + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + + + + + + + + + + + + udunits + cdm + bufr + grib + opendap + dts + visad + ncIdv + ui + tdcommon + tds + tdm + wmotables + cdmvalidator + cdm-test + it + + + + + true + + + UTF-8 + UTF-8 + + + yyyyMMdd.HHmm + ${maven.build.timestamp} + + + + 2.0-20130124 + + 2011-08-22 + + + 1.0.tds.4.3.20130918.0800 + + 3.21 + 2.2.2 + + 0.4.1 + 2.1.1 + 2.2 + 2.5.0 + 1.6.0 + 4.0.92 + 1.4 + 1.2.2 + 3.1 + 2.4 + 10.9.1.0 + 1.1.1 + 2.5 + 1.2 + 1.1.4 + 1.0.17 + 1.0.14 + 2.2 + 4.11 + 1.2.17 + 1.0 + 2.6.2 + 7.0.53 + 4.3.1.Final + 1.7.2 + 2.0.4 + 1.1.3 + 2.1.1 + 1.7.5 + 3.2.2.RELEASE + 3.1.3.RELEASE + 2.0.8 + 1.1.2 + 8.7 + + 1.7 + 2.4 + 3.1 + 2.7 + 2.9.1 + 2.4 + 2.4.1 + 2.1 + 2.16 + 2.4 + + + diff --git a/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.md5 b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.md5 new file mode 100644 index 0000000000..19c0e187b4 --- /dev/null +++ b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.md5 @@ -0,0 +1 @@ +bbe4a677d5dc5e9dcad7daaf98e25ad7 diff --git a/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.sha1 b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.sha1 new file mode 100644 index 0000000000..af21fc622d --- /dev/null +++ b/lib/maven-repo/edu/ucar/thredds-parent/4.3.22/thredds-parent-4.3.22.pom.sha1 @@ -0,0 +1 @@ +35d836b0c261705105473131098ae155e7fe7cc2 diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar new file mode 100644 index 0000000000..3f184d8a18 Binary files /dev/null and b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar differ diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.md5 b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.md5 new file mode 100644 index 0000000000..7a998bdb70 --- /dev/null +++ b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.md5 @@ -0,0 +1 @@ +fb8d4bcebeaece97f95e68e47bdbae0e diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.sha1 b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.sha1 new file mode 100644 index 0000000000..b03b2635b7 --- /dev/null +++ b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.jar.sha1 @@ -0,0 +1 @@ +ea8cad39471fa48e181abdd4f0eae6175098bc58 diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom new file mode 100644 index 0000000000..86bf51a83e --- /dev/null +++ b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom @@ -0,0 +1,80 @@ + + + 4.0.0 + + + edu.ucar + thredds-parent + 4.3.22 + + + udunits + jar + udunits + 4.3.22 + http://www.unidata.ucar.edu/software/udunits// + + The ucar.units Java package is for decoding and encoding + formatted unit specifications (e.g. "m/s"), converting numeric values + between compatible units (e.g. between "m/s" and "knot"), and for + performing arithmetic operations on units (e.g. dividing one unit by + another, raising a unit to a power). + + + + UTF-8 + UTF-8 + + + + + emmerson + Steve Emmerson + http://www.unidata.ucar.edu/staff/steve/ + + + + + + + + + + maven-javadoc-plugin + 2.7 + + 1024m + + false + + + + + + diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.md5 b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.md5 new file mode 100644 index 0000000000..7a031e63c8 --- /dev/null +++ b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.md5 @@ -0,0 +1 @@ +6d42423bb248501303a16999f0bb6262 diff --git a/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.sha1 b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.sha1 new file mode 100644 index 0000000000..c2bf24d74b --- /dev/null +++ b/lib/maven-repo/edu/ucar/udunits/4.3.22/udunits-4.3.22.pom.sha1 @@ -0,0 +1 @@ +d2946e6b9d2ab982d7d96b24f851ec1ed3988ff6 diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar new file mode 100644 index 0000000000..b29b8eed5b Binary files /dev/null and b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar differ diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.md5 b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.md5 new file mode 100644 index 0000000000..b2e491c083 --- /dev/null +++ b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.md5 @@ -0,0 +1 @@ +f398bc038307ee434bac1b93ba3ab02d diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.sha1 b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.sha1 new file mode 100644 index 0000000000..24a038217c --- /dev/null +++ b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.jar.sha1 @@ -0,0 +1 @@ +b179d2efb1174658483e8b41bf4ac9d2eb5de438 diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom new file mode 100644 index 0000000000..662f05a45f --- /dev/null +++ b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom @@ -0,0 +1,23 @@ + + + 4.0.0 + javax.media + jai_core + 1.1.3 + jar + Java Advanced Imaging + https://jai.dev.java.net/ + The Java Advanced Imaging API extends the Java 2 platform by allowing sophisticated, high-performance image processing to be incorporated into Java applets and applications. It is a set of classes providing imaging functionality beyond that of Java 2D and the Java Foundation classes, though it is designed for compatibility with those APIs. This API implements a set of core image processing capabilities including image tiling, regions of interest, deferred execution and a set of core image processing operators, including many common point, area, and frequency domain operators. + + + JDL (Java Distribution License) + https://jai.dev.java.net/jdl-jai.pdf + manual + + + + + https://jai.dev.java.net/binary-builds.html + + + diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.md5 b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.md5 new file mode 100644 index 0000000000..dedcca4f20 --- /dev/null +++ b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.md5 @@ -0,0 +1 @@ +bb7379e3dfe1988d2e68c636a730ad5f diff --git a/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.sha1 b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.sha1 new file mode 100644 index 0000000000..3a688a5b7c --- /dev/null +++ b/lib/maven-repo/javax/media/jai_core/1.1.3/jai_core-1.1.3.pom.sha1 @@ -0,0 +1 @@ +cf229622768058141f62852d774da792b25f3fe2 diff --git a/pom.xml b/pom.xml index b24eda3ef5..20a87a9c62 100644 --- a/pom.xml +++ b/pom.xml @@ -199,10 +199,16 @@ - + - osgeo - https://repo.osgeo.org/repository/release/ + lib-maven-repo + file://${maven.multiModuleProjectDirectory}/lib/maven-repo + + true + + + false + diff --git a/python-restclient/.openapi-generator/FILES b/python-restclient/.openapi-generator/FILES index bd03d3b283..3f9b5211aa 100644 --- a/python-restclient/.openapi-generator/FILES +++ b/python-restclient/.openapi-generator/FILES @@ -58,6 +58,7 @@ docs/Origin.md docs/Publication.md docs/PublicationInfo.md docs/PublicationResourceApi.md +docs/PublishModelsRequest.md docs/SPECIALCLAIM.md docs/SampledCurve.md docs/SchedulerStatus.md @@ -168,6 +169,7 @@ vcell_client/models/n5_export_request.py vcell_client/models/origin.py vcell_client/models/publication.py vcell_client/models/publication_info.py +vcell_client/models/publish_models_request.py vcell_client/models/sampled_curve.py vcell_client/models/scheduler_status.py vcell_client/models/simulation_execution_status_record.py diff --git a/python-restclient/README.md b/python-restclient/README.md index 9f03577c84..a7449b2810 100644 --- a/python-restclient/README.md +++ b/python-restclient/README.md @@ -122,6 +122,7 @@ Class | Method | HTTP request | Description *PublicationResourceApi* | [**delete_publication**](docs/PublicationResourceApi.md#delete_publication) | **DELETE** /api/v1/publications/{id} | Delete publication *PublicationResourceApi* | [**get_publication_by_id**](docs/PublicationResourceApi.md#get_publication_by_id) | **GET** /api/v1/publications/{id} | Get publication by ID *PublicationResourceApi* | [**get_publications**](docs/PublicationResourceApi.md#get_publications) | **GET** /api/v1/publications | Get all publications +*PublicationResourceApi* | [**publish_bio_models**](docs/PublicationResourceApi.md#publish_bio_models) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication *PublicationResourceApi* | [**update_publication**](docs/PublicationResourceApi.md#update_publication) | **PUT** /api/v1/publications | Update publication *SimulationResourceApi* | [**get_simulation_status**](docs/SimulationResourceApi.md#get_simulation_status) | **GET** /api/v1/Simulation/{simID}/simulationStatus | Get the status of simulation running *SimulationResourceApi* | [**start_simulation**](docs/SimulationResourceApi.md#start_simulation) | **POST** /api/v1/Simulation/{simID}/startSimulation | Start a simulation. @@ -196,6 +197,7 @@ Class | Method | HTTP request | Description - [Origin](docs/Origin.md) - [Publication](docs/Publication.md) - [PublicationInfo](docs/PublicationInfo.md) + - [PublishModelsRequest](docs/PublishModelsRequest.md) - [SPECIALCLAIM](docs/SPECIALCLAIM.md) - [SampledCurve](docs/SampledCurve.md) - [SchedulerStatus](docs/SchedulerStatus.md) diff --git a/python-restclient/docs/BioModel.md b/python-restclient/docs/BioModel.md index 9a117841c3..f23c613372 100644 --- a/python-restclient/docs/BioModel.md +++ b/python-restclient/docs/BioModel.md @@ -7,6 +7,7 @@ Name | Type | Description | Notes **bm_key** | **str** | | [optional] **name** | **str** | | [optional] **privacy** | **int** | | [optional] +**version_flag** | **int** | | [optional] **group_users** | **List[str]** | | [optional] **saved_date** | **int** | | [optional] **annot** | **str** | | [optional] diff --git a/python-restclient/docs/BiomodelRef.md b/python-restclient/docs/BiomodelRef.md index f7e4607b5e..c34d341ddd 100644 --- a/python-restclient/docs/BiomodelRef.md +++ b/python-restclient/docs/BiomodelRef.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **owner_name** | **str** | | [optional] **owner_key** | **int** | | [optional] **version_flag** | **int** | | [optional] +**privacy** | **int** | | [optional] ## Example diff --git a/python-restclient/docs/PublicationResourceApi.md b/python-restclient/docs/PublicationResourceApi.md index 4c11e01cc4..0f7e600a00 100644 --- a/python-restclient/docs/PublicationResourceApi.md +++ b/python-restclient/docs/PublicationResourceApi.md @@ -8,6 +8,7 @@ Method | HTTP request | Description [**delete_publication**](PublicationResourceApi.md#delete_publication) | **DELETE** /api/v1/publications/{id} | Delete publication [**get_publication_by_id**](PublicationResourceApi.md#get_publication_by_id) | **GET** /api/v1/publications/{id} | Get publication by ID [**get_publications**](PublicationResourceApi.md#get_publications) | **GET** /api/v1/publications | Get all publications +[**publish_bio_models**](PublicationResourceApi.md#publish_bio_models) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication [**update_publication**](PublicationResourceApi.md#update_publication) | **PUT** /api/v1/publications | Update publication @@ -281,6 +282,79 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **publish_bio_models** +> publish_bio_models(id, publish_models_request=publish_models_request) + +Publish selected BioModels and MathModels associated with a publication + +### Example + +```python +import time +import os +import vcell_client +from vcell_client.models.publish_models_request import PublishModelsRequest +from vcell_client.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://vcell.cam.uchc.edu +# See configuration.py for a list of all supported configuration parameters. +configuration = vcell_client.Configuration( + host = "https://vcell.cam.uchc.edu" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Enter a context with an instance of the API client +with vcell_client.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = vcell_client.PublicationResourceApi(api_client) + id = 56 # int | + publish_models_request = vcell_client.PublishModelsRequest() # PublishModelsRequest | (optional) + + try: + # Publish selected BioModels and MathModels associated with a publication + api_instance.publish_bio_models(id, publish_models_request=publish_models_request) + except Exception as e: + print("Exception when calling PublicationResourceApi->publish_bio_models: %s\n" % e) +``` + + + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **id** | **int**| | + **publish_models_request** | [**PublishModelsRequest**](PublishModelsRequest.md)| | [optional] + +### Return type + +void (empty response body) + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**204** | No Content | - | +**401** | Not Authenticated | - | +**403** | Not Allowed | - | +**404** | Not found | - | +**500** | Data Access Exception | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **update_publication** > Publication update_publication(publication=publication) diff --git a/python-restclient/docs/PublishModelsRequest.md b/python-restclient/docs/PublishModelsRequest.md new file mode 100644 index 0000000000..25eba52760 --- /dev/null +++ b/python-restclient/docs/PublishModelsRequest.md @@ -0,0 +1,29 @@ +# PublishModelsRequest + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**biomodel_keys** | **List[int]** | | [optional] +**mathmodel_keys** | **List[int]** | | [optional] + +## Example + +```python +from vcell_client.models.publish_models_request import PublishModelsRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of PublishModelsRequest from a JSON string +publish_models_request_instance = PublishModelsRequest.from_json(json) +# print the JSON string representation of the object +print PublishModelsRequest.to_json() + +# convert the object into a dict +publish_models_request_dict = publish_models_request_instance.to_dict() +# create an instance of PublishModelsRequest from a dict +publish_models_request_form_dict = publish_models_request.from_dict(publish_models_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/python-restclient/test/test_publish_models_request.py b/python-restclient/test/test_publish_models_request.py new file mode 100644 index 0000000000..bf3971aeba --- /dev/null +++ b/python-restclient/test/test_publish_models_request.py @@ -0,0 +1,58 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest +import datetime + +from vcell_client.models.publish_models_request import PublishModelsRequest + +class TestPublishModelsRequest(unittest.TestCase): + """PublishModelsRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> PublishModelsRequest: + """Test PublishModelsRequest + include_option is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `PublishModelsRequest` + """ + model = PublishModelsRequest() + if include_optional: + return PublishModelsRequest( + biomodel_keys = [ + 56 + ], + mathmodel_keys = [ + 56 + ] + ) + else: + return PublishModelsRequest( + ) + """ + + def testPublishModelsRequest(self): + """Test PublishModelsRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/python-restclient/vcell_client/__init__.py b/python-restclient/vcell_client/__init__.py index 8ad5416366..97b6e5257a 100644 --- a/python-restclient/vcell_client/__init__.py +++ b/python-restclient/vcell_client/__init__.py @@ -92,6 +92,7 @@ from vcell_client.models.origin import Origin from vcell_client.models.publication import Publication from vcell_client.models.publication_info import PublicationInfo +from vcell_client.models.publish_models_request import PublishModelsRequest from vcell_client.models.specialclaim import SPECIALCLAIM from vcell_client.models.sampled_curve import SampledCurve from vcell_client.models.scheduler_status import SchedulerStatus diff --git a/python-restclient/vcell_client/api/publication_resource_api.py b/python-restclient/vcell_client/api/publication_resource_api.py index f843d91b9c..a9b29835ef 100644 --- a/python-restclient/vcell_client/api/publication_resource_api.py +++ b/python-restclient/vcell_client/api/publication_resource_api.py @@ -29,6 +29,7 @@ from typing import List, Optional from vcell_client.models.publication import Publication +from vcell_client.models.publish_models_request import PublishModelsRequest from vcell_client.api_client import ApiClient from vcell_client.api_response import ApiResponse @@ -1092,6 +1093,290 @@ def _get_publications_serialize( + @validate_call + def publish_bio_models( + self, + id: StrictInt, + publish_models_request: Optional[PublishModelsRequest] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Publish selected BioModels and MathModels associated with a publication + + + :param id: (required) + :type id: int + :param publish_models_request: + :type publish_models_request: PublishModelsRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._publish_bio_models_serialize( + id=id, + publish_models_request=publish_models_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def publish_bio_models_with_http_info( + self, + id: StrictInt, + publish_models_request: Optional[PublishModelsRequest] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Publish selected BioModels and MathModels associated with a publication + + + :param id: (required) + :type id: int + :param publish_models_request: + :type publish_models_request: PublishModelsRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._publish_bio_models_serialize( + id=id, + publish_models_request=publish_models_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def publish_bio_models_without_preload_content( + self, + id: StrictInt, + publish_models_request: Optional[PublishModelsRequest] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Publish selected BioModels and MathModels associated with a publication + + + :param id: (required) + :type id: int + :param publish_models_request: + :type publish_models_request: PublishModelsRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._publish_bio_models_serialize( + id=id, + publish_models_request=publish_models_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _publish_bio_models_serialize( + self, + id, + publish_models_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> Tuple: + + _host = None + + _collection_formats: Dict[str, str] = { + + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, str] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if id is not None: + _path_params['id'] = id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if publish_models_request is not None: + _body_params = publish_models_request + + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'openId' + ] + + return self.api_client.param_serialize( + method='PUT', + resource_path='/api/v1/publications/{id}/publish', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def update_publication( self, diff --git a/python-restclient/vcell_client/models/__init__.py b/python-restclient/vcell_client/models/__init__.py index 5690747f2e..62754c6b30 100644 --- a/python-restclient/vcell_client/models/__init__.py +++ b/python-restclient/vcell_client/models/__init__.py @@ -61,6 +61,7 @@ from vcell_client.models.origin import Origin from vcell_client.models.publication import Publication from vcell_client.models.publication_info import PublicationInfo +from vcell_client.models.publish_models_request import PublishModelsRequest from vcell_client.models.specialclaim import SPECIALCLAIM from vcell_client.models.sampled_curve import SampledCurve from vcell_client.models.scheduler_status import SchedulerStatus diff --git a/python-restclient/vcell_client/models/bio_model.py b/python-restclient/vcell_client/models/bio_model.py index de3d33c9ff..6cef9ae214 100644 --- a/python-restclient/vcell_client/models/bio_model.py +++ b/python-restclient/vcell_client/models/bio_model.py @@ -34,6 +34,7 @@ class BioModel(BaseModel): bm_key: Optional[StrictStr] = Field(default=None, alias="bmKey") name: Optional[StrictStr] = None privacy: Optional[StrictInt] = None + version_flag: Optional[StrictInt] = Field(default=None, alias="versionFlag") group_users: Optional[List[StrictStr]] = Field(default=None, alias="groupUsers") saved_date: Optional[StrictInt] = Field(default=None, alias="savedDate") annot: Optional[StrictStr] = None @@ -43,7 +44,7 @@ class BioModel(BaseModel): owner_key: Optional[StrictStr] = Field(default=None, alias="ownerKey") simulation_key_list: Optional[List[StrictStr]] = Field(default=None, alias="simulationKeyList") applications: Optional[List[Union[str, Any]]] = None - __properties: ClassVar[List[str]] = ["bmKey", "name", "privacy", "groupUsers", "savedDate", "annot", "branchID", "physModelKey", "ownerName", "ownerKey", "simulationKeyList", "applications"] + __properties: ClassVar[List[str]] = ["bmKey", "name", "privacy", "versionFlag", "groupUsers", "savedDate", "annot", "branchID", "physModelKey", "ownerName", "ownerKey", "simulationKeyList", "applications"] model_config = { "populate_by_name": True, @@ -101,6 +102,7 @@ def from_dict(cls, obj: Dict) -> Self: "bmKey": obj.get("bmKey"), "name": obj.get("name"), "privacy": obj.get("privacy"), + "versionFlag": obj.get("versionFlag"), "groupUsers": obj.get("groupUsers"), "savedDate": obj.get("savedDate"), "annot": obj.get("annot"), diff --git a/python-restclient/vcell_client/models/biomodel_ref.py b/python-restclient/vcell_client/models/biomodel_ref.py index 8c79608270..09f5284c37 100644 --- a/python-restclient/vcell_client/models/biomodel_ref.py +++ b/python-restclient/vcell_client/models/biomodel_ref.py @@ -36,7 +36,8 @@ class BiomodelRef(BaseModel): owner_name: Optional[StrictStr] = Field(default=None, alias="ownerName") owner_key: Optional[StrictInt] = Field(default=None, alias="ownerKey") version_flag: Optional[StrictInt] = Field(default=None, alias="versionFlag") - __properties: ClassVar[List[str]] = ["bmKey", "name", "ownerName", "ownerKey", "versionFlag"] + privacy: Optional[StrictInt] = None + __properties: ClassVar[List[str]] = ["bmKey", "name", "ownerName", "ownerKey", "versionFlag", "privacy"] model_config = { "populate_by_name": True, @@ -95,7 +96,8 @@ def from_dict(cls, obj: Dict) -> Self: "name": obj.get("name"), "ownerName": obj.get("ownerName"), "ownerKey": obj.get("ownerKey"), - "versionFlag": obj.get("versionFlag") + "versionFlag": obj.get("versionFlag"), + "privacy": obj.get("privacy") }) return _obj diff --git a/python-restclient/vcell_client/models/publish_models_request.py b/python-restclient/vcell_client/models/publish_models_request.py new file mode 100644 index 0000000000..cdebe1481e --- /dev/null +++ b/python-restclient/vcell_client/models/publish_models_request.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + VCell API + + VCell API + + The version of the OpenAPI document: 1.0.1 + Contact: vcell_support@uchc.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + + +from typing import Any, ClassVar, Dict, List, Optional +from pydantic import BaseModel, StrictInt +from pydantic import Field +try: + from typing import Self +except ImportError: + from typing_extensions import Self + +class PublishModelsRequest(BaseModel): + """ + PublishModelsRequest + """ # noqa: E501 + biomodel_keys: Optional[List[StrictInt]] = Field(default=None, alias="biomodelKeys") + mathmodel_keys: Optional[List[StrictInt]] = Field(default=None, alias="mathmodelKeys") + __properties: ClassVar[List[str]] = ["biomodelKeys", "mathmodelKeys"] + + model_config = { + "populate_by_name": True, + "validate_assignment": True + } + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of PublishModelsRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + _dict = self.model_dump( + by_alias=True, + exclude={ + }, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Dict) -> Self: + """Create an instance of PublishModelsRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + # raise errors for additional fields in the input + for _key in obj.keys(): + if _key not in cls.__properties: + raise ValueError("Error due to additional fields (not defined in PublishModelsRequest) in the input: " + _key) + + _obj = cls.model_validate({ + "biomodelKeys": obj.get("biomodelKeys"), + "mathmodelKeys": obj.get("mathmodelKeys") + }) + return _obj + + diff --git a/tools/generate.sh b/tools/generate.sh index 80fde3b732..df5ad8ab24 100755 --- a/tools/generate.sh +++ b/tools/generate.sh @@ -38,7 +38,7 @@ ${generatorCliImage} generate \ -o /vcell/python-restclient \ -c /vcell/tools/python-config.yaml -./python-fix.sh +"${scriptDir}/python-fix.sh" docker run --rm -v ${parentDir}:/vcell \ ${generatorCliImage} generate \ diff --git a/tools/openapi.yaml b/tools/openapi.yaml index 0c7df40f21..10dd80a4d2 100644 --- a/tools/openapi.yaml +++ b/tools/openapi.yaml @@ -1704,6 +1704,54 @@ paths: security: - openId: - user + /api/v1/publications/{id}/publish: + put: + tags: + - Publication Resource + summary: Publish selected BioModels and MathModels associated with a publication + operationId: publishBioModels + parameters: + - name: id + in: path + required: true + schema: + format: int64 + type: integer + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PublishModelsRequest' + responses: + "204": + description: No Content + "401": + description: Not Authenticated + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + "403": + description: Not Allowed + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + "404": + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + "500": + description: Data Access Exception + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + security: + - openId: + - user /api/v1/solver/getFVSolverInput: post: tags: @@ -2167,6 +2215,9 @@ components: privacy: format: int32 type: integer + versionFlag: + format: int32 + type: integer groupUsers: type: array items: @@ -2278,6 +2329,9 @@ components: versionFlag: format: int32 type: integer + privacy: + format: int32 + type: integer CompositeCurve: required: - type @@ -3013,6 +3067,19 @@ components: theHashCode: format: int32 type: integer + PublishModelsRequest: + type: object + properties: + biomodelKeys: + type: array + items: + format: int64 + type: integer + mathmodelKeys: + type: array + items: + format: int64 + type: integer SPECIAL_CLAIM: enum: - admins diff --git a/vcell-api/src/main/java/org/vcell/rest/server/PublicationServerResource.java b/vcell-api/src/main/java/org/vcell/rest/server/PublicationServerResource.java index fe2ffd8e6a..a0f597d134 100644 --- a/vcell-api/src/main/java/org/vcell/rest/server/PublicationServerResource.java +++ b/vcell-api/src/main/java/org/vcell/rest/server/PublicationServerResource.java @@ -199,7 +199,7 @@ private Object convertToReferenceRep(String str,Class classType) throws Exceptio if(classType.equals(BioModelReferenceRep.class)) { BioModelReferenceRep[] biomodelReferenceReps = new BioModelReferenceRep[modelKeys.length]; for (int i = 0; i < modelKeys.length; i++) { - biomodelReferenceReps[i] = new BioModelReferenceRep(new KeyValue(modelKeys[i]), null, null,null); + biomodelReferenceReps[i] = new BioModelReferenceRep(new KeyValue(modelKeys[i]), null, null, null, null); } return biomodelReferenceReps; }else if(classType.equals(MathModelReferenceRep.class)) { diff --git a/vcell-api/src/main/java/org/vcell/rest/server/TestRestServerBlinov.java b/vcell-api/src/main/java/org/vcell/rest/server/TestRestServerBlinov.java index d4c0277b5f..9b5586ff16 100644 --- a/vcell-api/src/main/java/org/vcell/rest/server/TestRestServerBlinov.java +++ b/vcell-api/src/main/java/org/vcell/rest/server/TestRestServerBlinov.java @@ -97,9 +97,10 @@ public boolean accept(File pathname) { simulations[j].getName(), simulations[j].getVersion().getOwner(), simulations[j].getMathDescription().getKey(), simulations[j].getSolverTaskDescription(), new MathOverrides.Element[] {}); } - //KeyValue bmKey, String name, int privacy, User[] groupUsers, Date date, String annot, BigDecimal branchID, KeyValue modelRef, User owner, KeyValue[] simKeyList, KeyValue[] simContextKeyList) + //KeyValue bmKey, String name, int privacy, int versionFlag, User[] groupUsers, Date date, String annot, BigDecimal branchID, KeyValue modelRef, User owner, KeyValue[] simKeyList, KeyValue[] simContextKeyList) BioModelRep bmrep = new BioModelRep(bm.getVersion().getVersionKey(), bm.getName(), bm.getVersion().getGroupAccess().getGroupid().intValue(), + bm.getVersion().getFlag().getIntValue(), new User[] {}, bm.getVersion().getDate(), bm.getVersion().getAnnot(), bm.getVersion().getBranchID(), bm.getModel().getVersion().getVersionKey(), bm.getVersion().getOwner(), srepKeys, scrKeys); for(int j=0;j org.apache.maven.plugins maven-compiler-plugin + 3.11.0 16 16 @@ -176,6 +177,7 @@ org.codehaus.mojo exec-maven-plugin + 3.1.0 build-user-help diff --git a/vcell-rest/src/main/java/org/vcell/restq/handlers/PublicationResource.java b/vcell-rest/src/main/java/org/vcell/restq/handlers/PublicationResource.java index 0c74ef71e2..d82260b5c0 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/handlers/PublicationResource.java +++ b/vcell-rest/src/main/java/org/vcell/restq/handlers/PublicationResource.java @@ -12,12 +12,14 @@ import org.vcell.restq.services.UserRestService; import org.vcell.restq.errors.exceptions.*; import org.vcell.restq.models.Publication; +import org.vcell.restq.models.PublishModelsRequest; import org.vcell.util.DataAccessException; import org.vcell.util.PermissionException; import org.vcell.util.document.KeyValue; import org.vcell.util.document.User; import java.sql.SQLException; +import java.util.Arrays; @Path("/api/v1/publications") @Produces(MediaType.APPLICATION_JSON) @@ -106,6 +108,46 @@ public Publication update(Publication publication) throws PermissionWebException } + @PUT + @Path("{id}/publish") + @Consumes(MediaType.APPLICATION_JSON) + @RolesAllowed("user") + @Operation(operationId = "publishBioModels", summary = "Publish selected BioModels and MathModels associated with a publication") + public void publish(@PathParam("id") Long publicationID, PublishModelsRequest request) throws PermissionWebException, NotAuthenticatedWebException, NotFoundWebException, DataAccessWebException { + try { + User vcellUser = userRestService.getUserFromIdentity(securityIdentity); + Publication publication = publicationService.getPublication(new KeyValue(publicationID.toString()), vcellUser); + + KeyValue[] biomodelKeys; + KeyValue[] mathmodelKeys; + + if (request != null && request.biomodelKeys() != null) { + biomodelKeys = Arrays.stream(request.biomodelKeys()).map(k -> new KeyValue(k.toString())).toArray(KeyValue[]::new); + } else if (publication.biomodelRefs() != null) { + biomodelKeys = Arrays.stream(publication.biomodelRefs()).map(r -> new KeyValue(r.bmKey().toString())).toArray(KeyValue[]::new); + } else { + biomodelKeys = new KeyValue[0]; + } + + if (request != null && request.mathmodelKeys() != null) { + mathmodelKeys = Arrays.stream(request.mathmodelKeys()).map(k -> new KeyValue(k.toString())).toArray(KeyValue[]::new); + } else if (publication.mathmodelRefs() != null) { + mathmodelKeys = Arrays.stream(publication.mathmodelRefs()).map(r -> new KeyValue(r.mmKey().toString())).toArray(KeyValue[]::new); + } else { + mathmodelKeys = new KeyValue[0]; + } + + publicationService.publishDirectly(biomodelKeys, mathmodelKeys, vcellUser); + } catch (PermissionException e){ + throw new PermissionWebException(e.getMessage(), e); + } catch (DataAccessException e){ + throw new DataAccessWebException(e.getMessage(), e); + } catch (SQLException e) { + throw new RuntimeWebException("failed to publish models: " + e.getMessage(), e); + } + } + + @DELETE @Path("{id}") // @RolesAllowed("curator") diff --git a/vcell-rest/src/main/java/org/vcell/restq/models/BioModel.java b/vcell-rest/src/main/java/org/vcell/restq/models/BioModel.java index 8502a41073..9d64feea62 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/models/BioModel.java +++ b/vcell-rest/src/main/java/org/vcell/restq/models/BioModel.java @@ -10,6 +10,7 @@ public record BioModel( String bmKey, String name, int privacy, + int versionFlag, String[] groupUsers, Long savedDate, String annot, @@ -27,6 +28,7 @@ public static BioModel fromBioModelRep(cbit.vcell.modeldb.BioModelRep bioModelRe groupList.add(user.getName()); } return new BioModel(bioModelRep.getBmKey().toString(), bioModelRep.getName(), bioModelRep.getPrivacy(), + bioModelRep.getVersionFlag(), groupList.toArray(new String[groupList.size()]), bioModelRep.getDate().getTime(), bioModelRep.getAnnot(), bioModelRep.getBranchID().toString(), bioModelRep.getModelRef().toString(), bioModelRep.getOwner().getName(), bioModelRep.getOwner().getID().toString(), bioModelRep.getSimKeyList(), null); } diff --git a/vcell-rest/src/main/java/org/vcell/restq/models/BiomodelRef.java b/vcell-rest/src/main/java/org/vcell/restq/models/BiomodelRef.java index 5e006e516b..64993de7c5 100644 --- a/vcell-rest/src/main/java/org/vcell/restq/models/BiomodelRef.java +++ b/vcell-rest/src/main/java/org/vcell/restq/models/BiomodelRef.java @@ -9,7 +9,8 @@ public record BiomodelRef( String name, String ownerName, Long ownerKey, - Integer versionFlag) { + Integer versionFlag, + Integer privacy) { public static BiomodelRef fromBioModelReferenceRep(BioModelReferenceRep bioModelReferenceRep) { return new BiomodelRef( @@ -17,7 +18,8 @@ public static BiomodelRef fromBioModelReferenceRep(BioModelReferenceRep bioModel bioModelReferenceRep.getName(), bioModelReferenceRep.getOwner().getName(), Long.parseLong(bioModelReferenceRep.getOwner().getID().toString()), - bioModelReferenceRep.getVersionFlag().intValue() + bioModelReferenceRep.getVersionFlag().intValue(), + bioModelReferenceRep.getPrivacy() ); } @@ -26,7 +28,8 @@ public BioModelReferenceRep toBioModelReferenceRep() { bmKey!=null ? new KeyValue(Long.toString(bmKey)) : null, name, new User(ownerName, new KeyValue(Long.toString(ownerKey))), - versionFlag!=null ? versionFlag.longValue() : null + versionFlag!=null ? versionFlag.longValue() : null, + privacy ); } } diff --git a/vcell-rest/src/main/java/org/vcell/restq/models/PublishModelsRequest.java b/vcell-rest/src/main/java/org/vcell/restq/models/PublishModelsRequest.java new file mode 100644 index 0000000000..76228b540e --- /dev/null +++ b/vcell-rest/src/main/java/org/vcell/restq/models/PublishModelsRequest.java @@ -0,0 +1,6 @@ +package org.vcell.restq.models; + +public record PublishModelsRequest( + Long[] biomodelKeys, + Long[] mathmodelKeys +) {} diff --git a/vcell-rest/src/main/resources/application.properties b/vcell-rest/src/main/resources/application.properties index 93a166cd53..932fd8285f 100644 --- a/vcell-rest/src/main/resources/application.properties +++ b/vcell-rest/src/main/resources/application.properties @@ -102,6 +102,12 @@ quarkus.datasource.postgresql.db-kind=postgresql %test.quarkus.oidc.client-id=backend-service %test.quarkus.oidc.credentials.secret=secret +%test.quarkus.oidc.connection-delay=60S +%test.quarkus.oidc.connection-retry-count=15 +%test.quarkus.devservices.timeout=2M +%test.quarkus.keycloak.devservices.web-client-timeout=60S +%test.quarkus.oidc.devui.web-client-timeout=60S +%test.quarkus.keycloak.devservices.java-opts=-XX:+IgnoreUnrecognizedVMOptions -XX:UseSVE=0 quarkus.test.type=quarkus-test diff --git a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java index 8d008d8664..91d311c863 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java +++ b/vcell-rest/src/test/java/org/vcell/restq/TestEndpointUtils.java @@ -24,6 +24,7 @@ import org.vcell.restclient.ApiException; import org.vcell.restclient.CustomObjectMapper; import org.vcell.restclient.api.UsersResourceApi; +import org.vcell.restclient.model.BiomodelRef; import org.vcell.restclient.model.Publication; import org.vcell.restclient.model.UserLoginInfoForMapping; import org.vcell.restq.db.AgroalConnectionFactory; @@ -128,6 +129,17 @@ public static Publication defaultPublication(){ return publication; } + public static BiomodelRef biomodelRefFromBioModel(org.vcell.restclient.model.BioModel biomodel) { + BiomodelRef ref = new BiomodelRef(); + ref.setBmKey(biomodel.getBmKey() != null ? Long.parseLong(biomodel.getBmKey()) : -1); + ref.setName(biomodel.getName()); + ref.setOwnerName(biomodel.getOwnerName()); + ref.setOwnerKey(biomodel.getOwnerKey() != null ? Long.parseLong(biomodel.getOwnerKey()) : -1); + ref.setVersionFlag(biomodel.getVersionFlag()); + ref.setPrivacy(biomodel.getPrivacy()); + return ref; + } + public static BioModel defaultBiomodel() throws Exception { BioModel biomodel = new BioModel(null); Feature comp = biomodel.getModel().createFeature(); diff --git a/vcell-rest/src/test/java/org/vcell/restq/apiclient/PublicationApiTest.java b/vcell-rest/src/test/java/org/vcell/restq/apiclient/PublicationApiTest.java index c4162d0316..3b8e68b5d5 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/apiclient/PublicationApiTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/apiclient/PublicationApiTest.java @@ -14,9 +14,8 @@ import org.vcell.restclient.ApiException; import org.vcell.restclient.api.BioModelResourceApi; import org.vcell.restclient.api.PublicationResourceApi; -import org.vcell.restclient.model.BiomodelRef; import org.vcell.restclient.model.Publication; -import org.vcell.restclient.model.SaveBioModel; +import org.vcell.restclient.model.PublishModelsRequest; import org.vcell.restq.TestEndpointUtils; import org.vcell.restq.config.CDIVCellConfigProvider; import org.vcell.restq.db.AgroalConnectionFactory; @@ -102,15 +101,8 @@ public void testAddListRemove() throws Exception { org.vcell.restclient.model.BioModel biomodel = bioModelAPI.getBioModel(savedModelKey); Publication publication = TestEndpointUtils.defaultPublication(); - BiomodelRef bioModelRef = new BiomodelRef(); - bioModelRef.setBmKey(Long.parseLong(savedModelKey)); - bioModelRef.setName(biomodel.getName()); - bioModelRef.setOwnerName(biomodel.getOwnerName()); - bioModelRef.setVersionFlag(VersionFlag.Current.getIntValue()); - assert biomodel.getOwnerKey() != null; - bioModelRef.setOwnerKey(Long.parseLong(biomodel.getOwnerKey())); assert publication.getBiomodelRefs() != null; - publication.getBiomodelRefs().add(bioModelRef); + publication.getBiomodelRefs().add(TestEndpointUtils.biomodelRefFromBioModel(biomodel)); // save publication pub Long newPubKey = apiInstance.createPublication(publication); Assertions.assertNotNull(newPubKey); @@ -137,4 +129,86 @@ public void testAddListRemove() throws Exception { // remove added BioModel bioModelAPI.deleteBioModel(savedModelKey); } + + @Test + public void testPublishBioModels() throws Exception { + PublicationResourceApi pubAPI = new PublicationResourceApi(aliceAPIClient); + BioModelResourceApi bioModelAPI = new BioModelResourceApi(aliceAPIClient); + + // Create and save a biomodel with unique name to avoid conflicts with other tests + BioModel realBioModel = TestEndpointUtils.defaultBiomodel(); + realBioModel.setName("PublishTest_" + System.currentTimeMillis()); + String bioModelXml = XmlHelper.bioModelToXML(realBioModel, true); + BioModel savedBioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelAPI.saveBioModel(bioModelXml, null, null))); + String savedModelKey = savedBioModel.getVersion().getVersionKey().toString(); + org.vcell.restclient.model.BioModel biomodel = bioModelAPI.getBioModel(savedModelKey); + + // Create a publication with the biomodel ref queried from the database + Publication publication = TestEndpointUtils.defaultPublication(); + assert publication.getBiomodelRefs() != null; + publication.getBiomodelRefs().add(TestEndpointUtils.biomodelRefFromBioModel(biomodel)); + Long pubKey = pubAPI.createPublication(publication); + + // Verify biomodel is not yet published + Publication fetchedPub = pubAPI.getPublicationById(pubKey); + Assertions.assertNotNull(fetchedPub.getBiomodelRefs()); + Assertions.assertEquals(1, fetchedPub.getBiomodelRefs().size()); + Assertions.assertNotEquals(VersionFlag.Published.getIntValue(), fetchedPub.getBiomodelRefs().get(0).getVersionFlag()); + + // Publish all models linked to this publication (null request = all) + pubAPI.publishBioModels(pubKey, null); + + // Verify biomodel is now published + Publication publishedPub = pubAPI.getPublicationById(pubKey); + Assertions.assertNotNull(publishedPub.getBiomodelRefs()); + Assertions.assertEquals(1, publishedPub.getBiomodelRefs().size()); + Assertions.assertEquals(VersionFlag.Published.getIntValue(), publishedPub.getBiomodelRefs().get(0).getVersionFlag()); + + // Test selective publish with specific keys + PublishModelsRequest request = new PublishModelsRequest(); + request.setBiomodelKeys(List.of(Long.parseLong(savedModelKey))); + pubAPI.publishBioModels(pubKey, request); + + // Verify still published + Publication rePub = pubAPI.getPublicationById(pubKey); + Assertions.assertEquals(VersionFlag.Published.getIntValue(), rePub.getBiomodelRefs().get(0).getVersionFlag()); + + // Cleanup: unpublish before deleting (published models cannot be deleted) + setVersionFlag(savedModelKey, VersionFlag.Current.getIntValue()); + pubAPI.deletePublication(pubKey); + bioModelAPI.deleteBioModel(savedModelKey); + } + + private void setVersionFlag(String bioModelKey, int versionFlagValue) throws DataAccessException, SQLException { + Object lock = new Object(); + java.sql.Connection connection = agroalConnectionFactory.getConnection(lock); + connection.prepareStatement( + "UPDATE vc_biomodel SET versionFlag = " + versionFlagValue + + " WHERE id = " + bioModelKey + ).executeUpdate(); + connection.commit(); + connection.close(); + } + + @Test + public void testPublishBioModelsUnauthorized() throws Exception { + PublicationResourceApi alicePubAPI = new PublicationResourceApi(aliceAPIClient); + PublicationResourceApi bobPubAPI = new PublicationResourceApi(bobAPIClient); + + // Create publication as alice (admin) + Publication publication = TestEndpointUtils.defaultPublication(); + Long pubKey = alicePubAPI.createPublication(publication); + + // Bob (nagios, non-curator) tries to publish - should fail with permission error + try { + bobPubAPI.publishBioModels(pubKey, null); + Assertions.fail("Expected ApiException for unauthorized user"); + } catch (ApiException e) { + Assertions.assertTrue(e.getCode() == 403 || e.getCode() == 500, + "Expected 403 or 500 error, got " + e.getCode()); + } + + // Cleanup + alicePubAPI.deletePublication(pubKey); + } } \ No newline at end of file diff --git a/vcell-rest/src/test/java/org/vcell/restq/apiclient/documents/BioModelApiTest.java b/vcell-rest/src/test/java/org/vcell/restq/apiclient/documents/BioModelApiTest.java index aca8f6c9ec..3df277a41a 100644 --- a/vcell-rest/src/test/java/org/vcell/restq/apiclient/documents/BioModelApiTest.java +++ b/vcell-rest/src/test/java/org/vcell/restq/apiclient/documents/BioModelApiTest.java @@ -34,6 +34,7 @@ import org.vcell.util.document.BioModelChildSummary; import org.vcell.util.document.BioModelInfo; import org.vcell.util.document.KeyValue; +import org.vcell.util.document.VersionFlag; import java.beans.PropertyVetoException; import java.io.IOException; @@ -133,7 +134,9 @@ public void testRemoveBioModel() throws PropertyVetoException, XmlParseException BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelVCML)); KeyValue bioModelKey = bioModel.getVersion().getVersionKey(); - bioModelResourceApi.getBioModel(bioModelKey.toString()); + org.vcell.restclient.model.BioModel restBioModel = bioModelResourceApi.getBioModel(bioModelKey.toString()); + Assertions.assertNotNull(restBioModel.getVersionFlag(), "versionFlag should be populated"); + Assertions.assertEquals(0, restBioModel.getVersionFlag(), "newly saved BioModel should have versionFlag CURRENT (0)"); bioModelResourceApi.deleteBioModel(bioModelKey.toString()); Assertions.assertThrowsExactly(ObjectNotFoundException.class, () -> @@ -141,6 +144,62 @@ public void testRemoveBioModel() throws PropertyVetoException, XmlParseException bioModelKey, false)); } + @Test + public void testCannotDeleteArchivedOrPublishedBioModel() throws PropertyVetoException, XmlParseException, IOException, ApiException, SQLException, DataAccessException { + BioModelResourceApi bioModelResourceApi = new BioModelResourceApi(aliceAPIClient); + + String bioModelVCML = bioModelResourceApi.saveBioModel(XmlHelper.bioModelToXML(TestEndpointUtils.getTestBioModel()), null, null); + BioModel bioModel = XmlHelper.XMLToBioModel(new XMLSource(bioModelVCML)); + KeyValue bioModelKey = bioModel.getVersion().getVersionKey(); + + // Set versionFlag to ARCHIVED (1) via direct SQL + setVersionFlag(bioModelKey, VersionFlag.Archived.getIntValue()); + + // Verify the REST API returns the archived versionFlag + org.vcell.restclient.model.BioModel archivedModel = bioModelResourceApi.getBioModel(bioModelKey.toString()); + Assertions.assertEquals(VersionFlag.Archived.getIntValue(), archivedModel.getVersionFlag(), + "versionFlag should be ARCHIVED"); + + // Attempt to delete archived model should fail + try { + bioModelResourceApi.deleteBioModel(bioModelKey.toString()); + Assertions.fail("Should not be able to delete an ARCHIVED BioModel"); + } catch (ApiException e) { + Assertions.assertEquals(DataAccessWebException.HTTP_CODE, e.getCode()); + } + + // Set versionFlag to PUBLISHED (3) via direct SQL + setVersionFlag(bioModelKey, VersionFlag.Published.getIntValue()); + + // Verify the REST API returns the published versionFlag + org.vcell.restclient.model.BioModel publishedModel = bioModelResourceApi.getBioModel(bioModelKey.toString()); + Assertions.assertEquals(VersionFlag.Published.getIntValue(), publishedModel.getVersionFlag(), + "versionFlag should be PUBLISHED"); + + // Attempt to delete published model should fail + try { + bioModelResourceApi.deleteBioModel(bioModelKey.toString()); + Assertions.fail("Should not be able to delete a PUBLISHED BioModel"); + } catch (ApiException e) { + Assertions.assertEquals(DataAccessWebException.HTTP_CODE, e.getCode()); + } + + // Reset to CURRENT so cleanup can delete it + setVersionFlag(bioModelKey, VersionFlag.Current.getIntValue()); + bioModelResourceApi.deleteBioModel(bioModelKey.toString()); + } + + private void setVersionFlag(KeyValue bioModelKey, int versionFlagValue) throws DataAccessException, SQLException { + Object lock = new Object(); + java.sql.Connection connection = agroalConnectionFactory.getConnection(lock); + connection.prepareStatement( + "UPDATE vc_biomodel SET versionFlag = " + versionFlagValue + + " WHERE id = " + bioModelKey.toString() + ).executeUpdate(); + connection.commit(); + connection.close(); + } + @Test public void testGetBioModelContext() throws PropertyVetoException, XmlParseException, IOException, SQLException, DataAccessException, MappingException, ApiException { diff --git a/vcell-restclient/.openapi-generator/FILES b/vcell-restclient/.openapi-generator/FILES index 602361fc39..db63317f28 100644 --- a/vcell-restclient/.openapi-generator/FILES +++ b/vcell-restclient/.openapi-generator/FILES @@ -58,6 +58,7 @@ docs/Origin.md docs/Publication.md docs/PublicationInfo.md docs/PublicationResourceApi.md +docs/PublishModelsRequest.md docs/SPECIALCLAIM.md docs/SampledCurve.md docs/SchedulerStatus.md @@ -170,6 +171,7 @@ src/main/java/org/vcell/restclient/model/N5ExportRequest.java src/main/java/org/vcell/restclient/model/Origin.java src/main/java/org/vcell/restclient/model/Publication.java src/main/java/org/vcell/restclient/model/PublicationInfo.java +src/main/java/org/vcell/restclient/model/PublishModelsRequest.java src/main/java/org/vcell/restclient/model/SPECIALCLAIM.java src/main/java/org/vcell/restclient/model/SampledCurve.java src/main/java/org/vcell/restclient/model/SchedulerStatus.java diff --git a/vcell-restclient/README.md b/vcell-restclient/README.md index d176009a22..598416b98b 100644 --- a/vcell-restclient/README.md +++ b/vcell-restclient/README.md @@ -171,6 +171,8 @@ Class | Method | HTTP request | Description *PublicationResourceApi* | [**getPublicationByIdWithHttpInfo**](docs/PublicationResourceApi.md#getPublicationByIdWithHttpInfo) | **GET** /api/v1/publications/{id} | Get publication by ID *PublicationResourceApi* | [**getPublications**](docs/PublicationResourceApi.md#getPublications) | **GET** /api/v1/publications | Get all publications *PublicationResourceApi* | [**getPublicationsWithHttpInfo**](docs/PublicationResourceApi.md#getPublicationsWithHttpInfo) | **GET** /api/v1/publications | Get all publications +*PublicationResourceApi* | [**publishBioModels**](docs/PublicationResourceApi.md#publishBioModels) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication +*PublicationResourceApi* | [**publishBioModelsWithHttpInfo**](docs/PublicationResourceApi.md#publishBioModelsWithHttpInfo) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication *PublicationResourceApi* | [**updatePublication**](docs/PublicationResourceApi.md#updatePublication) | **PUT** /api/v1/publications | Update publication *PublicationResourceApi* | [**updatePublicationWithHttpInfo**](docs/PublicationResourceApi.md#updatePublicationWithHttpInfo) | **PUT** /api/v1/publications | Update publication *SimulationResourceApi* | [**getSimulationStatus**](docs/SimulationResourceApi.md#getSimulationStatus) | **GET** /api/v1/Simulation/{simID}/simulationStatus | Get the status of simulation running @@ -266,6 +268,7 @@ Class | Method | HTTP request | Description - [Origin](docs/Origin.md) - [Publication](docs/Publication.md) - [PublicationInfo](docs/PublicationInfo.md) + - [PublishModelsRequest](docs/PublishModelsRequest.md) - [SPECIALCLAIM](docs/SPECIALCLAIM.md) - [SampledCurve](docs/SampledCurve.md) - [SchedulerStatus](docs/SchedulerStatus.md) diff --git a/vcell-restclient/api/openapi.yaml b/vcell-restclient/api/openapi.yaml index 6216886b8c..16c828f0c3 100644 --- a/vcell-restclient/api/openapi.yaml +++ b/vcell-restclient/api/openapi.yaml @@ -1793,6 +1793,58 @@ paths: tags: - Publication Resource x-accepts: application/json + /api/v1/publications/{id}/publish: + put: + operationId: publishBioModels + parameters: + - explode: false + in: path + name: id + required: true + schema: + format: int64 + type: integer + style: simple + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PublishModelsRequest' + responses: + "204": + description: No Content + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Not Authenticated + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Not Allowed + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Not found + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/VCellHTTPError' + description: Data Access Exception + security: + - openId: + - user + summary: Publish selected BioModels and MathModels associated with a publication + tags: + - Publication Resource + x-content-type: application/json + x-accepts: application/json /api/v1/solver/getFVSolverInput: post: operationId: getFVSolverInputFromSBML @@ -2291,18 +2343,19 @@ components: branchID: branchID physModelKey: physModelKey bmKey: bmKey - ownerName: ownerName - name: name + versionFlag: 6 privacy: 0 groupUsers: - groupUsers - groupUsers annot: annot + ownerKey: ownerKey + ownerName: ownerName + name: name simulationKeyList: - null - null - ownerKey: ownerKey - savedDate: 6 + savedDate: 1 applications: - null - null @@ -2314,6 +2367,9 @@ components: privacy: format: int32 type: integer + versionFlag: + format: int32 + type: integer groupUsers: items: type: string @@ -2582,6 +2638,7 @@ components: ownerName: ownerName name: name versionFlag: 7 + privacy: 9 ownerKey: 2 properties: bmKey: @@ -2597,6 +2654,9 @@ components: versionFlag: format: int32 type: integer + privacy: + format: int32 + type: integer type: object CompositeCurve: allOf: @@ -3734,9 +3794,9 @@ components: example: ownerName: ownerName name: name - versionFlag: 2 - mmKey: 9 - ownerKey: 3 + versionFlag: 4 + mmKey: 3 + ownerKey: 2 properties: mmKey: format: int64 @@ -3968,25 +4028,27 @@ components: ownerName: ownerName name: name versionFlag: 7 + privacy: 9 ownerKey: 2 - bmKey: 5 ownerName: ownerName name: name versionFlag: 7 + privacy: 9 ownerKey: 2 pubmedid: pubmedid url: url mathmodelRefs: - ownerName: ownerName name: name - versionFlag: 2 - mmKey: 9 - ownerKey: 3 + versionFlag: 4 + mmKey: 3 + ownerKey: 2 - ownerName: ownerName name: name - versionFlag: 2 - mmKey: 9 - ownerKey: 3 + versionFlag: 4 + mmKey: 3 + ownerKey: 2 pubKey: 0 authors: - authors @@ -4085,6 +4147,26 @@ components: format: int32 type: integer type: object + PublishModelsRequest: + example: + mathmodelKeys: + - 6 + - 6 + biomodelKeys: + - 0 + - 0 + properties: + biomodelKeys: + items: + format: int64 + type: integer + type: array + mathmodelKeys: + items: + format: int64 + type: integer + type: array + type: object SPECIAL_CLAIM: enum: - admins diff --git a/vcell-restclient/docs/BioModel.md b/vcell-restclient/docs/BioModel.md index 5347a562fa..156a12e9be 100644 --- a/vcell-restclient/docs/BioModel.md +++ b/vcell-restclient/docs/BioModel.md @@ -10,6 +10,7 @@ |**bmKey** | **String** | | [optional] | |**name** | **String** | | [optional] | |**privacy** | **Integer** | | [optional] | +|**versionFlag** | **Integer** | | [optional] | |**groupUsers** | **List<String>** | | [optional] | |**savedDate** | **Long** | | [optional] | |**annot** | **String** | | [optional] | diff --git a/vcell-restclient/docs/BiomodelRef.md b/vcell-restclient/docs/BiomodelRef.md index 0cdbb97abd..37f0b59b0f 100644 --- a/vcell-restclient/docs/BiomodelRef.md +++ b/vcell-restclient/docs/BiomodelRef.md @@ -12,6 +12,7 @@ |**ownerName** | **String** | | [optional] | |**ownerKey** | **Long** | | [optional] | |**versionFlag** | **Integer** | | [optional] | +|**privacy** | **Integer** | | [optional] | diff --git a/vcell-restclient/docs/PublicationResourceApi.md b/vcell-restclient/docs/PublicationResourceApi.md index 3ad86157f3..4f2f9b64c9 100644 --- a/vcell-restclient/docs/PublicationResourceApi.md +++ b/vcell-restclient/docs/PublicationResourceApi.md @@ -12,6 +12,8 @@ All URIs are relative to *https://vcell.cam.uchc.edu* | [**getPublicationByIdWithHttpInfo**](PublicationResourceApi.md#getPublicationByIdWithHttpInfo) | **GET** /api/v1/publications/{id} | Get publication by ID | | [**getPublications**](PublicationResourceApi.md#getPublications) | **GET** /api/v1/publications | Get all publications | | [**getPublicationsWithHttpInfo**](PublicationResourceApi.md#getPublicationsWithHttpInfo) | **GET** /api/v1/publications | Get all publications | +| [**publishBioModels**](PublicationResourceApi.md#publishBioModels) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication | +| [**publishBioModelsWithHttpInfo**](PublicationResourceApi.md#publishBioModelsWithHttpInfo) | **PUT** /api/v1/publications/{id}/publish | Publish selected BioModels and MathModels associated with a publication | | [**updatePublication**](PublicationResourceApi.md#updatePublication) | **PUT** /api/v1/publications | Update publication | | [**updatePublicationWithHttpInfo**](PublicationResourceApi.md#updatePublicationWithHttpInfo) | **PUT** /api/v1/publications | Update publication | @@ -553,6 +555,150 @@ No authorization required | **500** | Data Access Exception | - | +## publishBioModels + +> void publishBioModels(id, publishModelsRequest) + +Publish selected BioModels and MathModels associated with a publication + +### Example + +```java +// Import classes: +import org.vcell.restclient.ApiClient; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.Configuration; +import org.vcell.restclient.auth.*; +import org.vcell.restclient.models.*; +import org.vcell.restclient.api.PublicationResourceApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://vcell.cam.uchc.edu"); + + + PublicationResourceApi apiInstance = new PublicationResourceApi(defaultClient); + Long id = 56L; // Long | + PublishModelsRequest publishModelsRequest = new PublishModelsRequest(); // PublishModelsRequest | + try { + apiInstance.publishBioModels(id, publishModelsRequest); + } catch (ApiException e) { + System.err.println("Exception when calling PublicationResourceApi#publishBioModels"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **Long**| | | +| **publishModelsRequest** | [**PublishModelsRequest**](PublishModelsRequest.md)| | [optional] | + +### Return type + + +null (empty response body) + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **204** | No Content | - | +| **401** | Not Authenticated | - | +| **403** | Not Allowed | - | +| **404** | Not found | - | +| **500** | Data Access Exception | - | + +## publishBioModelsWithHttpInfo + +> ApiResponse publishBioModels publishBioModelsWithHttpInfo(id, publishModelsRequest) + +Publish selected BioModels and MathModels associated with a publication + +### Example + +```java +// Import classes: +import org.vcell.restclient.ApiClient; +import org.vcell.restclient.ApiException; +import org.vcell.restclient.ApiResponse; +import org.vcell.restclient.Configuration; +import org.vcell.restclient.auth.*; +import org.vcell.restclient.models.*; +import org.vcell.restclient.api.PublicationResourceApi; + +public class Example { + public static void main(String[] args) { + ApiClient defaultClient = Configuration.getDefaultApiClient(); + defaultClient.setBasePath("https://vcell.cam.uchc.edu"); + + + PublicationResourceApi apiInstance = new PublicationResourceApi(defaultClient); + Long id = 56L; // Long | + PublishModelsRequest publishModelsRequest = new PublishModelsRequest(); // PublishModelsRequest | + try { + ApiResponse response = apiInstance.publishBioModelsWithHttpInfo(id, publishModelsRequest); + System.out.println("Status code: " + response.getStatusCode()); + System.out.println("Response headers: " + response.getHeaders()); + } catch (ApiException e) { + System.err.println("Exception when calling PublicationResourceApi#publishBioModels"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Response headers: " + e.getResponseHeaders()); + System.err.println("Reason: " + e.getResponseBody()); + e.printStackTrace(); + } + } +} +``` + +### Parameters + + +| Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **id** | **Long**| | | +| **publishModelsRequest** | [**PublishModelsRequest**](PublishModelsRequest.md)| | [optional] | + +### Return type + + +ApiResponse + +### Authorization + +[openId](../README.md#openId) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + +### HTTP response details +| Status code | Description | Response headers | +|-------------|-------------|------------------| +| **204** | No Content | - | +| **401** | Not Authenticated | - | +| **403** | Not Allowed | - | +| **404** | Not found | - | +| **500** | Data Access Exception | - | + + ## updatePublication > Publication updatePublication(publication) diff --git a/vcell-restclient/docs/PublishModelsRequest.md b/vcell-restclient/docs/PublishModelsRequest.md new file mode 100644 index 0000000000..8b62aadbbe --- /dev/null +++ b/vcell-restclient/docs/PublishModelsRequest.md @@ -0,0 +1,14 @@ + + +# PublishModelsRequest + + +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +|**biomodelKeys** | **List<Long>** | | [optional] | +|**mathmodelKeys** | **List<Long>** | | [optional] | + + + diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/api/PublicationResourceApi.java b/vcell-restclient/src/main/java/org/vcell/restclient/api/PublicationResourceApi.java index 343810defc..60013756a2 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/api/PublicationResourceApi.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/api/PublicationResourceApi.java @@ -18,6 +18,7 @@ import org.vcell.restclient.Pair; import org.vcell.restclient.model.Publication; +import org.vcell.restclient.model.PublishModelsRequest; import org.vcell.restclient.model.VCellHTTPError; import com.fasterxml.jackson.core.type.TypeReference; @@ -373,6 +374,89 @@ private HttpRequest.Builder getPublicationsRequestBuilder() throws ApiException } return localVarRequestBuilder; } + /** + * Publish selected BioModels and MathModels associated with a publication + * + * @param id (required) + * @param publishModelsRequest (optional) + * @throws ApiException if fails to make API call + */ + public void publishBioModels(Long id, PublishModelsRequest publishModelsRequest) throws ApiException { + publishBioModelsWithHttpInfo(id, publishModelsRequest); + } + + /** + * Publish selected BioModels and MathModels associated with a publication + * + * @param id (required) + * @param publishModelsRequest (optional) + * @return ApiResponse<Void> + * @throws ApiException if fails to make API call + */ + public ApiResponse publishBioModelsWithHttpInfo(Long id, PublishModelsRequest publishModelsRequest) throws ApiException { + HttpRequest.Builder localVarRequestBuilder = publishBioModelsRequestBuilder(id, publishModelsRequest); + try { + HttpResponse localVarResponse = memberVarHttpClient.send( + localVarRequestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream()); + if (memberVarResponseInterceptor != null) { + memberVarResponseInterceptor.accept(localVarResponse); + } + try { + if (localVarResponse.statusCode()/ 100 != 2) { + throw getApiException("publishBioModels", localVarResponse); + } + return new ApiResponse( + localVarResponse.statusCode(), + localVarResponse.headers().map(), + null + ); + } finally { + // Drain the InputStream + while (localVarResponse.body().read() != -1) { + // Ignore + } + localVarResponse.body().close(); + } + } catch (IOException e) { + throw new ApiException(e); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ApiException(e); + } + } + + private HttpRequest.Builder publishBioModelsRequestBuilder(Long id, PublishModelsRequest publishModelsRequest) throws ApiException { + // verify the required parameter 'id' is set + if (id == null) { + throw new ApiException(400, "Missing the required parameter 'id' when calling publishBioModels"); + } + + HttpRequest.Builder localVarRequestBuilder = HttpRequest.newBuilder(); + + String localVarPath = "/api/v1/publications/{id}/publish" + .replace("{id}", ApiClient.urlEncode(id.toString())); + + localVarRequestBuilder.uri(URI.create(memberVarBaseUri + localVarPath)); + + localVarRequestBuilder.header("Content-Type", "application/json"); + localVarRequestBuilder.header("Accept", "application/json"); + + try { + byte[] localVarPostBody = memberVarObjectMapper.writeValueAsBytes(publishModelsRequest); + localVarRequestBuilder.method("PUT", HttpRequest.BodyPublishers.ofByteArray(localVarPostBody)); + } catch (IOException e) { + throw new ApiException(e); + } + if (memberVarReadTimeout != null) { + localVarRequestBuilder.timeout(memberVarReadTimeout); + } + if (memberVarInterceptor != null) { + memberVarInterceptor.accept(localVarRequestBuilder); + } + return localVarRequestBuilder; + } /** * Update publication * diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/BioModel.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/BioModel.java index 87a75e57ac..ae11367c97 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/BioModel.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/BioModel.java @@ -37,6 +37,7 @@ BioModel.JSON_PROPERTY_BM_KEY, BioModel.JSON_PROPERTY_NAME, BioModel.JSON_PROPERTY_PRIVACY, + BioModel.JSON_PROPERTY_VERSION_FLAG, BioModel.JSON_PROPERTY_GROUP_USERS, BioModel.JSON_PROPERTY_SAVED_DATE, BioModel.JSON_PROPERTY_ANNOT, @@ -58,6 +59,9 @@ public class BioModel { public static final String JSON_PROPERTY_PRIVACY = "privacy"; private Integer privacy; + public static final String JSON_PROPERTY_VERSION_FLAG = "versionFlag"; + private Integer versionFlag; + public static final String JSON_PROPERTY_GROUP_USERS = "groupUsers"; private List groupUsers; @@ -163,6 +167,31 @@ public void setPrivacy(Integer privacy) { } + public BioModel versionFlag(Integer versionFlag) { + this.versionFlag = versionFlag; + return this; + } + + /** + * Get versionFlag + * @return versionFlag + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_VERSION_FLAG) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getVersionFlag() { + return versionFlag; + } + + + @JsonProperty(JSON_PROPERTY_VERSION_FLAG) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setVersionFlag(Integer versionFlag) { + this.versionFlag = versionFlag; + } + + public BioModel groupUsers(List groupUsers) { this.groupUsers = groupUsers; return this; @@ -427,6 +456,7 @@ public boolean equals(Object o) { return Objects.equals(this.bmKey, bioModel.bmKey) && Objects.equals(this.name, bioModel.name) && Objects.equals(this.privacy, bioModel.privacy) && + Objects.equals(this.versionFlag, bioModel.versionFlag) && Objects.equals(this.groupUsers, bioModel.groupUsers) && Objects.equals(this.savedDate, bioModel.savedDate) && Objects.equals(this.annot, bioModel.annot) && @@ -440,7 +470,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(bmKey, name, privacy, groupUsers, savedDate, annot, branchID, physModelKey, ownerName, ownerKey, simulationKeyList, applications); + return Objects.hash(bmKey, name, privacy, versionFlag, groupUsers, savedDate, annot, branchID, physModelKey, ownerName, ownerKey, simulationKeyList, applications); } @Override @@ -450,6 +480,7 @@ public String toString() { sb.append(" bmKey: ").append(toIndentedString(bmKey)).append("\n"); sb.append(" name: ").append(toIndentedString(name)).append("\n"); sb.append(" privacy: ").append(toIndentedString(privacy)).append("\n"); + sb.append(" versionFlag: ").append(toIndentedString(versionFlag)).append("\n"); sb.append(" groupUsers: ").append(toIndentedString(groupUsers)).append("\n"); sb.append(" savedDate: ").append(toIndentedString(savedDate)).append("\n"); sb.append(" annot: ").append(toIndentedString(annot)).append("\n"); @@ -521,6 +552,11 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%sprivacy%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getPrivacy()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } + // add `versionFlag` to the URL query string + if (getVersionFlag() != null) { + joiner.add(String.format("%sversionFlag%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getVersionFlag()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + // add `groupUsers` to the URL query string if (getGroupUsers() != null) { for (int i = 0; i < getGroupUsers().size(); i++) { diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/BiomodelRef.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/BiomodelRef.java index 3456ac5fc8..422d123d10 100644 --- a/vcell-restclient/src/main/java/org/vcell/restclient/model/BiomodelRef.java +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/BiomodelRef.java @@ -36,7 +36,8 @@ BiomodelRef.JSON_PROPERTY_NAME, BiomodelRef.JSON_PROPERTY_OWNER_NAME, BiomodelRef.JSON_PROPERTY_OWNER_KEY, - BiomodelRef.JSON_PROPERTY_VERSION_FLAG + BiomodelRef.JSON_PROPERTY_VERSION_FLAG, + BiomodelRef.JSON_PROPERTY_PRIVACY }) @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") public class BiomodelRef { @@ -55,6 +56,9 @@ public class BiomodelRef { public static final String JSON_PROPERTY_VERSION_FLAG = "versionFlag"; private Integer versionFlag; + public static final String JSON_PROPERTY_PRIVACY = "privacy"; + private Integer privacy; + public BiomodelRef() { } @@ -183,6 +187,31 @@ public void setVersionFlag(Integer versionFlag) { } + public BiomodelRef privacy(Integer privacy) { + this.privacy = privacy; + return this; + } + + /** + * Get privacy + * @return privacy + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_PRIVACY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public Integer getPrivacy() { + return privacy; + } + + + @JsonProperty(JSON_PROPERTY_PRIVACY) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setPrivacy(Integer privacy) { + this.privacy = privacy; + } + + /** * Return true if this BiomodelRef object is equal to o. */ @@ -199,12 +228,13 @@ public boolean equals(Object o) { Objects.equals(this.name, biomodelRef.name) && Objects.equals(this.ownerName, biomodelRef.ownerName) && Objects.equals(this.ownerKey, biomodelRef.ownerKey) && - Objects.equals(this.versionFlag, biomodelRef.versionFlag); + Objects.equals(this.versionFlag, biomodelRef.versionFlag) && + Objects.equals(this.privacy, biomodelRef.privacy); } @Override public int hashCode() { - return Objects.hash(bmKey, name, ownerName, ownerKey, versionFlag); + return Objects.hash(bmKey, name, ownerName, ownerKey, versionFlag, privacy); } @Override @@ -216,6 +246,7 @@ public String toString() { sb.append(" ownerName: ").append(toIndentedString(ownerName)).append("\n"); sb.append(" ownerKey: ").append(toIndentedString(ownerKey)).append("\n"); sb.append(" versionFlag: ").append(toIndentedString(versionFlag)).append("\n"); + sb.append(" privacy: ").append(toIndentedString(privacy)).append("\n"); sb.append("}"); return sb.toString(); } @@ -288,6 +319,11 @@ public String toUrlQueryString(String prefix) { joiner.add(String.format("%sversionFlag%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getVersionFlag()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); } + // add `privacy` to the URL query string + if (getPrivacy() != null) { + joiner.add(String.format("%sprivacy%s=%s", prefix, suffix, URLEncoder.encode(String.valueOf(getPrivacy()), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + return joiner.toString(); } } diff --git a/vcell-restclient/src/main/java/org/vcell/restclient/model/PublishModelsRequest.java b/vcell-restclient/src/main/java/org/vcell/restclient/model/PublishModelsRequest.java new file mode 100644 index 0000000000..9386bc95cd --- /dev/null +++ b/vcell-restclient/src/main/java/org/vcell/restclient/model/PublishModelsRequest.java @@ -0,0 +1,212 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.StringJoiner; +import java.util.Objects; +import java.util.Map; +import java.util.HashMap; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * PublishModelsRequest + */ +@JsonPropertyOrder({ + PublishModelsRequest.JSON_PROPERTY_BIOMODEL_KEYS, + PublishModelsRequest.JSON_PROPERTY_MATHMODEL_KEYS +}) +@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") +public class PublishModelsRequest { + public static final String JSON_PROPERTY_BIOMODEL_KEYS = "biomodelKeys"; + private List biomodelKeys; + + public static final String JSON_PROPERTY_MATHMODEL_KEYS = "mathmodelKeys"; + private List mathmodelKeys; + + public PublishModelsRequest() { + } + + public PublishModelsRequest biomodelKeys(List biomodelKeys) { + this.biomodelKeys = biomodelKeys; + return this; + } + + public PublishModelsRequest addBiomodelKeysItem(Long biomodelKeysItem) { + if (this.biomodelKeys == null) { + this.biomodelKeys = new ArrayList<>(); + } + this.biomodelKeys.add(biomodelKeysItem); + return this; + } + + /** + * Get biomodelKeys + * @return biomodelKeys + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_BIOMODEL_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getBiomodelKeys() { + return biomodelKeys; + } + + + @JsonProperty(JSON_PROPERTY_BIOMODEL_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setBiomodelKeys(List biomodelKeys) { + this.biomodelKeys = biomodelKeys; + } + + + public PublishModelsRequest mathmodelKeys(List mathmodelKeys) { + this.mathmodelKeys = mathmodelKeys; + return this; + } + + public PublishModelsRequest addMathmodelKeysItem(Long mathmodelKeysItem) { + if (this.mathmodelKeys == null) { + this.mathmodelKeys = new ArrayList<>(); + } + this.mathmodelKeys.add(mathmodelKeysItem); + return this; + } + + /** + * Get mathmodelKeys + * @return mathmodelKeys + **/ + @javax.annotation.Nullable + @JsonProperty(JSON_PROPERTY_MATHMODEL_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + + public List getMathmodelKeys() { + return mathmodelKeys; + } + + + @JsonProperty(JSON_PROPERTY_MATHMODEL_KEYS) + @JsonInclude(value = JsonInclude.Include.USE_DEFAULTS) + public void setMathmodelKeys(List mathmodelKeys) { + this.mathmodelKeys = mathmodelKeys; + } + + + /** + * Return true if this PublishModelsRequest object is equal to o. + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PublishModelsRequest publishModelsRequest = (PublishModelsRequest) o; + return Objects.equals(this.biomodelKeys, publishModelsRequest.biomodelKeys) && + Objects.equals(this.mathmodelKeys, publishModelsRequest.mathmodelKeys); + } + + @Override + public int hashCode() { + return Objects.hash(biomodelKeys, mathmodelKeys); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class PublishModelsRequest {\n"); + sb.append(" biomodelKeys: ").append(toIndentedString(biomodelKeys)).append("\n"); + sb.append(" mathmodelKeys: ").append(toIndentedString(mathmodelKeys)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + + /** + * Convert the instance into URL query string. + * + * @return URL query string + */ + public String toUrlQueryString() { + return toUrlQueryString(null); + } + + /** + * Convert the instance into URL query string. + * + * @param prefix prefix of the query string + * @return URL query string + */ + public String toUrlQueryString(String prefix) { + String suffix = ""; + String containerSuffix = ""; + String containerPrefix = ""; + if (prefix == null) { + // style=form, explode=true, e.g. /pet?name=cat&type=manx + prefix = ""; + } else { + // deepObject style e.g. /pet?id[name]=cat&id[type]=manx + prefix = prefix + "["; + suffix = "]"; + containerSuffix = "]"; + containerPrefix = "["; + } + + StringJoiner joiner = new StringJoiner("&"); + + // add `biomodelKeys` to the URL query string + if (getBiomodelKeys() != null) { + for (int i = 0; i < getBiomodelKeys().size(); i++) { + joiner.add(String.format("%sbiomodelKeys%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getBiomodelKeys().get(i)), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + } + + // add `mathmodelKeys` to the URL query string + if (getMathmodelKeys() != null) { + for (int i = 0; i < getMathmodelKeys().size(); i++) { + joiner.add(String.format("%smathmodelKeys%s%s=%s", prefix, suffix, + "".equals(suffix) ? "" : String.format("%s%d%s", containerPrefix, i, containerSuffix), + URLEncoder.encode(String.valueOf(getMathmodelKeys().get(i)), StandardCharsets.UTF_8).replaceAll("\\+", "%20"))); + } + } + + return joiner.toString(); + } +} + diff --git a/vcell-restclient/src/test/java/org/vcell/restclient/model/PublishModelsRequestTest.java b/vcell-restclient/src/test/java/org/vcell/restclient/model/PublishModelsRequestTest.java new file mode 100644 index 0000000000..38d59bd784 --- /dev/null +++ b/vcell-restclient/src/test/java/org/vcell/restclient/model/PublishModelsRequestTest.java @@ -0,0 +1,58 @@ +/* + * VCell API + * VCell API + * + * The version of the OpenAPI document: 1.0.1 + * Contact: vcell_support@uchc.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package org.vcell.restclient.model; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonValue; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Model tests for PublishModelsRequest + */ +public class PublishModelsRequestTest { + private final PublishModelsRequest model = new PublishModelsRequest(); + + /** + * Model tests for PublishModelsRequest + */ + @Test + public void testPublishModelsRequest() { + // TODO: test PublishModelsRequest + } + + /** + * Test the property 'biomodelKeys' + */ + @Test + public void biomodelKeysTest() { + // TODO: test biomodelKeys + } + + /** + * Test the property 'mathmodelKeys' + */ + @Test + public void mathmodelKeysTest() { + // TODO: test mathmodelKeys + } + +} diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelReferenceRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelReferenceRep.java index cca11e6f7f..59da759c35 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelReferenceRep.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelReferenceRep.java @@ -8,13 +8,15 @@ public class BioModelReferenceRep { private final String name; private final User owner; private final Long versionFlag; - - public BioModelReferenceRep(KeyValue bmKey, String name, User owner,Long versionFlag) { + private final Integer privacy; + + public BioModelReferenceRep(KeyValue bmKey, String name, User owner, Long versionFlag, Integer privacy) { super(); this.bmKey = bmKey; this.name = name; this.owner = owner; this.versionFlag = versionFlag; + this.privacy = privacy; } public KeyValue getBmKey() { @@ -32,4 +34,8 @@ public User getOwner() { public Long getVersionFlag() { return versionFlag; } + + public Integer getPrivacy() { + return privacy; + } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelRep.java b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelRep.java index fc52afb3fb..f5f37fa656 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelRep.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelRep.java @@ -11,6 +11,7 @@ public class BioModelRep { private final KeyValue bmKey; private final String name; private final int privacy; + private final int versionFlag; private final User[] groupUsers; private final Date date; private final String annot; @@ -22,12 +23,13 @@ public class BioModelRep { private ArrayList simContextRepList = new ArrayList(); private ArrayList simulationRepList = new ArrayList(); - public BioModelRep(KeyValue bmKey, String name, int privacy, User[] groupUsers, Date date, String annot, BigDecimal branchID, KeyValue modelRef, + public BioModelRep(KeyValue bmKey, String name, int privacy, int versionFlag, User[] groupUsers, Date date, String annot, BigDecimal branchID, KeyValue modelRef, User owner, KeyValue[] simKeyList, KeyValue[] simContextKeyList) { super(); this.bmKey = bmKey; this.name = name; this.privacy = privacy; + this.versionFlag = versionFlag; this.groupUsers = groupUsers; this.date = date; this.annot = annot; @@ -50,6 +52,10 @@ public int getPrivacy() { return privacy; } + public int getVersionFlag() { + return versionFlag; + } + public User[] getGroupUsers() { return groupUsers; } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelTable.java index fa295f3285..979866b32e 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/BioModelTable.java @@ -185,6 +185,7 @@ public String getPreparedStatement_BioModelReps(String conditions, OrderBy order bmTable.id.getQualifiedColName()+", "+ bmTable.name.getQualifiedColName()+", "+ bmTable.privacy.getQualifiedColName()+", "+ + bmTable.versionFlag.getQualifiedColName()+", "+ bmTable.versionDate.getQualifiedColName()+", "+ bmTable.versionAnnot.getQualifiedColName()+", "+ bmTable.versionBranchID.getQualifiedColName()+", "+ @@ -291,6 +292,7 @@ public BioModelRep getBioModelRep(User user, ResultSet rset, DatabaseSyntax dbSy KeyValue bmKey = new KeyValue(rset.getBigDecimal(table.id.toString())); String name = rset.getString(table.name.toString()); int privacy = rset.getInt(table.privacy.toString()); + int versionFlag = rset.getInt(table.versionFlag.toString()); Date date = getDate(rset, dbSyntax, table.versionDate.toString()); String annot = rset.getString(table.versionAnnot.toString()); BigDecimal branchID = rset.getBigDecimal(table.versionBranchID.toString()); @@ -342,6 +344,6 @@ public BioModelRep getBioModelRep(User user, ResultSet rset, DatabaseSyntax dbSy User[] groupUserArray = groupUsers.toArray(new User[0]); - return new BioModelRep(bmKey,name,privacy,groupUserArray,date,annot,branchID,modelRef,owner,simKeyArray,simContextKeyArray); + return new BioModelRep(bmKey,name,privacy,versionFlag,groupUserArray,date,annot,branchID,modelRef,owner,simKeyArray,simContextKeyArray); } } diff --git a/vcell-server/src/main/java/cbit/vcell/modeldb/PublicationTable.java b/vcell-server/src/main/java/cbit/vcell/modeldb/PublicationTable.java index f909151ff8..18498c562e 100644 --- a/vcell-server/src/main/java/cbit/vcell/modeldb/PublicationTable.java +++ b/vcell-server/src/main/java/cbit/vcell/modeldb/PublicationTable.java @@ -109,7 +109,8 @@ public String getPreparedStatement_PublicationReps(String conditions, OrderBy or "||"+"SQ1_"+biomodelTable.name.getQualifiedColName()+"||';'"+ "||"+"SQ1_"+userTable.id.getQualifiedColName()+string_cast+"||';'"+ "||"+"SQ1_"+userTable.userid.getQualifiedColName()+"||';'"+ - "||"+"SQ1_"+biomodelTable.versionFlag.getQualifiedColName()+string_cast + concat_second_arg+")||']' "+ + "||"+"SQ1_"+biomodelTable.versionFlag.getQualifiedColName()+string_cast+"||';'"+ + "||"+"SQ1_"+biomodelTable.privacy.getQualifiedColName()+string_cast + concat_second_arg+")||']' "+ " from "+pubModelTable.getTableName()+" SQ1_"+pubModelTable.getTableName()+", "+ biomodelTable.getTableName()+" SQ1_"+biomodelTable.getTableName()+", "+ userTable.getTableName()+" SQ1_"+userTable.getTableName()+" "+ @@ -182,13 +183,14 @@ public PublicationRep getPublicationRep(ResultSet rset, DatabaseSyntax dbSyntax) String[] bmRefStrings = bmRefsString.replace("[", "").replace("]", "").split(","); for (String bmRefString : bmRefStrings) { String bmRefComponents[] = bmRefString.split(";"); - if (bmRefComponents.length==5){ + if (bmRefComponents.length >= 5){ KeyValue bmKey = new KeyValue(bmRefComponents[0]); String bmName = bmRefComponents[1]; KeyValue ownerKey = new KeyValue(bmRefComponents[2]); String ownerUserid = bmRefComponents[3]; Long versionFlag = Long.valueOf(bmRefComponents[4]); - bmRefList.add(new BioModelReferenceRep(bmKey, bmName, new User(ownerUserid,ownerKey),versionFlag)); + Integer privacy = bmRefComponents.length >= 6 ? Integer.valueOf(bmRefComponents[5]) : null; + bmRefList.add(new BioModelReferenceRep(bmKey, bmName, new User(ownerUserid,ownerKey), versionFlag, privacy)); } } } diff --git a/webapp-ng/package-lock.json b/webapp-ng/package-lock.json index 03a404acc2..d0836bc1e4 100644 --- a/webapp-ng/package-lock.json +++ b/webapp-ng/package-lock.json @@ -247,13 +247,6 @@ "node": ">=12" } }, - "node_modules/@angular-devkit/build-angular/node_modules/@types/node": { - "version": "20.3.1", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/@angular-devkit/build-angular/node_modules/@vitejs/plugin-basic-ssl": { "version": "1.0.1", "dev": true, @@ -17738,12 +17731,6 @@ "dev": true, "optional": true }, - "@types/node": { - "version": "20.3.1", - "dev": true, - "optional": true, - "peer": true - }, "@vitejs/plugin-basic-ssl": { "version": "1.0.1", "dev": true, diff --git a/webapp-ng/src/app/components/publication-detail/publication-detail.component.html b/webapp-ng/src/app/components/publication-detail/publication-detail.component.html index 5141cf7f17..dd80466dd2 100644 --- a/webapp-ng/src/app/components/publication-detail/publication-detail.component.html +++ b/webapp-ng/src/app/components/publication-detail/publication-detail.component.html @@ -4,5 +4,5 @@

{{ "Publication id=" + publication

Loading publication...


- + diff --git a/webapp-ng/src/app/components/publication-detail/publication-detail.component.ts b/webapp-ng/src/app/components/publication-detail/publication-detail.component.ts index 886d20ef84..8c6db0ae70 100644 --- a/webapp-ng/src/app/components/publication-detail/publication-detail.component.ts +++ b/webapp-ng/src/app/components/publication-detail/publication-detail.component.ts @@ -65,6 +65,19 @@ export class PublicationDetailComponent implements OnInit { }); } + refreshPublication() { + if (this.publication?.pubKey) { + this.publicationService.getPublicationById(this.publication.pubKey).subscribe({ + next: (publication) => { + this.publication = publication; + }, + error: (err) => { + console.error('Error refreshing publication', err); + } + }); + } + } + cancel() { console.log("Update cancelled"); this.router.navigate(['/publications']); diff --git a/webapp-ng/src/app/components/publication-edit/publication-edit.component.css b/webapp-ng/src/app/components/publication-edit/publication-edit.component.css index cfc6610f8d..6d6b87bca7 100644 --- a/webapp-ng/src/app/components/publication-edit/publication-edit.component.css +++ b/webapp-ng/src/app/components/publication-edit/publication-edit.component.css @@ -28,7 +28,65 @@ .list-item { margin-top: 0; margin-bottom: 0; - /*height: min-content; !* Adjust this value as needed *!*/ - /*display: flex;*/ align-items: center; } + +.version-badge { + display: inline-block; + padding: 2px 8px; + border-radius: 12px; + font-size: 0.75em; + font-weight: 500; + margin-left: 8px; +} + +.badge-published { + background-color: #4caf50; + color: white; +} + +.badge-archived { + background-color: #ff9800; + color: white; +} + +.badge-current { + background-color: #9e9e9e; + color: white; +} + +.badge-unknown { + background-color: #e0e0e0; + color: #666; +} + +.privacy-badge { + display: inline-block; + padding: 2px 8px; + border-radius: 12px; + font-size: 0.75em; + font-weight: 500; + margin-left: 4px; +} + +.badge-public { + background-color: #2196f3; + color: white; +} + +.badge-private { + background-color: #f44336; + color: white; +} + +.badge-shared { + background-color: #9c27b0; + color: white; +} + +.publish-row { + display: flex; + justify-content: flex-start; + margin-top: 1rem; + margin-bottom: 1rem; +} diff --git a/webapp-ng/src/app/components/publication-edit/publication-edit.component.html b/webapp-ng/src/app/components/publication-edit/publication-edit.component.html index 8d541f8176..d28e95a02c 100644 --- a/webapp-ng/src/app/components/publication-edit/publication-edit.component.html +++ b/webapp-ng/src/app/components/publication-edit/publication-edit.component.html @@ -45,7 +45,10 @@

Biomodel IDs

+ {{ "BioModel (" + biomodelRef.ownerName + " : " + biomodelRef.bmKey + " : " + biomodelRef.name + ")" }} + {{ getVersionFlagLabel(biomodelRef.versionFlag) }} + {{ getPrivacyLabel(biomodelRef.privacy) }} @@ -66,7 +69,9 @@

Mathmodel IDs

+ {{ "MathModel (" + mathmodelRef.ownerName + " : " + mathmodelRef.mmKey + " : " + mathmodelRef.name + ")" }} + {{ getVersionFlagLabel(mathmodelRef.versionFlag) }} @@ -85,6 +90,12 @@

Mathmodel IDs

+
+ +
+