";
34 |
35 | String namespace();
36 | }
37 |
--------------------------------------------------------------------------------
/.bazelrc:
--------------------------------------------------------------------------------
1 | # Recommended bazel settings for working with J2CL.
2 | # You can copy this into root of your workspace.
3 |
4 | build --watchfs
5 |
6 | build --spawn_strategy=local
7 |
8 | build --strategy=J2cl=worker
9 | build --strategy=J2clStrip=worker
10 | build --strategy=J2clRta=worker
11 |
12 | build --strategy=J2wasm=worker
13 | build --strategy=J2wasmStrip=worker
14 | build --strategy=J2wasmApp=local
15 |
16 | build --strategy=Closure=worker
17 | build --strategy=Javac=worker
18 | build --strategy=JavaIjar=local
19 | build --strategy=JavaDeployJar=local
20 | build --strategy=JavaSourceJar=local
21 | build --strategy=Turbine=local
22 |
23 | # --experimental_inprocess_symlink_creation is used to workaround the missing
24 | # support for paths with spaces https://github.com/bazelbuild/bazel/issues/4327.
25 | # Remove the two flags after this issue is fixed in bazel new release.
26 | build --enable_platform_specific_config
27 | build:macos --experimental_inprocess_symlink_creation
28 |
29 | test --test_output=errors
30 |
31 | # Enable Java 21. Note this doesn't control whether J2CL accepts Java 21 inputs,
32 | # that is controlled in build_defs/internal_do_not_use/j2cl_common.bzl.
33 | build --java_language_version=21
34 | build --java_runtime_version=21
35 |
36 | # Enable Java 21 for J2CL compiler itself
37 | build --tool_java_language_version=21
38 | build --tool_java_runtime_version=21
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsIgnore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * Marks a member to be ignored for JsInterop purposes.
26 | *
27 | * This is particularly useful when {@link JsType} is applied to a class and some members need to
28 | * be ignored as they don't comply with restrictions (e.g. overloading) or shouldn't be exported for
29 | * other reasons.
30 | */
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD})
33 | @Documented
34 | public @interface JsIgnore {}
35 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsNonNull.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsNonNull marks a type as non-nullable indicating that program elements of such a type can not
26 | * hold a {@code null} value.
27 | *
28 | *
Note that JsNonNull can only be used in a JsConstructor, a JsMethod, a JsProperty or a
29 | * JsFunction method.
30 | *
31 | *
This annotation is informational in the GWT compiler but other compilers or tools might use it
32 | * for example to annotate types in the output JavaScript program.
33 | */
34 | @Retention(RetentionPolicy.RUNTIME)
35 | @Target(ElementType.TYPE_USE)
36 | @Documented
37 | public @interface JsNonNull {}
38 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsNullable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsNullable marks a type variable as nullable indicating that program elements of such a type can
26 | * hold a {@code null} value.
27 | *
28 | *
Note that JsNullable can only be used on type variables in the context of a JsConstructor, a
29 | * JsMethod, a JsProperty or a JsFunction method.
30 | *
31 | *
This annotation is informational in the GWT compiler but other compilers or tools might use it
32 | * for example to annotate types in the output JavaScript program.
33 | */
34 | @Retention(RetentionPolicy.RUNTIME)
35 | @Target(ElementType.TYPE_USE)
36 | @Documented
37 | public @interface JsNullable {}
38 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsAsync.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsAsync marks a method to be transpiled to an async JavaScript method.
26 | *
27 | *
Adding this annotation to a method adds an {@code async} keyword to the generated JavaScript
28 | * function.
29 | *
30 | *
There are some limitations apply on JsAsync to make the annotation practical:
31 | *
32 | *
33 | * - A @JsAsync method return type should be IThenable or Promise.
34 | *
- A @JsAsync method should not return {@code null}.
35 | *
36 | *
37 | * This is an EXPERIMENTAL annotation and only works in J2CL.
38 | */
39 | @Retention(RetentionPolicy.RUNTIME)
40 | @Target(ElementType.METHOD)
41 | @Documented
42 | public @interface JsAsync {}
43 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsOptional.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsOptional marks a parameter in a method as optional indicating that the argument can be omitted
26 | * from the function call when called from JavaScript side.
27 | *
28 | *
Note that JsOptional can only be used in a JsConstructor, a JsMethod or a JsFunction method.
29 | * An optional argument cannot precede a non-optional argument (a vararg is considered an optional
30 | * argument).
31 | *
32 | *
This annotation is informational in the GWT compiler but other compilers or tools might use it
33 | * for example to annotate types in the output JavaScript program.
34 | */
35 | @Retention(RetentionPolicy.RUNTIME)
36 | @Target(ElementType.PARAMETER)
37 | @Documented
38 | public @interface JsOptional {}
39 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsConstructor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsConstructor marks a constructor that will be translated into a JavaScript constructor function.
26 | *
27 | *
Due to ES6 class semantics, for non-native JsTypes only one JsConstructor is allowed to exist
28 | * in the type which becomes the 'primary constructor'. All other constructors in the type must
29 | * delegate to it. Subclasses of a type with JsConstructor should follow the same restriction with
30 | * the exception that the primary constructor is not required to be marked as JsConstructor but
31 | * still need to delegate to super primary constructor.
32 | */
33 | @Retention(RetentionPolicy.RUNTIME)
34 | @Target(ElementType.CONSTRUCTOR)
35 | @Documented
36 | public @interface JsConstructor {}
37 |
--------------------------------------------------------------------------------
/maven/pom-annotations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | com.google.jsinterop
6 | jsinterop-annotations
7 | __VERSION__
8 |
9 | JsInterop Annotations
10 | JsInterop Annotations contains a set of java annotations that drive the javascript
11 | code generation of J2CL transpiler or GWT
12 | https://github.com/google/jsinterop-annotations
13 |
14 |
15 |
16 | The Apache Software License, Version 2.0
17 | http://www.apache.org/licenses/LICENSE-2.0.txt
18 | repo
19 |
20 |
21 |
22 |
23 | scm:git:https://github.com/google/jsinterop-annotations.git
24 | scm:git:git@github.com:google/jsinterop-annotations.git
25 | https://github.com/google/jsinterop-annotations
26 |
27 |
28 |
29 | https://github.com/google/jsinterop-annotations/issues
30 | GitHub Issues
31 |
32 |
33 |
34 |
35 | J2CL team
36 | Google
37 | http://www.google.com
38 |
39 |
40 | __BUILD_SECTION__
41 |
42 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsMethod marks a method that will be directly translated into a JavaScript method preserving its
26 | * name.
27 | *
28 | *
Note: In JavaScript, instance members are defined on the prototype and class members are
29 | * defined on the constructor function of the type.
30 | */
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target(ElementType.METHOD)
33 | @Documented
34 | public @interface JsMethod {
35 |
36 | /**
37 | * Customizes the name of the member in generated JavaScript. If not provided, the Java name will
38 | * be used.
39 | */
40 | String name() default "";
41 |
42 | /**
43 | * Customizes the namespace of the static member in generated JavaScript. If none is provided,
44 | * namespace is the enclosing class' fully qualified JavaScript name.
45 | */
46 | String namespace() default "";
47 | }
48 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsFunction marks a functional interface as being the definition of a JavaScript function.
26 | *
27 | * There are some limitations exists on JsFunction to make them practical and efficient:
28 | *
29 | *
30 | * - A JsFunction interface cannot extend any other interfaces.
31 | *
- A class may not implement more than one JsFunction interface.
32 | *
- A class that implements a JsFunction type cannot be a {@link JsType} (directly or
33 | * indirectly).
34 | *
- Fields and defender methods of the interfaces should be marked with {@link JsOverlay} and
35 | * cannot be overridden by the implementations.
36 | *
37 | *
38 | * As a best practice, we also recommend marking JsFunction interfaces with FunctionalInterface
39 | * to get improved checking in IDEs.
40 | *
41 | *
Instanceof and Castability:
42 | *
43 | *
Instanceof and casting for JsFunction is effectively a JavaScript {@code typeof} check to
44 | * determine if the instance is a function.
45 | */
46 | @Retention(RetentionPolicy.RUNTIME)
47 | @Target(ElementType.TYPE)
48 | @Documented
49 | public @interface JsFunction {}
50 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsOverlay.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsOverlay is used to enhance Java API of the native JsTypes and JsFunctions so richer and more
26 | * Java friendly abstractions could be provided.
27 | *
28 | *
29 | * {@literal @}JsType(isNative=true)
30 | * class Person {
31 | * {@literal @}JsOverlay
32 | * private static final Person NO_BODY = new Person();
33 | *
34 | * private String name;
35 | * private String lastName;
36 | *
37 | * {@literal @}JsOverlay
38 | * public String getFullName() {
39 | * return (name + " " + lastName).trim();
40 | * }
41 | * }
42 | *
43 | * Note that:
44 | *
45 | *
46 | * - JsOverlay methods cannot override any existing methods.
47 | *
- JsOverlay methods should be effectively final.
48 | *
- JsOverlay methods cannot be called from JavaScript
49 | *
50 | *
51 | * These restrictions are in place to avoid polymorphism because underneath the original type is not
52 | * modified and the overlay fields/methods are simply turned into static dispatches.
53 | */
54 | @Retention(RetentionPolicy.RUNTIME)
55 | @Target({ElementType.METHOD, ElementType.FIELD})
56 | @Documented
57 | public @interface JsOverlay {}
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JsInterop Annotations ·  · [](https://github.com/google/jsinterop-annotations/actions/workflows/ci.yaml)
2 |
3 |
4 |
5 | JsInterop Annotations contains a set of java annotations that drive the
6 | javascript code generation of [J2CL transpiler](https://github.com/google/j2cl)
7 | or [GWT](https://github.com/gwtproject/gwt)
8 |
9 | Bazel dependency
10 | ----------------
11 | If your project uses [Bazel](https://bazel.build), J2CL repository already
12 | provides targets `@j2cl//:jsinterop-annotations` and
13 | `@j2cl://jsinterop-annotations-j2cl` for Server/Android and J2CL respectively.
14 |
15 | Maven dependency
16 | ----------------
17 | If your project uses [Maven](https://maven.apache.org), add the following maven
18 | dependency in your `pom.xml`. Replace `RELEASE_VERSION` with an actual
19 | [release version](https://github.com/google/jsinterop-annotations/releases):
20 |
21 |
22 | com.google.jsinterop
23 | jsinterop-annotations
24 | RELEASE_VERSION
25 |
26 |
27 | Build GWT compatible maven jar files
28 | ------------------------------------
29 | If you want to build the last version on your own, follow the instructions
30 | below:
31 |
32 | - Install [Bazelisk](https://github.com/bazelbuild/bazelisk):
33 |
34 | ```shell
35 | $ npm install -g @bazel/bazelisk
36 | $ alias bazel=bazelisk
37 | ```
38 | - Clone this git repository:
39 | ```shell
40 | $ git clone https://github.com/google/jsinterop-annotations.git
41 | ```
42 | - Run the release script:
43 | ```shell
44 | $ cd jsinterop-annotations
45 | $ ./maven/release_jsinterop_annotations.sh --version local --no-deploy
46 | ```
47 |
48 | The script will output the directory containing the generated jar files that
49 | can be used with maven.
50 |
51 | Contributing
52 | ------------
53 | Please refer to [the contributing document](CONTRIBUTING.md).
54 |
55 | Licensing
56 | ---------
57 | Please refer to [the license file](LICENSE).
58 |
59 | Disclaimer
60 | ----------
61 | This is not an official Google product.
62 |
63 |
--------------------------------------------------------------------------------
/maven/publish_to_sonatype.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google Inc. All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS-IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | # The script generates the open source artifacts for JsInterop Annotations and
17 | # uploads them to sonatype.
18 | set -euo pipefail
19 |
20 | source "$(dirname "$0")/deploy.sh"
21 |
22 | readonly MAVEN_ARTIFACT="jsinterop-annotations"
23 | readonly BAZEL_ARTIFACT="annotations"
24 | readonly BAZEL_PATH="java/jsinterop/annotations"
25 | readonly COPY_SRCS_IN_JAR=false
26 |
27 | usage() {
28 | echo ""
29 | echo "$(basename $0): Build and deploy script for Jsinterop Annotations."
30 | echo ""
31 | echo "$(basename $0) --version [--no-deploy]"
32 | echo " --help"
33 | echo " Print this help output and exit."
34 | echo " --version "
35 | echo " Maven version of the library to use for deploying to sonatype."
36 | echo " --no-deploy"
37 | echo " Skip the deployment part but build all artifacts."
38 | echo " --sonatype-auto-publish"
39 | echo " Publish automatically the artifact on sonatype."
40 | echo ""
41 | }
42 |
43 | parse_arguments() {
44 | deploy_to_sonatype=true
45 | lib_version=""
46 | sonatype_auto_publish=false
47 |
48 | while [[ $# -gt 0 ]]; do
49 | case "$1" in
50 | --version )
51 | shift
52 | lib_version=$1
53 | ;;
54 | --no-deploy )
55 | deploy_to_sonatype=false
56 | ;;
57 | --help )
58 | usage
59 | exit 0
60 | ;;
61 | --sonatype-auto-publish)
62 | sonatype_auto_publish=true
63 | ;;
64 | * )
65 | common::error "unexpected option $1"
66 | ;;
67 | esac
68 | shift
69 | done
70 | }
71 |
72 | main() {
73 | parse_arguments "$@"
74 |
75 | common::check_version_set
76 | common::check_bazel_prerequisites
77 | common::check_maven_prerequisites
78 |
79 | common::build
80 | common::deploy_to_sonatype
81 | }
82 |
83 | # Set the trap to cleanup temporary files on EXIT
84 | trap common::cleanup_temp_files EXIT
85 |
86 | main "$@"
87 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsProperty.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsProperty marks a field or method that is translated directly into a JavaScript property
26 | * preserving its name.
27 | *
28 | * If it is applied to a method, it will be treated as a property accessor. As a result, instead
29 | * of translating method calls to JsProperty methods as method calls in JS, they will be translated
30 | * as property lookups. When a JsProperty method implemented by a Java class, such methods will be
31 | * generated as property accessor in JavaScript, hence the property access will trigger the
32 | * execution of the matching getter or setter methods.
33 | *
34 | *
JsProperty follows JavaBean style naming convention to extract the default property name. If
35 | * the JavaBean convention is not followed, the name should be set explicitly. For example:
36 | *
37 | *
38 | * - {@code @JsProperty getX()} or {@code @JsProperty isX()} translates as {@code this.x}
39 | *
- {@code @JsProperty setX(int y)} translates as {@code this.x=y}
40 | *
41 | *
42 | * Note: In JavaScript, instance members are defined on the prototype and class members are
43 | * defined on the constructor function of the type which mimics ES6 class style.
44 | */
45 | @Retention(RetentionPolicy.RUNTIME)
46 | @Target({ElementType.METHOD, ElementType.FIELD})
47 | @Documented
48 | public @interface JsProperty {
49 |
50 | /**
51 | * Customizes the name of the member in generated JavaScript. If none is provided;
52 | *
53 | *
54 | * - if it is field, the simple Java name will be used.
55 | *
- if it is a method, the name will be generated based on JavaBean conventions.
56 | *
57 | */
58 | String name() default "";
59 |
60 | /**
61 | * Customizes the namespace of the static member in generated JavaScript. If none is provided,
62 | * namespace is the enclosing class' fully qualified JavaScript name.
63 | */
64 | String namespace() default "";
65 | }
66 |
--------------------------------------------------------------------------------
/maven/build_section.xml:
--------------------------------------------------------------------------------
1 |
2 | ${project.artifactId}-classes
3 | ${project.artifactId}-javadoc.jar
4 | ${project.artifactId}-sources.jar
5 |
6 |
7 |
8 |
9 |
10 | org.apache.maven.plugins
11 | maven-jar-plugin
12 | 3.4.2
13 |
14 | ${classesDirectory}
15 |
16 |
17 |
18 | org.codehaus.plexus
19 | plexus-io
20 |
21 | 3.5.1
22 |
23 |
24 |
25 |
26 | org.codehaus.mojo
27 | build-helper-maven-plugin
28 | 1.9.1
29 |
30 |
31 | attach-artifacts
32 | package
33 |
34 | attach-artifact
35 |
36 |
37 |
38 |
39 | ${javadocFile}
40 | jar
41 | javadoc
42 |
43 |
44 | ${sourcesFile}
45 | jar
46 | sources
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | org.apache.maven.plugins
55 | maven-gpg-plugin
56 | 3.2.7
57 |
58 |
59 | sign-artifacts
60 | verify
61 |
62 | sign
63 |
64 |
65 |
66 |
67 |
68 | org.sonatype.central
69 | central-publishing-maven-plugin
70 | 0.8.0
71 | true
72 |
73 | central
74 | ${autoPublish}
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsType is used to describe the JavaScript API of an object, either one that already exists from
26 | * the external JavaScript environment, or one that will be accessible from the external JavaScript
27 | * environment.
28 | *
29 | * Marking an object with JsType is similar to marking each public member of the class with
30 | * {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} respectively. In order for this to work
31 | * correctly the JavaScript name needs to be unique for each member. Some unobvious ways to cause
32 | * name collisions are:
33 | *
34 | *
35 | * - having method or constructor overloads
36 | *
- using the same name for a method and a field
37 | *
- shadowing a field from parent
38 | *
39 | *
40 | * Name collisions must be avoided by providing custom names (e.g. {@link JsProperty#name}) or by
41 | * ignoring members using {@link JsIgnore}.
42 | *
43 | *
If the JsType is marked as "native" via {@link #isNative}, then the type is considered a stub
44 | * for an existing class that is available in native JavaScript. Unlike non-native JsTypes, all
45 | * members are considered {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} unless they are
46 | * explicitly marked with {@link JsOverlay}.
47 | *
48 | *
For native interfaces with no particular JavaScript type associated with them (e.g. structural
49 | * types) it is recommended to use {@code namespace = JsPackage.GLOBAL} and {@code name = '?'}.
50 | *
51 | *
Instanceof and Castability:
52 | *
53 | *
If the JsType is native, the generated code will try to mimic Javascript semantics.
54 | *
55 | *
All non-native JsTypes will follow regular Java semantics in terms of castability.
56 | *
57 | *
58 | * - For concrete native JsTypes, cast checks and instanceof checks will be delegated to the
59 | * native JavaScript instanceof operator.
60 | *
- For interface native JsTypes, instanceof is forbidden and casts to them always succeed.
61 | *
62 | */
63 | @Retention(RetentionPolicy.RUNTIME)
64 | @Target(ElementType.TYPE)
65 | @Documented
66 | public @interface JsType {
67 |
68 | /**
69 | * Customizes the name of the type in generated JavaScript. If not provided, the simple Java name
70 | * will be used.
71 | */
72 | String name() default "";
73 |
74 | /** Customizes the namespace of the type in generated JavaScript. */
75 | String namespace() default "";
76 |
77 | /** Set to {@code true}, this JsType is a native JavaScript type. */
78 | boolean isNative() default false;
79 | }
80 |
--------------------------------------------------------------------------------
/java/jsinterop/annotations/JsEnum.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Google Inc.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 | package jsinterop.annotations;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * JsEnum marks a Java enum as being represented as a Closure enum, either one that already exists
26 | * from the external JavaScript environment, or one that will be accessible from the external
27 | * JavaScript environment.
28 | *
29 | * The underlying type of the Closure enum can be specified via {@link #hasCustomValue} and
30 | * declaring an instance field named "value" of the desired type.
31 | *
32 | *
If the JsEnum is non-native and has custom values, a constructor is required to allow
33 | * specifying the values for the enum constants, as in the following example
34 | *
35 | *
36 | * {@literal @}JsEnum(hasCustomValue=true)
37 | * enum IntJsEnum {
38 | * TEN(10),
39 | * TWENTY(20);
40 | *
41 | * int value;
42 | *
43 | * IntJsEnum(int value) { this.value = value; }
44 | * }
45 | *
46 | *
47 | * If the JsEnum is native and has custom values, the value field is still required but
48 | * constructors are not needed nor allowed.
49 | *
50 | *
JsEnums do not support the full Java semantics:
51 | *
52 | *
53 | * - No instance fields are allowed other than {@code value},
54 | *
- {@link Enum#name()} and {@code values()} are not supported.
55 | *
- {@link Enum#ordinal()} is supported only for non-native JsEnums that don't have custom
56 | * values.
57 | *
- The class is initialization might be delayed until a static field/method is accessed.
58 | *
59 | *
60 | * The JavaScript namespace and name can be specified in a manner similar to JsTypes via {@link
61 | * #namespace} and {@link #name} respectively.
62 | *
63 | *
Methods and fields declared in the JsEnum are only accessible in Java code. Only the enum
64 | * constants are accessible from JavaScript code.
65 | *
66 | *
This annotation is only supported by J2CL.
67 | */
68 | @Retention(RetentionPolicy.RUNTIME)
69 | @Target(ElementType.TYPE)
70 | @Documented
71 | public @interface JsEnum {
72 |
73 | /**
74 | * Customizes the name of the type in generated JavaScript. If not provided, the simple Java name
75 | * will be used.
76 | */
77 | String name() default "";
78 |
79 | /** Customizes the namespace of the type in generated JavaScript. */
80 | String namespace() default "";
81 |
82 | /** When set to {@code true}, this JsEnum is a native Closure enum type. */
83 | boolean isNative() default false;
84 |
85 | /**
86 | * When set to {@code true}, this JsEnum will have a custom value defined by a field named
87 | * 'value'. The only allowed types for the value field are String and primitive types with the
88 | * exception of long.
89 | */
90 | boolean hasCustomValue() default false;
91 | }
92 |
--------------------------------------------------------------------------------
/.github/workflows/scorecard.yaml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub. They are provided
2 | # by a third-party and are governed by separate terms of service, privacy
3 | # policy, and support documentation.
4 |
5 | name: Scorecard supply-chain security
6 | on:
7 | # For Branch-Protection check. Only the default branch is supported. See
8 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
9 | branch_protection_rule:
10 | # To guarantee Maintained check is occasionally updated. See
11 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
12 | schedule:
13 | - cron: '25 5 * * 5'
14 | push:
15 | branches: [ "master" ]
16 |
17 | # Declare default permissions as read only.
18 | permissions: read-all
19 |
20 | jobs:
21 | analysis:
22 | name: Scorecard analysis
23 | runs-on: ubuntu-latest
24 | # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
25 | if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
26 | permissions:
27 | # Needed to upload the results to code-scanning dashboard.
28 | security-events: write
29 | # Needed to publish results and get a badge (see publish_results below).
30 | id-token: write
31 | # Uncomment the permissions below if installing in a private repository.
32 | # contents: read
33 | # actions: read
34 |
35 | steps:
36 | - name: "Checkout code"
37 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
38 | with:
39 | persist-credentials: false
40 |
41 | - name: "Run analysis"
42 | uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
43 | with:
44 | results_file: results.sarif
45 | results_format: sarif
46 | # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
47 | # - you want to enable the Branch-Protection check on a *public* repository, or
48 | # - you are installing Scorecard on a *private* repository
49 | # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
50 | # repo_token: ${{ secrets.SCORECARD_TOKEN }}
51 |
52 | # Public repositories:
53 | # - Publish results to OpenSSF REST API for easy access by consumers
54 | # - Allows the repository to include the Scorecard badge.
55 | # - See https://github.com/ossf/scorecard-action#publishing-results.
56 | # For private repositories:
57 | # - `publish_results` will always be set to `false`, regardless
58 | # of the value entered here.
59 | publish_results: true
60 |
61 | # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore
62 | # file_mode: git
63 |
64 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
65 | # format to the repository Actions tab.
66 | - name: "Upload artifact"
67 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
68 | with:
69 | name: SARIF file
70 | path: results.sarif
71 | retention-days: 5
72 |
73 | # Upload the results to GitHub's code scanning dashboard (optional).
74 | # Commenting out will disable upload of results to your repo's Code Scanning dashboard
75 | - name: "Upload to code-scanning"
76 | uses: github/codeql-action/upload-sarif@v4
77 | with:
78 | sarif_file: results.sarif
79 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2020 Google LLC
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 | # https://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 |
15 | # Format reference: https://docs.github.com/en/actions/reference
16 |
17 | name: CI
18 |
19 | permissions:
20 | contents: read
21 |
22 | # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#on
23 | on:
24 | push:
25 | branches: [ master ]
26 | pull_request:
27 | branches: [ master ]
28 | schedule:
29 | # Daily at 12pm UTC
30 | - cron: '0 12 * * *'
31 | # Can be called from other workflow to run the tests
32 | workflow_call:
33 | inputs:
34 | git_ref:
35 | description: 'The git ref used to checkout the repository and run the tests.'
36 | type: string
37 | required: false
38 |
39 | # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs
40 | jobs:
41 | build:
42 | strategy:
43 | fail-fast: false
44 | matrix:
45 | test-target: ['default', 'samples']
46 | os: [macos-latest, ubuntu-latest]
47 |
48 | runs-on: ${{ matrix.os }}
49 |
50 | steps:
51 | - name: Setup Java
52 | uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
53 | with:
54 | java-version: '21'
55 | distribution: 'zulu'
56 | java-package: jdk
57 |
58 | - name: Checkout the repository
59 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
60 | with:
61 | ref: ${{ inputs.git_ref || github.ref }}
62 |
63 | - name: Cache Bazel repositories
64 | uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
65 | with:
66 | path: ~/bazel-repository-cache
67 | key: bazel-repositories-${{hashFiles('**/MODULE.bazel')}}
68 | restore-keys: |
69 | bazel-repositories-
70 |
71 | - name: Cache Bazel results
72 | uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
73 | with:
74 | path: ~/bazel-action-cache
75 | key: bazel-actions-${{runner.os}}-${{github.sha}}
76 | restore-keys: |
77 | bazel-actions-${{runner.os}}-
78 |
79 | - name: Configure bazel
80 | run: |
81 | echo "build --repository_cache=~/bazel-repository-cache" >> ~/.bazelrc
82 | echo "build --disk_cache=~/bazel-action-cache" >> ~/.bazelrc
83 | echo "build -c opt" >> ~/.bazelrc
84 | echo "build --verbose_failures" >> ~/.bazelrc
85 | bazel info
86 |
87 | # Fake the host name to cause name lookups fail and fallback to localhost in WTL:
88 | # rules_webtesting/go/httphelper/http_helper.go#FQDN()
89 | # This prevents potential 'underscore' in resolved name which later used by
90 | # WebDriver that inherits a JDK bug (https://bugs.openjdk.org/browse/JDK-8221675).
91 | - name: Fake host name
92 | if: matrix.os == 'macos-latest'
93 | run: sudo scutil --set HostName unknown
94 |
95 | - name: Run tests
96 | if: matrix.test-target == 'default'
97 | run: ./build_test.sh CI
98 | - name: Run samples tests
99 | if: matrix.test-target == 'samples'
100 | run: |
101 | if [[ -f "./build_test_samples.sh" ]]; then
102 | ./build_test_samples.sh CI
103 | fi
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2025 Google LLC
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 | # https://www.apache.0rg/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 | name: Release Project
15 |
16 | permissions:
17 | contents: read
18 |
19 | # TODO(b/452391493): Consider triggering the workflow on git release creation instead.
20 | # This workflow is triggered manually from the Actions tab.
21 | on:
22 | workflow_dispatch:
23 | inputs:
24 | version:
25 | description: 'The version to release'
26 | required: true
27 | type: string
28 | base_rc_version:
29 | description: 'The base RC version to use to create the final release. Should be formatted as X.Y.Z-RC.N'
30 | type: string
31 | required: false
32 | continue_if_tag_exists:
33 | description: 'Continue the workflow even if the GitHub tag already exists'
34 | type: boolean
35 | required: true
36 | default: false
37 |
38 | jobs:
39 | validate_inputs:
40 | runs-on: ubuntu-latest
41 | steps:
42 | - name: Validate base_rc_version
43 | run: |
44 | base_rc_version="${{ github.event.inputs.base_rc_version }}"
45 | if [[ -z "$base_rc_version" ]]; then
46 | echo "The base RC version field is empty, no validation needed."
47 | exit 0
48 | fi
49 |
50 | version="${{ github.event.inputs.version }}"
51 | repo_name="${{ github.event.repository.name }}"
52 | RC_REGEX='^([0-9]+\.[0-9]+\.[0-9]+)-RC\.?[0-9]+$'
53 | VERSION_REGEX='^[0-9]+\.[0-9]+\.[0-9]+$'
54 |
55 | # Ensure base_rc_version is not set for repositories that do not use RC versions.
56 | if [[ "$repo_name" == "jsinterop-generator" || "$repo_name" == "j2cl" ]]; then
57 | echo "Error: The base RC version field should not be set for repository '${repo_name}'."
58 | exit 1
59 | fi
60 |
61 | # Ensure base_rc_version is not set for for RC releases.
62 | # RC releases should not be based on another RC version.
63 | if [[ "$version" =~ $RC_REGEX ]]; then
64 | echo "Error: If the version '${version}' is an RC version, the base RC version field must be empty."
65 | exit 1
66 | fi
67 |
68 | # Validate base_rc_version format
69 | if [[ ! "$base_rc_version" =~ $RC_REGEX ]]; then
70 | echo "Error: Invalid base_rc_version format. Expected X.Y.Z-RC.N, but got '${base_rc_version}'."
71 | exit 1
72 | fi
73 |
74 | # Extract the base version from base_rc_version using the first captured group from the regex match.
75 | base_version_from_rc="${BASH_REMATCH[1]}"
76 | # Ensure the base version extracted from `base_rc_version` matches the intended release `version`.
77 | # This prevents releasing a final version based on an incorrect Release Candidate.
78 | if [[ "$base_version_from_rc" != "$version" ]]; then
79 | echo "Error: The base_rc_version '${base_rc_version}' does not match the version '${version}'."
80 | exit 1
81 | fi
82 |
83 | # Check if the base version is an existing git tag
84 | if ! git ls-remote ${{ github.server_url }}/${{ github.repository }} "refs/tags/${base_rc_version}" | grep -q "refs/tags/${base_rc_version}"; then
85 | echo "Error: The base version '${base_rc_version}' is not a valid tag in the repository."
86 | exit 1
87 | fi
88 |
89 | release:
90 | needs: validate_inputs
91 | uses: google/j2cl/.github/workflows/release_common.yaml@master
92 |
93 | permissions:
94 | # Permissions for creating a github release.
95 | contents: write
96 | # Permissions for publishing to bcr.
97 | id-token: write
98 | attestations: write
99 |
100 | # Pass the inputs from the manual trigger to the reusable workflow.
101 | with:
102 | version: ${{ github.event.inputs.version }}
103 | git_ref: ${{ github.event.inputs.base_rc_version && format('refs/tags/{0}', github.event.inputs.base_rc_version) || github.ref }}
104 | publish_to_sonatype: ${{ github.event.repository.name != 'jsinterop-generator' && github.event.repository.name != 'j2cl' }}
105 | continue_if_tag_exists: ${{ github.event.inputs.continue_if_tag_exists == 'true' }}
106 | publish_to_bcr: ${{ github.event.repository.name != 'jsinterop-annotations' }}
107 |
108 | # Allow the reusable workflow to access the secrets.
109 | secrets: inherit
110 |
--------------------------------------------------------------------------------
/maven/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright 2019 Google Inc. All Rights Reserved
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS-IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | #
17 | # The script generates the open source artifacts needed for uploading a library to oss sonatype.
18 | # The artifacts include the jar file, the sources jar file and the javadoc jar file.
19 | # The script signs each jar and uploads them to sonatype.
20 | #
21 | # You need to install maven (3.0.5) before to run this script:
22 | # sudo apt-get install maven
23 | #
24 | # For using the gpg maven plugin, you need to create a gpg2 key.
25 | # 1) install gpg2 (1.4.16) if needed:
26 | # sudo apt-get install gnupg2
27 | # 2) create a key pair by running:
28 | # gpg2 --gen-key
29 | #
30 | # The script will ask you the passphrase of your key if the MAVEN_GPG_PASSPHRASE
31 | # environment variable is not set.
32 | #
33 | # You have to also configure the repository credentials by creating a settings.xml
34 | # file in the ~/.m2/ directory and add this section :
35 | #
36 | #
37 | # central
38 | # central_portal_token_username
39 | # central_portal_token_password
40 | #
41 | #
42 | #
43 | # You can find the repository credentials in go/valentine
44 | #
45 | readonly BAZEL_ROOT=$(pwd)
46 | readonly BUILD_SECTION_FILE="${BAZEL_ROOT}/maven/build_section.xml"
47 |
48 | common::error() {
49 | echo "Error: $@" >&2
50 | exit 1
51 | }
52 |
53 | common::info() {
54 | echo "Info: $@"
55 | }
56 |
57 | #######################################
58 | # Check if :
59 | # - Bazel is installed,
60 | # - the script is run from the root of the Bazel repository.
61 | # - Bazel environment variables are set.
62 | # Globals:
63 | # BAZEL
64 | # BAZEL_ARTIFACT
65 | # BAZEL_PATH
66 | #######################################
67 | common::check_bazel_prerequisites() {
68 | if [ ! -f "MODULE.bazel" ]; then
69 | common::error "This script must be run from the root of the Bazel repository (where MODULE.bazel exists)."
70 | fi
71 |
72 | # Check for Bazel or Bazelisk
73 | if command -v bazelisk &> /dev/null; then
74 | BAZEL="bazelisk"
75 | elif command -v bazel &> /dev/null; then
76 | BAZEL="bazel"
77 | else
78 | common::error "Neither Bazel nor Bazelisk is installed or in your PATH."
79 | fi
80 |
81 | if [[ -z "${BAZEL_ARTIFACT:-}" ]]; then
82 | common::error "BAZEL_ARTIFACT is not set."
83 | fi
84 |
85 | if [[ -z "${BAZEL_PATH:-}" ]]; then
86 | common::error "BAZEL_PATH is not set."
87 | fi
88 | }
89 |
90 | #######################################
91 | # Check if :
92 | # - Maven is installed.
93 | # - MAVEN_ARTIFACT is set.
94 | # - a pom xml file is present in the maven directory
95 | # - global variables used for deployement are set.
96 | # Globals:
97 | # MAVEN_ARTIFACT
98 | # BAZEL_ROOT
99 | #######################################
100 | common::check_maven_prerequisites() {
101 | if ! command -v mvn &> /dev/null; then
102 | common::error "Maven is not installed. Please install it."
103 | fi
104 |
105 | if [[ -z "${MAVEN_ARTIFACT:-}" ]]; then
106 | common::error "MAVEN_ARTIFACT is not set."
107 | fi
108 |
109 | # TODO(dramaix): Rename the pom files by using the maven artifact name.
110 | if [ ! -f "${BAZEL_ROOT}/maven/pom-${BAZEL_ARTIFACT}.xml" ]; then
111 | common::error "Maven pom file not found for artifact ${MAVEN_ARTIFACT}."
112 | fi
113 |
114 | if [[ -n "${COMMON_DEPENDENCIES_FILE:-}" ]] && [[ ! -f "${COMMON_DEPENDENCIES_FILE}" ]]; then
115 | common::error "COMMON_DEPENDENCIES_FILE is set but the file '${COMMON_DEPENDENCIES_FILE}' does not exist."
116 | fi
117 |
118 | # Every project that deploy to sonatype with maven needs to set the
119 | # deploy_to_sonatype variable to be able to skip the deployment step.
120 | if [[ -z "${deploy_to_sonatype:-}" ]]; then
121 | common::error "deploy_to_sonatype variable is missing."
122 | fi
123 |
124 | # sonatype_auto_publish is used to automatically publish the artifacts after
125 | # deployment.
126 | if [[ -z "${sonatype_auto_publish:-}" ]]; then
127 | common::error "sonatype_auto_publish variable is missing."
128 | fi
129 | }
130 |
131 | #######################################
132 | # Check if --version flag is set and the value is valid.
133 | # Every project requires a version number for deployment.
134 | #######################################
135 | common::check_version_set() {
136 | if [[ -z "$lib_version" ]]; then
137 | common::error "--version flag is missing"
138 | fi
139 | if [[ "$lib_version" == "--"* ]]; then
140 | common::error "Incorrect version value: $lib_version"
141 | fi
142 | }
143 |
144 | common::_bazel_build() {
145 | local target="$1"
146 | common::info "Building Bazel target: ${target}"
147 | "${BAZEL}" build "${target}"
148 | }
149 |
150 | common::build() {
151 | common::_bazel_build "//${BAZEL_PATH}:lib${BAZEL_ARTIFACT}.jar"
152 | common::_bazel_build "//${BAZEL_PATH}:lib${BAZEL_ARTIFACT}-src.jar"
153 | common::_bazel_build "//${BAZEL_PATH}:${BAZEL_ARTIFACT}-javadoc.jar"
154 | }
155 |
156 | common::_prepare_sources_artifact() {
157 | local maven_src_jar="$1"
158 | local bazel_src_jar="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/lib${BAZEL_ARTIFACT}-src.jar"
159 |
160 | if [[ -n "${LICENSE_HEADER_FILE:-}" ]]; then
161 | common::info "Adding license header to java source files."
162 |
163 | local srcs_directory=$(mktemp -d)
164 | (cd "${srcs_directory}" && jar xf "${bazel_src_jar}")
165 |
166 | local tmp_file=$(mktemp)
167 |
168 | for java in $(find "${srcs_directory}" -name '*.java'); do
169 | cat "${LICENSE_HEADER_FILE}" "${java}" > "${tmp_file}"
170 | mv "${tmp_file}" "${java}"
171 | done
172 |
173 | jar cf "${maven_src_jar}" -C "${srcs_directory}" .
174 | rm -rf "${srcs_directory}"
175 | else
176 | common::info "Copy sources jar to maven directory."
177 | cp "${bazel_src_jar}" "${maven_src_jar}"
178 | fi
179 | }
180 |
181 | common::_prepare_javadoc_artifact() {
182 | common::info "Copying javadoc jar to maven directory."
183 | local javadoc_jar="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/${BAZEL_ARTIFACT}-javadoc.jar"
184 | local maven_javadoc_jar="${maven_wd}/${MAVEN_ARTIFACT}-javadoc.jar"
185 | cp "${javadoc_jar}" "${maven_javadoc_jar}"
186 | }
187 |
188 | common::_extract_classes(){
189 | common::info "Extracting class files to maven directory."
190 | local maven_src_jar="$1"
191 |
192 | local classes_directory="${maven_wd}/${MAVEN_ARTIFACT}-classes"
193 | mkdir -p "${classes_directory}"
194 |
195 | local bazel_jar_file="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/lib${BAZEL_ARTIFACT}.jar"
196 |
197 | (cd "${classes_directory}" && jar xf "${bazel_jar_file}")
198 |
199 | if [[ "${COPY_SRCS_IN_JAR:-true}" == true ]]; then
200 | common::info "Extracting sources along with the class files."
201 | (cd "${classes_directory}" && jar xf "${maven_src_jar}")
202 | fi
203 | }
204 |
205 | common::_prepare_pom_file() {
206 | common::info "Generating pom file for ${MAVEN_ARTIFACT}."
207 | # Replace placeholders and generate the final pom.xml
208 | local -a sed_args
209 | sed_args+=(-e "s/__VERSION__/${lib_version}/g")
210 | sed_args+=(-e "/__BUILD_SECTION__/r ${BUILD_SECTION_FILE}")
211 | sed_args+=(-e "/__BUILD_SECTION__/d")
212 |
213 | if [[ -n "${COMMON_DEPENDENCIES_FILE:-}" ]]; then
214 | common::info "Adding common dependencies to pom file."
215 | sed_args+=(-e "/__COMMON_DEPENDENCIES__/r ${COMMON_DEPENDENCIES_FILE}")
216 | sed_args+=(-e "/__COMMON_DEPENDENCIES__/d")
217 | fi
218 |
219 | sed "${sed_args[@]}" \
220 | "${BAZEL_ROOT}/maven/pom-${BAZEL_ARTIFACT}.xml" > "${maven_wd}/pom-${MAVEN_ARTIFACT}.xml"
221 | }
222 |
223 | common::_prepare_artifact_for_sonatype() {
224 | local maven_src_jar="${maven_wd}/${MAVEN_ARTIFACT}-sources.jar"
225 |
226 | common::_prepare_sources_artifact "${maven_src_jar}"
227 | common::_prepare_javadoc_artifact
228 | # Extract the class files, maven will repackage everything in its own jar.
229 | common::_extract_classes "${maven_src_jar}"
230 | common::_prepare_pom_file
231 | }
232 |
233 | common::deploy_to_sonatype() {
234 | # TODO(Dramaix): Let the caller pass in the maven directory and be responsible
235 | # for setting the trap to cleanup the tmp directory
236 | if [[ -n "${1:-}" ]]; then
237 | common::info "Using provided directory '$1' for maven artifacts."
238 | maven_wd="$1"
239 | else
240 | common::info "Created temporary directory for maven artifacts."
241 | maven_wd=$(mktemp -d)
242 | fi
243 |
244 | common::_prepare_artifact_for_sonatype
245 |
246 | local pom_file="${maven_wd}/pom-${MAVEN_ARTIFACT}.xml"
247 |
248 | if [[ "${deploy_to_sonatype}" == true ]]; then
249 | common::info "Deploying artifacts to sonatype..."
250 | # Use maven to sign and deploy jar, sources jar and javadocs jar to OSS sonatype
251 | mvn -f "${pom_file}" clean deploy "-DautoPublish=${sonatype_auto_publish}"
252 |
253 | common::info "Deployment completed."
254 | else
255 | common::info "Packaging and installing maven artifacts locally..."
256 | mvn -f "${pom_file}" clean install
257 |
258 | common::info "Maven artifacts created in ${maven_wd}"
259 | common::info "Deployment not requested. No artifacts will be deployed."
260 | # set maven_wd to empty string so it's not deleted in cleanup_temp_files
261 | maven_wd=""
262 | fi
263 |
264 | common::cleanup_temp_files
265 | }
266 |
267 | common::cleanup_temp_files() {
268 | if [[ -d "${maven_wd:-}" ]]; then
269 | rm -rf "${maven_wd}"
270 | fi
271 | }
272 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2017 Google Inc.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------