j4rs/
provisioning.rs

1// Copyright 2019 astonbitecode
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::cell::RefCell;
16
17use crate::utils;
18
19const MAVEN_CENTRAL: &str = "MavenCentral::https://repo.maven.apache.org/maven2";
20const OSS_SNAPSHOTS: &str = "OssSnapshots::https://oss.sonatype.org/content/repositories/snapshots";
21
22thread_local! {
23    static MAVEN_SETTINGS: RefCell<MavenSettings> = RefCell::new(MavenSettings::default());
24}
25
26pub(crate) fn set_maven_settings(ms: &MavenSettings) {
27    MAVEN_SETTINGS.with(|maven_settings| {
28        *maven_settings.borrow_mut() = ms.clone();
29    });
30}
31
32pub(crate) fn get_maven_settings() -> MavenSettings {
33    MAVEN_SETTINGS.with(|maven_settings| {
34        let ms = maven_settings.borrow();
35        ms.clone()
36    })
37}
38
39/// Marker trait to be used for deploying artifacts.
40pub trait JavaArtifact {}
41
42/// Represents a Jar artifact that resides in the local storage.
43/// It can be deployed in order to be loaded and used by j4rs by calling the `JVM::deploy_artifact` method.
44#[derive(Debug)]
45pub struct LocalJarArtifact {
46    pub(crate) base: String,
47    pub(crate) path: String,
48}
49
50impl LocalJarArtifact {
51    /// Creates a new LocalJarArtifact.
52    /// path is the location of the jar file in the local storage
53    pub fn new(path: &str) -> LocalJarArtifact {
54        LocalJarArtifact {
55            base: utils::jassets_path()
56                .unwrap_or_default()
57                .to_str()
58                .unwrap_or("")
59                .to_string(),
60            path: path.to_string(),
61        }
62    }
63}
64
65impl JavaArtifact for LocalJarArtifact {}
66
67impl<'a> From<&'a str> for LocalJarArtifact {
68    fn from(string: &'a str) -> LocalJarArtifact {
69        LocalJarArtifact::new(string)
70    }
71}
72
73impl From<String> for LocalJarArtifact {
74    fn from(string: String) -> LocalJarArtifact {
75        LocalJarArtifact::new(&string)
76    }
77}
78
79/// Represents an Artifact that can be fetched by a remote Maven repository.
80/// It can loaded and used by j4rs by calling the `JVM::deploy_artifact` method.
81#[derive(Debug, Clone)]
82pub struct MavenArtifact {
83    pub(crate) base: String,
84    pub(crate) group: String,
85    pub(crate) id: String,
86    pub(crate) version: String,
87    pub(crate) qualifier: String,
88}
89
90impl JavaArtifact for MavenArtifact {}
91
92impl From<&[&str]> for MavenArtifact {
93    fn from(slice: &[&str]) -> MavenArtifact {
94        MavenArtifact {
95            base: utils::jassets_path()
96                .unwrap_or_default()
97                .to_str()
98                .unwrap_or("")
99                .to_string(),
100            group: slice.first().unwrap_or(&"").to_string(),
101            id: slice.get(1).unwrap_or(&"").to_string(),
102            version: slice.get(2).unwrap_or(&"").to_string(),
103            qualifier: slice.get(3).unwrap_or(&"").to_string(),
104        }
105    }
106}
107
108impl From<Vec<&str>> for MavenArtifact {
109    fn from(v: Vec<&str>) -> MavenArtifact {
110        MavenArtifact::from(v.as_slice())
111    }
112}
113
114impl From<&Vec<&str>> for MavenArtifact {
115    fn from(v: &Vec<&str>) -> MavenArtifact {
116        MavenArtifact::from(v.as_slice())
117    }
118}
119
120impl<'a> From<&'a str> for MavenArtifact {
121    /// Convenience for creating a MavenArtifact.
122    ///
123    /// The `&str` should be formed like following:
124    ///
125    /// __group__:__id__:__version__:__qualifier__
126    ///
127    /// E.g:
128    /// _io.github.astonbitecode:j4rs:0.5.1_
129    fn from(string: &'a str) -> MavenArtifact {
130        let v: Vec<&str> = string.split(':').collect();
131        MavenArtifact::from(v.as_slice())
132    }
133}
134
135impl From<String> for MavenArtifact {
136    /// Convenience for creating a MavenArtifact.
137    ///
138    /// The `&str` should be formed like following:
139    ///
140    /// __group__:__id__:__version__:__qualifier__
141    ///
142    /// E.g:
143    /// _io.github.astonbitecode:j4rs:0.5.1_
144    fn from(string: String) -> MavenArtifact {
145        let v: Vec<&str> = string.split(':').collect();
146        MavenArtifact::from(v.as_slice())
147    }
148}
149
150/// Contains Maven settings and configuration
151#[derive(Debug, Clone)]
152pub struct MavenSettings {
153    pub(crate) repos: Vec<MavenArtifactRepo>,
154}
155
156impl MavenSettings {
157    /// Creates new Maven Settings by defining additional repositories to use.
158    /// The [maven central](https://repo.maven.apache.org/maven2) is always being included as a repo.
159    pub fn new(repos: Vec<MavenArtifactRepo>) -> MavenSettings {
160        let mut repos = repos;
161        repos.push(MavenArtifactRepo::from(MAVEN_CENTRAL));
162        repos.push(MavenArtifactRepo::from(OSS_SNAPSHOTS));
163        MavenSettings { repos }
164    }
165}
166
167impl Default for MavenSettings {
168    fn default() -> Self {
169        MavenSettings::new(vec![])
170    }
171}
172
173/// A repository from which Java artifacts can be fetched.
174#[derive(Debug, Clone)]
175pub struct MavenArtifactRepo {
176    pub(crate) _id: String,
177    pub(crate) uri: String,
178}
179
180impl From<&[&str]> for MavenArtifactRepo {
181    fn from(slice: &[&str]) -> MavenArtifactRepo {
182        MavenArtifactRepo {
183            _id: slice.first().unwrap_or(&"").to_string(),
184            uri: slice.get(1).unwrap_or(&"").to_string(),
185        }
186    }
187}
188
189impl<'a> From<&'a str> for MavenArtifactRepo {
190    /// Convenience for creating a MavenArtifactRepo.
191    ///
192    /// The `&str` should be formed like following:
193    ///
194    /// `id::uri`
195    ///
196    /// E.g:
197    /// `MyAlterRepo::https://myalterrepo.io`
198    fn from(string: &'a str) -> MavenArtifactRepo {
199        let v: Vec<&str> = string.split("::").collect();
200        MavenArtifactRepo::from(v.as_slice())
201    }
202}
203
204impl From<String> for MavenArtifactRepo {
205    /// Convenience for creating a MavenArtifactRepo.
206    ///
207    /// The `&str` should be formed like following:
208    ///
209    /// `id::uri`
210    ///
211    /// E.g:
212    /// `MyAlterRepo::https://myalterrepo.io`
213    fn from(string: String) -> MavenArtifactRepo {
214        MavenArtifactRepo::from(string.as_str())
215    }
216}
217
218#[cfg(test)]
219mod provisioning_unit_tests {
220    use super::*;
221
222    #[test]
223    fn maven_artifact_from() {
224        let ma1 = MavenArtifact::from("io.github.astonbitecode:j4rs:0.5.1");
225        assert_eq!(ma1.group, "io.github.astonbitecode");
226        assert_eq!(ma1.id, "j4rs");
227        assert_eq!(ma1.version, "0.5.1");
228        assert_eq!(ma1.qualifier, "");
229
230        let ma2 = MavenArtifact::from("io.github.astonbitecode:j4rs:0.5.1".to_string());
231        assert_eq!(ma2.group, "io.github.astonbitecode");
232        assert_eq!(ma2.id, "j4rs");
233        assert_eq!(ma2.version, "0.5.1");
234        assert_eq!(ma2.qualifier, "");
235
236        let ma3 = MavenArtifact::from(&vec!["io.github.astonbitecode", "j4rs", "0.5.1"]);
237        assert_eq!(ma3.group, "io.github.astonbitecode");
238        assert_eq!(ma3.id, "j4rs");
239        assert_eq!(ma3.version, "0.5.1");
240        assert_eq!(ma3.qualifier, "");
241    }
242
243    #[test]
244    fn maven_artifact_repo_from() {
245        let mar = MavenArtifactRepo::from("myrepo::https://myrepo.io");
246        assert_eq!(mar._id, "myrepo");
247        assert_eq!(mar.uri, "https://myrepo.io");
248    }
249}